Browse Source

Updated patches for v96

Minus timezone customization and user scripts patches
csagan5 3 years ago
parent
commit
820e23fb3d
100 changed files with 1490 additions and 12156 deletions
  1. 1 1
      build/RELEASE
  2. 3 5
      build/bromite_patches_list.txt
  3. 13 13
      build/patches/AImageReader-CFI-crash-mitigations.patch
  4. 15 15
      build/patches/AV1-codec-support.patch
  5. 7 7
      build/patches/Add-AllowUserCertificates-flag.patch
  6. 4 4
      build/patches/Add-IsCleartextPermitted-flag.patch
  7. 5 5
      build/patches/Add-a-flag-to-allow-screenshots-in-Incognito-mode.patch
  8. 37 37
      build/patches/Add-a-proxy-configuration-page.patch
  9. 22 22
      build/patches/Add-an-always-incognito-mode.patch
  10. 54 72
      build/patches/Add-bookmark-import-export-actions.patch
  11. 7 7
      build/patches/Add-custom-tab-intents-privacy-option.patch
  12. 9 9
      build/patches/Add-exit-menu-item.patch
  13. 3 3
      build/patches/Add-flag-for-omnibox-autocomplete-filtering.patch
  14. 4 4
      build/patches/Add-flag-for-save-data-header.patch
  15. 4 4
      build/patches/Add-flag-to-configure-maximum-connections-per-host.patch
  16. 5 5
      build/patches/Add-flag-to-control-video-playback-resume-feature.patch
  17. 6 6
      build/patches/Add-flag-to-disable-IPv6-probes.patch
  18. 3 3
      build/patches/Add-flag-to-disable-WebGL.patch
  19. 5 5
      build/patches/Add-flag-to-disable-external-intent-requests.patch
  20. 13 13
      build/patches/Add-flag-to-disable-vibration.patch
  21. 54 53
      build/patches/Add-history-support-in-incognito-mode.patch
  22. 34 34
      build/patches/Add-menu-item-to-bookmark-all-tabs.patch
  23. 11 11
      build/patches/Add-menu-item-to-view-source.patch
  24. 43 29
      build/patches/Add-option-to-force-tablet-UI.patch
  25. 9 9
      build/patches/Add-option-to-not-persist-tabs-across-sessions.patch
  26. 6 6
      build/patches/Add-option-to-use-home-page-as-NTP.patch
  27. 15 15
      build/patches/Allow-building-without-enable_reporting.patch
  28. 2 2
      build/patches/Allow-playing-audio-in-background.patch
  29. 4 4
      build/patches/Allow-website-sign-in-without-account-sign-in.patch
  30. 1 1
      build/patches/Always-allow-partner-customisation.patch
  31. 2 2
      build/patches/Always-use-new-tab-page-for-default-home-page.patch
  32. 3 3
      build/patches/Ask-user-before-closing-all-tabs.patch
  33. 1 1
      build/patches/AudioBuffer-AnalyserNode-fp-mitigations.patch
  34. 153 112
      build/patches/Automated-domain-substitution.patch
  35. 3 3
      build/patches/Block-gateway-attacks-via-websockets.patch
  36. 5 5
      build/patches/Block-qjz9zk-or-trk-requests.patch
  37. 35 35
      build/patches/Bromite-AdBlockUpdaterService.patch
  38. 10 10
      build/patches/Bromite-auto-updater.patch
  39. 1 1
      build/patches/Change-default-webRTC-policy-to-not-use-any-address.patch
  40. 3 3
      build/patches/Disable-AGSA-by-default.patch
  41. 1 1
      build/patches/Disable-Accessibility-service-by-default.patch
  42. 1 1
      build/patches/Disable-DRM-media-origin-IDs-preprovisioning.patch
  43. 23 24
      build/patches/Disable-FLoC.patch
  44. 0 54
      build/patches/Disable-HEAD-requests-for-single-word-Omnibar-searches.patch
  45. 2 2
      build/patches/Disable-all-promo-dialogs.patch
  46. 49 48
      build/patches/Disable-conversion-measurement-api.patch
  47. 1 1
      build/patches/Disable-feeds-support-by-default.patch
  48. 7 7
      build/patches/Disable-fetching-of-all-field-trials.patch
  49. 2 2
      build/patches/Disable-media-router-and-remoting-by-default.patch
  50. 4 4
      build/patches/Disable-metrics-collection-for-NTP-tiles.patch
  51. 1 1
      build/patches/Disable-metrics-on-all-I-O-threads.patch
  52. 1 1
      build/patches/Disable-plugins-enumeration.patch
  53. 11 11
      build/patches/Disable-privacy-sandbox.patch
  54. 29 0
      build/patches/Disable-requests-for-single-word-Omnibar-searches.patch
  55. 158 139
      build/patches/Disable-safe-browsing.patch
  56. 10 10
      build/patches/Disable-smart-selection-by-default.patch
  57. 2 2
      build/patches/Disable-some-signed-exchange-features.patch
  58. 6 6
      build/patches/Disable-text-fragments-by-default.patch
  59. 2 2
      build/patches/Disable-the-DIAL-repeating-discovery.patch
  60. 0 24
      build/patches/Disable-third-party-cookies-by-default.patch
  61. 12 12
      build/patches/Disable-third-party-origin-trials.patch
  62. 1 1
      build/patches/Disable-unified-autoplay-feature.patch
  63. 1 1
      build/patches/Do-not-build-API-keys-infobar.patch
  64. 6 6
      build/patches/Do-not-compile-QR-code-sharing.patch
  65. 6 5
      build/patches/Do-not-ignore-download-location-prompt-setting.patch
  66. 11 11
      build/patches/Enable-SPPI-for-devices-with-enough-memory.patch
  67. 2 2
      build/patches/Enable-darken-websites-checkbox-in-themes.patch
  68. 1 1
      build/patches/Enable-fwrapv-in-Clang-for-non-UBSan-builds.patch
  69. 18 18
      build/patches/Enable-native-Android-autofill.patch
  70. 1 1
      build/patches/Enable-prefetch-privacy-changes-by-default.patch
  71. 11 11
      build/patches/Enable-share-intent.patch
  72. 1 1
      build/patches/Enable-user-agent-freeze-by-default.patch
  73. 0 10640
      build/patches/Experimental-user-scripts-support.patch
  74. 2 2
      build/patches/Hide-passwords-manager-link.patch
  75. 2 2
      build/patches/Increase-number-of-autocomplete-matches-from-5-to-10.patch
  76. 8 8
      build/patches/Inject-scripts-for-AMP-tracking-ads-and-video.patch
  77. 13 14
      build/patches/JIT-less-toggle.patch
  78. 2 2
      build/patches/Keep-empty-tabs-between-sessions.patch
  79. 11 13
      build/patches/Logcat-crash-reports-UI.patch
  80. 3 3
      build/patches/Modify-default-preferences.patch
  81. 11 11
      build/patches/Move-some-account-settings-back-to-privacy-settings.patch
  82. 23 23
      build/patches/Multiple-fingerprinting-mitigations.patch
  83. 0 33
      build/patches/Never-send-any-crash-upload-data.patch
  84. 1 1
      build/patches/Offer-builtin-autocomplete-for-chrome-flags.patch
  85. 1 1
      build/patches/Override-UA-client-hint-for-model.patch
  86. 6 6
      build/patches/Reduce-HTTP-headers-in-DoH-requests-to-bare-minimum.patch
  87. 1 1
      build/patches/Remove-EV-certificates.patch
  88. 3 3
      build/patches/Remove-SMS-integration.patch
  89. 44 80
      build/patches/Remove-binary-blob-integrations.patch
  90. 5 5
      build/patches/Remove-blocklisted-URLs-upon-bookmark-creation.patch
  91. 6 6
      build/patches/Remove-help-menu-item.patch
  92. 1 1
      build/patches/Remove-offline-measurement-background-task.patch
  93. 232 168
      build/patches/Remove-signin-and-data-saver-integrations.patch
  94. 1 1
      build/patches/Replace-DoH-probe-domain-with-RIPE-domain.patch
  95. 19 19
      build/patches/Restore-Search-Ready-Omnibox-flag.patch
  96. 14 14
      build/patches/Restore-Simplified-NTP-launch.patch
  97. 4 4
      build/patches/Revert-flags-remove-disable-pull-to-refresh-effect.patch
  98. 8 8
      build/patches/Revert-flags-remove-num-raster-threads.patch
  99. 69 94
      build/patches/Revert-the-removal-of-an-option-to-block-autoplay.patch
  100. 4 4
      build/patches/Show-site-settings-for-cookies-javascript-and-ads.patch

+ 1 - 1
build/RELEASE

@@ -1 +1 @@
-95.0.4638.78
+96.0.4664.54

+ 3 - 5
build/bromite_patches_list.txt

@@ -1,4 +1,3 @@
-Disable-third-party-cookies-by-default.patch
 AV1-codec-support.patch
 Switch-to-fstack-protector-strong.patch
 Enable-fwrapv-in-Clang-for-non-UBSan-builds.patch
@@ -17,7 +16,6 @@ Do-not-store-passwords-by-default.patch
 Disable-NTP-remote-suggestions-by-default.patch
 Disable-references-to-fonts.googleapis.com.patch
 Change-default-webRTC-policy-to-not-use-any-address.patch
-Never-send-any-crash-upload-data.patch
 Hide-send-reports-checkbox.patch
 Never-fetch-popular-sites.patch
 ungoogled-chromium-Disable-webRTC-log-uploader.patch
@@ -90,7 +88,7 @@ disable-AdsBlockedInfoBar.patch
 Bromite-AdBlockUpdaterService.patch
 Replace-DoH-probe-domain-with-RIPE-domain.patch
 Increase-number-of-autocomplete-matches-from-5-to-10.patch
-Disable-HEAD-requests-for-single-word-Omnibar-searches.patch
+Disable-requests-for-single-word-Omnibar-searches.patch
 Disable-some-signed-exchange-features.patch
 Add-flag-to-disable-WebGL.patch
 DoH-secure-mode-by-default.patch
@@ -118,9 +116,9 @@ Disable-the-DIAL-repeating-discovery.patch
 Block-qjz9zk-or-trk-requests.patch
 Hardening-against-incognito-mode-detection.patch
 Remove-weblayer-dependency-on-Play-Services.patch
-Timezone-customization.patch
 Move-some-account-settings-back-to-privacy-settings.patch
 Restore-Simplified-NTP-launch.patch
+Add-option-to-use-home-page-as-NTP.patch
 Revert-the-removal-of-an-option-to-block-autoplay.patch
 Disable-text-fragments-by-default.patch
 disable-WebView-variations-support.patch
@@ -132,6 +130,7 @@ Revert-flags-remove-num-raster-threads.patch
 webview-Hard-no-to-persistent-histograms.patch
 Ignore-enterprise-policies-for-secure-DNS.patch
 Add-menu-item-to-bookmark-all-tabs.patch
+Ask-user-before-closing-all-tabs.patch
 Add-flag-for-save-data-header.patch
 Add-option-to-force-tablet-UI.patch
 Make-all-favicon-requests-on-demand.patch
@@ -158,7 +157,6 @@ Add-custom-tab-intents-privacy-option.patch
 Enable-share-intent.patch
 Site-setting-for-images.patch
 Bromite-auto-updater.patch
-Experimental-user-scripts-support.patch
 Enable-native-Android-autofill.patch
 Keep-empty-tabs-between-sessions.patch
 Disable-third-party-origin-trials.patch

+ 13 - 13
build/patches/AImageReader-CFI-crash-mitigations.patch

@@ -61,9 +61,9 @@ diff --git a/base/android/android_image_reader_compat.cc b/base/android/android_
 diff --git a/base/android/android_image_reader_compat.h b/base/android/android_image_reader_compat.h
 --- a/base/android/android_image_reader_compat.h
 +++ b/base/android/android_image_reader_compat.h
-@@ -22,6 +22,9 @@ class BASE_EXPORT AndroidImageReader {
-   // Thread safe GetInstance.
-   static AndroidImageReader& GetInstance();
+@@ -25,6 +25,9 @@ class BASE_EXPORT AndroidImageReader {
+   AndroidImageReader(const AndroidImageReader&) = delete;
+   AndroidImageReader& operator=(const AndroidImageReader&) = delete;
  
 +  // Disable image reader support.
 +  static void DisableSupport();
@@ -71,7 +71,7 @@ diff --git a/base/android/android_image_reader_compat.h b/base/android/android_i
    // Check if the image reader usage is supported. This function returns TRUE
    // if android version is >=OREO, image reader support is not disabled and all
    // the required functions are loaded.
-@@ -59,6 +62,7 @@ class BASE_EXPORT AndroidImageReader {
+@@ -62,6 +65,7 @@ class BASE_EXPORT AndroidImageReader {
    jobject ANativeWindow_toSurface(JNIEnv* env, ANativeWindow* window);
  
   private:
@@ -82,15 +82,15 @@ diff --git a/base/android/android_image_reader_compat.h b/base/android/android_i
 diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
 --- a/chrome/browser/flag-metadata.json
 +++ b/chrome/browser/flag-metadata.json
-@@ -2101,7 +2101,7 @@
+@@ -2121,7 +2121,7 @@
    {
-     "name": "enable-image-reader",
-     "owners": [ "vikassoni", "liberato" ],
+     "name": "enable-launcher-app-paging",
+     "owners": [ "//ash/app_list/OWNERS" ],
 -    "expiry_milestone": 95
 +    "expiry_milestone": -1
    },
    {
-     "name": "enable-immersive-fullscreen-toolbar",
+     "name": "enable-layout-ng",
 diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json
 --- a/gpu/config/gpu_driver_bug_list.json
 +++ b/gpu/config/gpu_driver_bug_list.json
@@ -171,7 +171,7 @@ diff --git a/gpu/config/gpu_util.cc b/gpu/config/gpu_util.cc
 diff --git a/gpu/config/gpu_workaround_list.txt b/gpu/config/gpu_workaround_list.txt
 --- a/gpu/config/gpu_workaround_list.txt
 +++ b/gpu/config/gpu_workaround_list.txt
-@@ -13,6 +13,7 @@ decode_encode_srgb_for_generatemipmap
+@@ -14,6 +14,7 @@ decode_encode_srgb_for_generatemipmap
  depth_stencil_renderbuffer_resize_emulation
  disable_2d_canvas_auto_flush
  disable_accelerated_av1_decode
@@ -182,7 +182,7 @@ diff --git a/gpu/config/gpu_workaround_list.txt b/gpu/config/gpu_workaround_list
 diff --git a/gpu/ipc/service/gpu_init.cc b/gpu/ipc/service/gpu_init.cc
 --- a/gpu/ipc/service/gpu_init.cc
 +++ b/gpu/ipc/service/gpu_init.cc
-@@ -517,6 +517,11 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line,
+@@ -521,6 +521,11 @@ bool GpuInit::InitializeAndStartSandbox(base::CommandLine* command_line,
      }
    }
  
@@ -205,7 +205,7 @@ diff --git a/gpu/ipc/service/stream_texture_android.cc b/gpu/ipc/service/stream_
  #include "base/android/scoped_hardware_buffer_fence_sync.h"
  #include "base/bind.h"
  #include "base/feature_list.h"
-@@ -50,7 +51,15 @@ std::unique_ptr<ui::ScopedMakeCurrent> MakeCurrent(
+@@ -51,7 +52,15 @@ std::unique_ptr<ui::ScopedMakeCurrent> MakeCurrent(
  }
  
  TextureOwner::Mode GetTextureOwnerMode() {
@@ -225,7 +225,7 @@ diff --git a/gpu/ipc/service/stream_texture_android.cc b/gpu/ipc/service/stream_
 diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
 --- a/media/base/media_switches.cc
 +++ b/media/base/media_switches.cc
-@@ -653,6 +653,10 @@ const base::Feature kMediaDrmPreprovisioning{"MediaDrmPreprovisioning",
+@@ -663,6 +663,10 @@ const base::Feature kMediaDrmPreprovisioning{"MediaDrmPreprovisioning",
  // Note: Has no effect if kMediaDrmPreprovisioning feature is disabled.
  const base::Feature kMediaDrmPreprovisioningAtStartup{
      "MediaDrmPreprovisioningAtStartup", base::FEATURE_ENABLED_BY_DEFAULT};
@@ -239,7 +239,7 @@ diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
 diff --git a/media/base/media_switches.h b/media/base/media_switches.h
 --- a/media/base/media_switches.h
 +++ b/media/base/media_switches.h
-@@ -216,6 +216,7 @@ MEDIA_EXPORT extern const base::Feature kForceHardwareAudioDecoders;
+@@ -219,6 +219,7 @@ MEDIA_EXPORT extern const base::Feature kForceHardwareAudioDecoders;
  MEDIA_EXPORT extern const base::Feature kAllowNonSecureOverlays;
  MEDIA_EXPORT extern const base::Feature kMediaControlsExpandGesture;
  MEDIA_EXPORT extern const base::Feature kMediaDrmPersistentLicense;

+ 15 - 15
build/patches/AV1-codec-support.patch

@@ -33,7 +33,7 @@ diff --git a/third_party/libaom/BUILD.gn b/third_party/libaom/BUILD.gn
        include_dirs = libaom_include_dirs
      }
  
-@@ -193,7 +193,7 @@ if (enable_libaom) {
+@@ -194,7 +194,7 @@ if (enable_libaom) {
        configs += [ "//build/config/compiler:no_chromium_code" ]
        if (current_cpu == "arm") {
          configs -= [ "//build/config/compiler:compiler_arm_fpu" ]
@@ -42,7 +42,7 @@ diff --git a/third_party/libaom/BUILD.gn b/third_party/libaom/BUILD.gn
        }
        configs += [ ":libaom_config" ]
  
-@@ -256,6 +256,8 @@ if (enable_libaom) {
+@@ -257,6 +257,8 @@ if (enable_libaom) {
      if (current_cpu == "arm64" || cpu_arch_full == "arm-neon" ||
          cpu_arch_full == "arm-neon-cpu-detect") {
        deps += [ ":libaom_intrinsics_neon" ]
@@ -54,7 +54,7 @@ diff --git a/third_party/libaom/BUILD.gn b/third_party/libaom/BUILD.gn
 diff --git a/third_party/libaom/libaom_srcs.gni b/third_party/libaom/libaom_srcs.gni
 --- a/third_party/libaom/libaom_srcs.gni
 +++ b/third_party/libaom/libaom_srcs.gni
-@@ -634,6 +634,11 @@ aom_mem_sources = [
+@@ -642,6 +642,11 @@ aom_mem_sources = [
  
  aom_ports_asm_x86 = [ "//third_party/libaom/source/libaom/aom_ports/float.asm" ]
  
@@ -69,7 +69,7 @@ diff --git a/third_party/libaom/libaom_srcs.gni b/third_party/libaom/libaom_srcs
 diff --git a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.asm b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.asm
 --- a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.asm
 +++ b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.asm
-@@ -48,7 +48,7 @@ CONFIG_NORMAL_TILE_MODE equ 1
+@@ -49,7 +49,7 @@ CONFIG_NORMAL_TILE_MODE equ 1
  CONFIG_OPTICAL_FLOW_API equ 0
  CONFIG_OS_SUPPORT equ 1
  CONFIG_PARTITION_SEARCH_ORDER equ 0
@@ -81,7 +81,7 @@ diff --git a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/a
 diff --git a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.h b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.h
 --- a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.h
 +++ b/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/aom_config.h
-@@ -50,7 +50,7 @@
+@@ -51,7 +51,7 @@
  #define CONFIG_OPTICAL_FLOW_API 0
  #define CONFIG_OS_SUPPORT 1
  #define CONFIG_PARTITION_SEARCH_ORDER 0
@@ -93,7 +93,7 @@ diff --git a/third_party/libaom/source/config/linux/arm-neon-cpu-detect/config/a
 diff --git a/third_party/libaom/source/config/linux/arm-neon/config/aom_config.asm b/third_party/libaom/source/config/linux/arm-neon/config/aom_config.asm
 --- a/third_party/libaom/source/config/linux/arm-neon/config/aom_config.asm
 +++ b/third_party/libaom/source/config/linux/arm-neon/config/aom_config.asm
-@@ -48,7 +48,7 @@ CONFIG_NORMAL_TILE_MODE equ 1
+@@ -49,7 +49,7 @@ CONFIG_NORMAL_TILE_MODE equ 1
  CONFIG_OPTICAL_FLOW_API equ 0
  CONFIG_OS_SUPPORT equ 1
  CONFIG_PARTITION_SEARCH_ORDER equ 0
@@ -105,7 +105,7 @@ diff --git a/third_party/libaom/source/config/linux/arm-neon/config/aom_config.a
 diff --git a/third_party/libaom/source/config/linux/arm-neon/config/aom_config.h b/third_party/libaom/source/config/linux/arm-neon/config/aom_config.h
 --- a/third_party/libaom/source/config/linux/arm-neon/config/aom_config.h
 +++ b/third_party/libaom/source/config/linux/arm-neon/config/aom_config.h
-@@ -50,7 +50,7 @@
+@@ -51,7 +51,7 @@
  #define CONFIG_OPTICAL_FLOW_API 0
  #define CONFIG_OS_SUPPORT 1
  #define CONFIG_PARTITION_SEARCH_ORDER 0
@@ -117,7 +117,7 @@ diff --git a/third_party/libaom/source/config/linux/arm-neon/config/aom_config.h
 diff --git a/third_party/libaom/source/config/linux/arm/config/aom_config.asm b/third_party/libaom/source/config/linux/arm/config/aom_config.asm
 --- a/third_party/libaom/source/config/linux/arm/config/aom_config.asm
 +++ b/third_party/libaom/source/config/linux/arm/config/aom_config.asm
-@@ -48,7 +48,7 @@ CONFIG_NORMAL_TILE_MODE equ 1
+@@ -49,7 +49,7 @@ CONFIG_NORMAL_TILE_MODE equ 1
  CONFIG_OPTICAL_FLOW_API equ 0
  CONFIG_OS_SUPPORT equ 1
  CONFIG_PARTITION_SEARCH_ORDER equ 0
@@ -129,7 +129,7 @@ diff --git a/third_party/libaom/source/config/linux/arm/config/aom_config.asm b/
 diff --git a/third_party/libaom/source/config/linux/arm/config/aom_config.h b/third_party/libaom/source/config/linux/arm/config/aom_config.h
 --- a/third_party/libaom/source/config/linux/arm/config/aom_config.h
 +++ b/third_party/libaom/source/config/linux/arm/config/aom_config.h
-@@ -50,7 +50,7 @@
+@@ -51,7 +51,7 @@
  #define CONFIG_OPTICAL_FLOW_API 0
  #define CONFIG_OS_SUPPORT 1
  #define CONFIG_PARTITION_SEARCH_ORDER 0
@@ -141,7 +141,7 @@ diff --git a/third_party/libaom/source/config/linux/arm/config/aom_config.h b/th
 diff --git a/third_party/libaom/source/config/linux/arm64/config/aom_config.asm b/third_party/libaom/source/config/linux/arm64/config/aom_config.asm
 --- a/third_party/libaom/source/config/linux/arm64/config/aom_config.asm
 +++ b/third_party/libaom/source/config/linux/arm64/config/aom_config.asm
-@@ -48,7 +48,7 @@ CONFIG_NORMAL_TILE_MODE equ 1
+@@ -49,7 +49,7 @@ CONFIG_NORMAL_TILE_MODE equ 1
  CONFIG_OPTICAL_FLOW_API equ 0
  CONFIG_OS_SUPPORT equ 1
  CONFIG_PARTITION_SEARCH_ORDER equ 0
@@ -153,7 +153,7 @@ diff --git a/third_party/libaom/source/config/linux/arm64/config/aom_config.asm
 diff --git a/third_party/libaom/source/config/linux/arm64/config/aom_config.h b/third_party/libaom/source/config/linux/arm64/config/aom_config.h
 --- a/third_party/libaom/source/config/linux/arm64/config/aom_config.h
 +++ b/third_party/libaom/source/config/linux/arm64/config/aom_config.h
-@@ -50,7 +50,7 @@
+@@ -51,7 +51,7 @@
  #define CONFIG_OPTICAL_FLOW_API 0
  #define CONFIG_OS_SUPPORT 1
  #define CONFIG_PARTITION_SEARCH_ORDER 0
@@ -165,7 +165,7 @@ diff --git a/third_party/libaom/source/config/linux/arm64/config/aom_config.h b/
 diff --git a/third_party/libaom/source/config/linux/generic/config/aom_config.asm b/third_party/libaom/source/config/linux/generic/config/aom_config.asm
 --- a/third_party/libaom/source/config/linux/generic/config/aom_config.asm
 +++ b/third_party/libaom/source/config/linux/generic/config/aom_config.asm
-@@ -48,7 +48,7 @@ CONFIG_NORMAL_TILE_MODE equ 1
+@@ -49,7 +49,7 @@ CONFIG_NORMAL_TILE_MODE equ 1
  CONFIG_OPTICAL_FLOW_API equ 0
  CONFIG_OS_SUPPORT equ 1
  CONFIG_PARTITION_SEARCH_ORDER equ 0
@@ -177,7 +177,7 @@ diff --git a/third_party/libaom/source/config/linux/generic/config/aom_config.as
 diff --git a/third_party/libaom/source/config/linux/generic/config/aom_config.h b/third_party/libaom/source/config/linux/generic/config/aom_config.h
 --- a/third_party/libaom/source/config/linux/generic/config/aom_config.h
 +++ b/third_party/libaom/source/config/linux/generic/config/aom_config.h
-@@ -50,7 +50,7 @@
+@@ -51,7 +51,7 @@
  #define CONFIG_OPTICAL_FLOW_API 0
  #define CONFIG_OS_SUPPORT 1
  #define CONFIG_PARTITION_SEARCH_ORDER 0
@@ -189,7 +189,7 @@ diff --git a/third_party/libaom/source/config/linux/generic/config/aom_config.h
 diff --git a/third_party/libaom/source/config/linux/x64/config/aom_config.asm b/third_party/libaom/source/config/linux/x64/config/aom_config.asm
 --- a/third_party/libaom/source/config/linux/x64/config/aom_config.asm
 +++ b/third_party/libaom/source/config/linux/x64/config/aom_config.asm
-@@ -38,7 +38,7 @@
+@@ -39,7 +39,7 @@
  %define CONFIG_OPTICAL_FLOW_API 0
  %define CONFIG_OS_SUPPORT 1
  %define CONFIG_PARTITION_SEARCH_ORDER 0
@@ -201,7 +201,7 @@ diff --git a/third_party/libaom/source/config/linux/x64/config/aom_config.asm b/
 diff --git a/third_party/libaom/source/config/linux/x64/config/aom_config.h b/third_party/libaom/source/config/linux/x64/config/aom_config.h
 --- a/third_party/libaom/source/config/linux/x64/config/aom_config.h
 +++ b/third_party/libaom/source/config/linux/x64/config/aom_config.h
-@@ -50,7 +50,7 @@
+@@ -51,7 +51,7 @@
  #define CONFIG_OPTICAL_FLOW_API 0
  #define CONFIG_OS_SUPPORT 1
  #define CONFIG_PARTITION_SEARCH_ORDER 0

+ 7 - 7
build/patches/Add-AllowUserCertificates-flag.patch

@@ -26,7 +26,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActiv
  import org.chromium.printing.PrintManagerDelegateImpl;
  import org.chromium.printing.PrintingController;
  import org.chromium.printing.PrintingControllerImpl;
-@@ -984,6 +985,8 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
+@@ -981,6 +982,8 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
          UpdateMenuItemHelper.getInstance().onStart();
          ChromeActivitySessionTracker.getInstance().onStartWithNative();
          ChromeCachedFlags.getInstance().cacheNativeFlags();
@@ -38,9 +38,9 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActiv
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
-@@ -87,6 +87,7 @@ public class ChromeCachedFlags {
-                 add(ChromeFeatureList.EARLY_LIBRARY_LOAD);
-                 add(ChromeFeatureList.ELASTIC_OVERSCROLL);
+@@ -90,6 +90,7 @@ public class ChromeCachedFlags {
+                 add(ChromeFeatureList
+                                 .GIVE_JAVA_UI_THREAD_DEFAULT_TASK_TRAITS_USER_BLOCKING_PRIORITY);
                  add(ChromeFeatureList.IMMERSIVE_UI_MODE);
 +                add(ChromeFeatureList.ALLOW_USER_CERTIFICATES);
                  add(ChromeFeatureList.INSTANT_START);
@@ -49,7 +49,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/Chrom
 diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 --- a/chrome/browser/about_flags.cc
 +++ b/chrome/browser/about_flags.cc
-@@ -2910,6 +2910,10 @@ const FeatureEntry kFeatureEntries[] = {
+@@ -2874,6 +2874,10 @@ const FeatureEntry kFeatureEntries[] = {
       flag_descriptions::kCSSContainerQueriesDescription, kOsAll,
       FEATURE_VALUE_TYPE(blink::features::kCSSContainerQueries)},
  #if defined(OS_ANDROID)
@@ -91,7 +91,7 @@ diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptio
 diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
 --- a/chrome/browser/flags/android/chrome_feature_list.cc
 +++ b/chrome/browser/flags/android/chrome_feature_list.cc
-@@ -142,6 +142,7 @@ const base::Feature* const kFeaturesExposedToJava[] = {
+@@ -150,6 +150,7 @@ const base::Feature* const kFeaturesExposedToJava[] = {
      &feed::kFeedSignInPromoDismiss,
      &feed::kInterestFeedContentSuggestions,
      &feed::kInterestFeedSpinnerAlwaysAnimate,
@@ -99,7 +99,7 @@ diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browse
      &feed::kInterestFeedV1ClicksAndViewsConditionalUpload,
      &feed::kInterestFeedV2,
      &feed::kInterestFeedV2Autoplay,
-@@ -377,6 +378,9 @@ const base::Feature kAdaptiveButtonInTopToolbarCustomizationV2{
+@@ -387,6 +388,9 @@ const base::Feature kAdaptiveButtonInTopToolbarCustomizationV2{
      "AdaptiveButtonInTopToolbarCustomizationV2",
      base::FEATURE_DISABLED_BY_DEFAULT};
  

+ 4 - 4
build/patches/Add-IsCleartextPermitted-flag.patch

@@ -14,7 +14,7 @@ Subject: Add IsCleartextPermitted flag
 diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 --- a/chrome/browser/about_flags.cc
 +++ b/chrome/browser/about_flags.cc
-@@ -7852,6 +7852,11 @@ const FeatureEntry kFeatureEntries[] = {
+@@ -7783,6 +7783,11 @@ const FeatureEntry kFeatureEntries[] = {
       FEATURE_VALUE_TYPE(
           chrome::android::kBookmarksExportUseSaf)},
  
@@ -29,7 +29,7 @@ diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
 --- a/chrome/browser/flag_descriptions.cc
 +++ b/chrome/browser/flag_descriptions.cc
-@@ -1460,6 +1460,10 @@ const char kHttpsOnlyModeDescription[] =
+@@ -1507,6 +1507,10 @@ const char kHttpsOnlyModeDescription[] =
      "Adds a setting under chrome://settings/security to opt-in to HTTPS-First "
      "Mode.";
  
@@ -43,7 +43,7 @@ diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descripti
 diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
 --- a/chrome/browser/flag_descriptions.h
 +++ b/chrome/browser/flag_descriptions.h
-@@ -845,6 +845,9 @@ extern const char kHostedAppShimCreationDescription[];
+@@ -867,6 +867,9 @@ extern const char kHostedAppShimCreationDescription[];
  extern const char kHttpsOnlyModeName[];
  extern const char kHttpsOnlyModeDescription[];
  
@@ -81,7 +81,7 @@ diff --git a/net/base/features.h b/net/base/features.h
 diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
 --- a/net/url_request/url_request_http_job.cc
 +++ b/net/url_request/url_request_http_job.cc
-@@ -215,6 +215,10 @@ std::unique_ptr<URLRequestJob> URLRequestHttpJob::Create(URLRequest* request) {
+@@ -234,6 +234,10 @@ std::unique_ptr<URLRequestJob> URLRequestHttpJob::Create(URLRequest* request) {
      }
  
  #if defined(OS_ANDROID)

+ 5 - 5
build/patches/Add-a-flag-to-allow-screenshots-in-Incognito-mode.patch

@@ -17,7 +17,7 @@ See also:
 diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 --- a/chrome/browser/about_flags.cc
 +++ b/chrome/browser/about_flags.cc
-@@ -7709,6 +7709,12 @@ const FeatureEntry kFeatureEntries[] = {
+@@ -7538,6 +7538,12 @@ const FeatureEntry kFeatureEntries[] = {
                                      "AndroidDynamicColor")},
  #endif  //   defined(OS_ANDROID)
  
@@ -33,7 +33,7 @@ diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
 --- a/chrome/browser/flag_descriptions.cc
 +++ b/chrome/browser/flag_descriptions.cc
-@@ -658,6 +658,11 @@ const char kEnableAutofillCreditCardAuthenticationDescription[] =
+@@ -712,6 +712,11 @@ const char kEnableAutofillCreditCardAuthenticationDescription[] =
      "authenticator (if available) to verify card ownership when retrieving "
      "credit cards from Google Payments.";
  
@@ -48,7 +48,7 @@ diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descripti
 diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
 --- a/chrome/browser/flag_descriptions.h
 +++ b/chrome/browser/flag_descriptions.h
-@@ -420,6 +420,9 @@ extern const char kEnableAutofillSaveCardInfoBarAccountIndicationFooterName[];
+@@ -446,6 +446,9 @@ extern const char kEnableAutofillSaveCardInfoBarAccountIndicationFooterName[];
  extern const char
      kEnableAutofillSaveCardInfoBarAccountIndicationFooterDescription[];
  
@@ -75,7 +75,7 @@ diff --git a/chrome/browser/flags/android/java_templates/ChromeSwitches.java.tmp
 diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
 --- a/chrome/common/chrome_switches.cc
 +++ b/chrome/common/chrome_switches.cc
-@@ -344,6 +344,9 @@ const char kHomePage[]                      = "homepage";
+@@ -335,6 +335,9 @@ const char kHomePage[]                      = "homepage";
  // Causes the browser to launch directly in incognito mode.
  const char kIncognito[]                     = "incognito";
  
@@ -88,7 +88,7 @@ diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
 diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
 --- a/chrome/common/chrome_switches.h
 +++ b/chrome/common/chrome_switches.h
-@@ -114,6 +114,7 @@ extern const char kForceStackedTabStripLayout[];
+@@ -110,6 +110,7 @@ extern const char kForceStackedTabStripLayout[];
  extern const char kHideCrashRestoreBubble[];
  extern const char kHomePage[];
  extern const char kIncognito[];

+ 37 - 37
build/patches/Add-a-proxy-configuration-page.patch

@@ -70,7 +70,7 @@ diff --git a/chrome/android/java/res/xml/privacy_preferences.xml b/chrome/androi
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
-@@ -49,6 +49,7 @@ import org.chromium.ui.text.SpanApplier;
+@@ -52,6 +52,7 @@ import org.chromium.ui.text.SpanApplier;
  public class PrivacySettings
          extends PreferenceFragmentCompat implements Preference.OnPreferenceChangeListener,
                                                      INeedSnackbarManager {
@@ -81,7 +81,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
 diff --git a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
 --- a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
 +++ b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
-@@ -367,6 +367,8 @@ ChromeAutocompleteProviderClient::GetBuiltinsToProvideAsUserTypes() {
+@@ -374,6 +374,8 @@ ChromeAutocompleteProviderClient::GetBuiltinsToProvideAsUserTypes() {
    builtins_to_provide.push_back(
        base::ASCIIToUTF16(chrome::kChromeUISettingsURL));
  #endif
@@ -119,7 +119,7 @@ diff --git a/chrome/browser/net/proxy_service_factory.cc b/chrome/browser/net/pr
  
  #if BUILDFLAG(IS_CHROMEOS_ASH)
  #include "chromeos/network/proxy/proxy_config_service_impl.h"
-@@ -59,7 +62,20 @@ ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile(
+@@ -73,7 +76,20 @@ ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile(
    return std::make_unique<chromeos::ProxyConfigServiceImpl>(
        profile_prefs, local_state_prefs, nullptr);
  #else
@@ -141,7 +141,7 @@ diff --git a/chrome/browser/net/proxy_service_factory.cc b/chrome/browser/net/pr
  #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
  }
  
-@@ -75,3 +91,8 @@ ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState(
+@@ -89,3 +105,8 @@ ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState(
                                                        nullptr);
  #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
  }
@@ -162,18 +162,18 @@ diff --git a/chrome/browser/net/proxy_service_factory.h b/chrome/browser/net/pro
  class PrefProxyConfigTracker;
  class PrefService;
 @@ -37,6 +38,8 @@ class ProxyServiceFactory {
-   static std::unique_ptr<PrefProxyConfigTracker>
-   CreatePrefProxyConfigTrackerOfLocalState(PrefService* local_state_prefs);
+   CreatePrefProxyConfigTrackerOfProfile(PrefService* profile_prefs,
+                                         PrefService* local_state_prefs);
  
 +  static void RegisterPrefs(PrefRegistrySimple* registry);
 +
-  private:
-   DISALLOW_IMPLICIT_CONSTRUCTORS(ProxyServiceFactory);
- };
+   // Creates a PrefProxyConfigTracker that tracks local state only. This tracker
+   // should be used for the system request context and the signin screen
+   // (ChromeOS only).
 diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
 --- a/chrome/browser/prefs/browser_prefs.cc
 +++ b/chrome/browser/prefs/browser_prefs.cc
-@@ -160,6 +160,8 @@
+@@ -164,6 +164,8 @@
  #include "printing/buildflags/buildflags.h"
  #include "rlz/buildflags/buildflags.h"
  
@@ -182,7 +182,7 @@ diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browse
  #if BUILDFLAG(ENABLE_BACKGROUND_MODE)
  #include "chrome/browser/background/background_mode_manager.h"
  #endif
-@@ -941,6 +943,8 @@ void RegisterLocalState(PrefRegistrySimple* registry) {
+@@ -960,6 +962,8 @@ void RegisterLocalState(PrefRegistrySimple* registry) {
    PluginsResourceService::RegisterPrefs(registry);
  #endif
  
@@ -194,7 +194,7 @@ diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browse
 diff --git a/chrome/browser/prefs/chrome_command_line_pref_store.cc b/chrome/browser/prefs/chrome_command_line_pref_store.cc
 --- a/chrome/browser/prefs/chrome_command_line_pref_store.cc
 +++ b/chrome/browser/prefs/chrome_command_line_pref_store.cc
-@@ -157,7 +157,7 @@ void ChromeCommandLinePrefStore::ApplyProxyMode() {
+@@ -161,7 +161,7 @@ void ChromeCommandLinePrefStore::ApplyProxyMode() {
      SetValue(
          proxy_config::prefs::kProxy,
          std::make_unique<base::Value>(ProxyConfigDictionary::CreateFixedServers(
@@ -627,7 +627,7 @@ new file mode 100644
 diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
 --- a/chrome/browser/ui/BUILD.gn
 +++ b/chrome/browser/ui/BUILD.gn
-@@ -265,6 +265,8 @@ static_library("ui") {
+@@ -278,6 +278,8 @@ static_library("ui") {
      "webui/metrics_handler.h",
      "webui/net_export_ui.cc",
      "webui/net_export_ui.h",
@@ -646,8 +646,8 @@ diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrom
 +#include "chrome/browser/ui/webui/proxy_config_ui.h"
  #include "chrome/browser/ui/webui/quota_internals/quota_internals_ui.h"
  #include "chrome/browser/ui/webui/signin_internals_ui.h"
- #include "chrome/browser/ui/webui/sync_internals/sync_internals_ui.h"
-@@ -638,6 +639,8 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui,
+ #include "chrome/browser/ui/webui/support_tool_ui.h"
+@@ -644,6 +645,8 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui,
      return &NewWebUI<MemoryInternalsUI>;
    if (url.host_piece() == chrome::kChromeUINetExportHost)
      return &NewWebUI<NetExportUI>;
@@ -801,7 +801,7 @@ new file mode 100644
 +  }
 +
 +  proxy_config_service_ = ProxyServiceFactory::CreateProxyConfigService(
-+      pref_proxy_config_tracker_.get());
++      pref_proxy_config_tracker_.get(), nullptr);
 +}
 +
 +void ProxyConfigMessageHandler::OnProxyConfigChanged(
@@ -1121,7 +1121,7 @@ new file mode 100644
 diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc
 --- a/chrome/common/webui_url_constants.cc
 +++ b/chrome/common/webui_url_constants.cc
-@@ -35,6 +35,8 @@ const char kChromeUICertificateViewerHost[] = "view-cert";
+@@ -37,6 +37,8 @@ const char kChromeUICertificateViewerHost[] = "view-cert";
  const char kChromeUICertificateViewerURL[] = "chrome://view-cert/";
  const char kChromeUIChromeSigninHost[] = "chrome-signin";
  const char kChromeUIChromeSigninURL[] = "chrome://chrome-signin/";
@@ -1130,7 +1130,7 @@ diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_cons
  const char kChromeUIChromeURLsHost[] = "chrome-urls";
  const char kChromeUIChromeURLsURL[] = "chrome://chrome-urls/";
  const char kChromeUIComponentsHost[] = "components";
-@@ -346,6 +348,7 @@ bool IsSystemWebUIHost(base::StringPiece host) {
+@@ -354,6 +356,7 @@ bool IsSystemWebUIHost(base::StringPiece host) {
      kChromeUIMobileSetupHost,
      kChromeUIMultiDeviceSetupHost,
      kChromeUINetworkHost,
@@ -1138,7 +1138,7 @@ diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_cons
      kChromeUIOobeHost,
      kChromeUIOSCreditsHost,
      kChromeUIOSSettingsHost,
-@@ -568,6 +571,7 @@ const char* const kChromeHostURLs[] = {
+@@ -584,6 +587,7 @@ const char* const kChromeHostURLs[] = {
  #if !defined(OS_ANDROID)
  #if !BUILDFLAG(IS_CHROMEOS_ASH)
      kChromeUIAppLauncherPageHost,
@@ -1149,7 +1149,7 @@ diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_cons
 diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h
 --- a/chrome/common/webui_url_constants.h
 +++ b/chrome/common/webui_url_constants.h
-@@ -126,6 +126,8 @@ extern const char kChromeUIMemoryInternalsHost[];
+@@ -127,6 +127,8 @@ extern const char kChromeUIMemoryInternalsHost[];
  extern const char kChromeUINTPTilesInternalsHost[];
  extern const char kChromeUINaClHost[];
  extern const char kChromeUINetExportHost[];
@@ -1172,7 +1172,7 @@ diff --git a/components/proxy_config/pref_proxy_config_tracker_impl.cc b/compone
 diff --git a/components/proxy_config/proxy_config_dictionary.cc b/components/proxy_config/proxy_config_dictionary.cc
 --- a/components/proxy_config/proxy_config_dictionary.cc
 +++ b/components/proxy_config/proxy_config_dictionary.cc
-@@ -28,6 +28,8 @@ const char kProxyPacMandatory[] = "pac_mandatory";
+@@ -30,6 +30,8 @@ const char kProxyPacMandatory[] = "pac_mandatory";
  // String containing proxy bypass rules. For a specification of the
  // expected syntax see net::ProxyBypassRules::ParseFromString().
  const char kProxyBypassList[] = "bypass_list";
@@ -1181,7 +1181,7 @@ diff --git a/components/proxy_config/proxy_config_dictionary.cc b/components/pro
  
  }  // namespace
  
-@@ -72,6 +74,14 @@ bool ProxyConfigDictionary::HasBypassList() const {
+@@ -78,6 +80,14 @@ bool ProxyConfigDictionary::HasBypassList() const {
    return dict_.FindKey(kProxyBypassList);
  }
  
@@ -1196,7 +1196,7 @@ diff --git a/components/proxy_config/proxy_config_dictionary.cc b/components/pro
  const base::Value& ProxyConfigDictionary::GetDictionary() const {
    return dict_;
  }
-@@ -79,29 +89,30 @@ const base::Value& ProxyConfigDictionary::GetDictionary() const {
+@@ -85,29 +95,30 @@ const base::Value& ProxyConfigDictionary::GetDictionary() const {
  // static
  base::Value ProxyConfigDictionary::CreateDirect() {
    return CreateDictionary(ProxyPrefs::MODE_DIRECT, std::string(), false,
@@ -1232,7 +1232,7 @@ diff --git a/components/proxy_config/proxy_config_dictionary.cc b/components/pro
    } else {
      return CreateDirect();
    }
-@@ -110,7 +121,7 @@ base::Value ProxyConfigDictionary::CreateFixedServers(
+@@ -116,7 +127,7 @@ base::Value ProxyConfigDictionary::CreateFixedServers(
  // static
  base::Value ProxyConfigDictionary::CreateSystem() {
    return CreateDictionary(ProxyPrefs::MODE_SYSTEM, std::string(), false,
@@ -1241,7 +1241,7 @@ diff --git a/components/proxy_config/proxy_config_dictionary.cc b/components/pro
  }
  
  // static
-@@ -119,7 +130,8 @@ base::Value ProxyConfigDictionary::CreateDictionary(
+@@ -125,7 +136,8 @@ base::Value ProxyConfigDictionary::CreateDictionary(
      const std::string& pac_url,
      bool pac_mandatory,
      const std::string& proxy_server,
@@ -1251,7 +1251,7 @@ diff --git a/components/proxy_config/proxy_config_dictionary.cc b/components/pro
    base::Value dict(base::Value::Type::DICTIONARY);
    dict.SetKey(kProxyMode, base::Value(ProxyModeToString(mode)));
    if (!pac_url.empty()) {
-@@ -128,8 +140,10 @@ base::Value ProxyConfigDictionary::CreateDictionary(
+@@ -134,8 +146,10 @@ base::Value ProxyConfigDictionary::CreateDictionary(
    }
    if (!proxy_server.empty())
      dict.SetKey(kProxyServer, base::Value(proxy_server));
@@ -1266,7 +1266,7 @@ diff --git a/components/proxy_config/proxy_config_dictionary.cc b/components/pro
 diff --git a/components/proxy_config/proxy_config_dictionary.h b/components/proxy_config/proxy_config_dictionary.h
 --- a/components/proxy_config/proxy_config_dictionary.h
 +++ b/components/proxy_config/proxy_config_dictionary.h
-@@ -38,6 +38,7 @@ class PROXY_CONFIG_EXPORT ProxyConfigDictionary {
+@@ -43,6 +43,7 @@ class PROXY_CONFIG_EXPORT ProxyConfigDictionary {
    bool GetProxyServer(std::string* out) const;
    bool GetBypassList(std::string* out) const;
    bool HasBypassList() const;
@@ -1274,7 +1274,7 @@ diff --git a/components/proxy_config/proxy_config_dictionary.h b/components/prox
  
    const base::Value& GetDictionary() const;
  
-@@ -46,7 +47,8 @@ class PROXY_CONFIG_EXPORT ProxyConfigDictionary {
+@@ -51,7 +52,8 @@ class PROXY_CONFIG_EXPORT ProxyConfigDictionary {
    static base::Value CreatePacScript(const std::string& pac_url,
                                       bool pac_mandatory);
    static base::Value CreateFixedServers(const std::string& proxy_server,
@@ -1284,7 +1284,7 @@ diff --git a/components/proxy_config/proxy_config_dictionary.h b/components/prox
    static base::Value CreateSystem();
  
    // Encodes the proxy server as "<url-scheme>=<proxy-scheme>://<proxy>".
-@@ -62,7 +64,8 @@ class PROXY_CONFIG_EXPORT ProxyConfigDictionary {
+@@ -67,7 +69,8 @@ class PROXY_CONFIG_EXPORT ProxyConfigDictionary {
                                        const std::string& pac_url,
                                        bool pac_mandatory,
                                        const std::string& proxy_server,
@@ -1293,7 +1293,7 @@ diff --git a/components/proxy_config/proxy_config_dictionary.h b/components/prox
 +                                      bool reverse_bypass);
  
    base::Value dict_;
- 
+ };
 diff --git a/components/proxy_config/proxy_policy_handler.cc b/components/proxy_config/proxy_policy_handler.cc
 --- a/components/proxy_config/proxy_policy_handler.cc
 +++ b/components/proxy_config/proxy_policy_handler.cc
@@ -1309,7 +1309,7 @@ diff --git a/components/proxy_config/proxy_policy_handler.cc b/components/proxy_
 diff --git a/net/proxy_resolution/proxy_config.cc b/net/proxy_resolution/proxy_config.cc
 --- a/net/proxy_resolution/proxy_config.cc
 +++ b/net/proxy_resolution/proxy_config.cc
-@@ -110,7 +110,7 @@ void ProxyConfig::ProxyRules::ParseFromString(const std::string& proxy_rules) {
+@@ -112,7 +112,7 @@ void ProxyConfig::ProxyRules::ParseFromString(const std::string& proxy_rules) {
                                     &single_proxies,
                                     ProxyServer::SCHEME_HTTP);
          type = Type::PROXY_LIST;
@@ -1318,7 +1318,7 @@ diff --git a/net/proxy_resolution/proxy_config.cc b/net/proxy_resolution/proxy_c
        }
  
        // Trim whitespace off the url scheme.
-@@ -141,6 +141,56 @@ void ProxyConfig::ProxyRules::ParseFromString(const std::string& proxy_rules) {
+@@ -143,6 +143,56 @@ void ProxyConfig::ProxyRules::ParseFromString(const std::string& proxy_rules) {
    }
  }
  
@@ -1332,7 +1332,7 @@ diff --git a/net/proxy_resolution/proxy_config.cc b/net/proxy_resolution/proxy_c
 +    std::string proxy_list;
 +    for (const ProxyServer& proxy_server :
 +         single_proxies.GetAll()) {
-+      proxy_list += proxy_server.ToURI() + ";";
++      proxy_list += ProxyServerToProxyUri(proxy_server) + ";";
 +    }
 +    // remove last semicolon
 +    if (proxy_list.length() != 0 ) {
@@ -1351,19 +1351,19 @@ diff --git a/net/proxy_resolution/proxy_config.cc b/net/proxy_resolution/proxy_c
 +  std::string list;
 +  for (const ProxyServer& proxy_server :
 +       proxies_for_http.GetAll()) {
-+    list += "http=" + proxy_server.ToURI() + ";";
++    list += "http=" + ProxyServerToProxyUri(proxy_server) + ";";
 +  }
 +  for (const ProxyServer& proxy_server :
 +       proxies_for_https.GetAll()) {
-+    list += "https=" + proxy_server.ToURI() + ";";
++    list += "https=" + ProxyServerToProxyUri(proxy_server) + ";";
 +  }
 +  for (const ProxyServer& proxy_server :
 +       proxies_for_ftp.GetAll()) {
-+    list += "ftp=" + proxy_server.ToURI() + ";";
++    list += "ftp=" + ProxyServerToProxyUri(proxy_server) + ";";
 +  }
 +  for (const ProxyServer& proxy_server :
 +       fallback_proxies.GetAll()) {
-+    list += "socks=" + proxy_server.ToURI() + ";";
++    list += "socks=" + ProxyServerToProxyUri(proxy_server) + ";";
 +  }
 +  if (list.length() != 0 ) {
 +    // remove last semicolon

+ 22 - 22
build/patches/Add-an-always-incognito-mode.patch

@@ -45,7 +45,7 @@ diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java
 diff --git a/chrome/android/java/res/xml/privacy_preferences.xml b/chrome/android/java/res/xml/privacy_preferences.xml
 --- a/chrome/android/java/res/xml/privacy_preferences.xml
 +++ b/chrome/android/java/res/xml/privacy_preferences.xml
-@@ -32,6 +32,11 @@
+@@ -37,6 +37,11 @@
          android:key="secure_dns"
          android:title="@string/settings_secure_dns_title"
          android:fragment="org.chromium.chrome.browser.privacy.secure_dns.SecureDnsSettings"/>
@@ -153,7 +153,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedAct
  import org.chromium.chrome.browser.IntentHandler.IntentHandlerDelegate;
  import org.chromium.chrome.browser.IntentHandler.TabOpenType;
  import org.chromium.chrome.browser.accessibility_tab_switcher.OverviewListLayout;
-@@ -1766,8 +1767,9 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
+@@ -1770,8 +1771,9 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
          Bundle savedInstanceState = getSavedInstanceState();
  
          // We determine the model as soon as possible so every systems get initialized coherently.
@@ -176,7 +176,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActiv
  import org.chromium.chrome.browser.dependency_injection.ChromeActivityComponent;
  import org.chromium.chrome.browser.dependency_injection.ModuleFactoryOverrides;
  import org.chromium.chrome.browser.device.DeviceClassManager;
-@@ -1884,6 +1885,9 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
+@@ -1891,6 +1892,9 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
              throw new IllegalStateException(
                      "Attempting to access TabCreator before initialization");
          }
@@ -189,7 +189,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActiv
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
-@@ -378,6 +378,12 @@ public class AppMenuPropertiesDelegateImpl implements AppMenuPropertiesDelegate
+@@ -538,6 +538,12 @@ public class AppMenuPropertiesDelegateImpl implements AppMenuPropertiesDelegate
      }
  
      private void prepareCommonMenuItems(Menu menu, @MenuGroup int menuGroup, boolean isIncognito) {
@@ -201,7 +201,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/App
 +
          // We have to iterate all menu items since same menu item ID may be associated with more
          // than one menu items.
-         boolean isMenuGroupTabsVisible = TabUiFeatureUtilities.isTabGroupsAndroidEnabled(mContext)
+         boolean isOverviewModeMenu = menuGroup == MenuGroup.OVERVIEW_MODE_MENU;
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -340,7 +340,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/StartupTab
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
-@@ -26,6 +26,10 @@ import org.chromium.chrome.browser.profiles.Profile;
+@@ -29,6 +29,10 @@ import org.chromium.chrome.browser.profiles.Profile;
  import org.chromium.chrome.browser.settings.ChromeManagedPreferenceDelegate;
  import org.chromium.chrome.browser.settings.SettingsLauncherImpl;
  import org.chromium.chrome.browser.signin.services.IdentityServicesProvider;
@@ -351,7 +351,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
  import org.chromium.components.browser_ui.settings.ChromeSwitchPreference;
  import org.chromium.components.browser_ui.settings.ManagedPreferenceDelegate;
  import org.chromium.components.browser_ui.settings.SettingsLauncher;
-@@ -40,7 +44,12 @@ import org.chromium.ui.text.SpanApplier;
+@@ -43,7 +47,12 @@ import org.chromium.ui.text.SpanApplier;
   * Fragment to keep track of the all the privacy related preferences.
   */
  public class PrivacySettings
@@ -365,7 +365,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
      private static final String PREF_CAN_MAKE_PAYMENT = "can_make_payment";
      private static final String PREF_NETWORK_PREDICTIONS = "preload_pages";
      private static final String PREF_HTTPS_FIRST_MODE = "https_first_mode";
-@@ -83,6 +92,25 @@ public class PrivacySettings
+@@ -96,6 +105,25 @@ public class PrivacySettings
                  (ChromeSwitchPreference) findPreference(PREF_CAN_MAKE_PAYMENT);
          canMakePaymentPref.setOnPreferenceChangeListener(this);
  
@@ -391,7 +391,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
          ChromeSwitchPreference networkPredictionPref =
                  (ChromeSwitchPreference) findPreference(PREF_NETWORK_PREDICTIONS);
          networkPredictionPref.setChecked(
-@@ -114,6 +142,9 @@ public class PrivacySettings
+@@ -156,6 +184,9 @@ public class PrivacySettings
          } else if (PREF_NETWORK_PREDICTIONS.equals(key)) {
              PrivacyPreferencesManagerImpl.getInstance().setNetworkPredictionEnabled(
                      (boolean) newValue);
@@ -401,7 +401,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
          } else if (PREF_HTTPS_FIRST_MODE.equals(key)) {
              UserPrefs.get(Profile.getLastUsedRegularProfile())
                      .setBoolean(Pref.HTTPS_ONLY_MODE_ENABLED, (boolean) newValue);
-@@ -191,4 +222,8 @@ public class PrivacySettings
+@@ -238,4 +269,8 @@ public class PrivacySettings
          }
          return false;
      }
@@ -434,7 +434,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/Settin
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
-@@ -117,6 +117,8 @@ import org.chromium.ui.base.DeviceFormFactor;
+@@ -121,6 +121,8 @@ import org.chromium.ui.base.DeviceFormFactor;
  import org.chromium.ui.base.IntentRequestTracker;
  import org.chromium.ui.modaldialog.ModalDialogManager;
  import org.chromium.ui.util.TokenHolder;
@@ -443,7 +443,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/Tab
  
  /**
   * A {@link RootUiCoordinator} variant that controls tabbed-mode specific UI.
-@@ -479,11 +481,13 @@ public class TabbedRootUiCoordinator extends RootUiCoordinator {
+@@ -483,11 +485,13 @@ public class TabbedRootUiCoordinator extends RootUiCoordinator {
  
          // TODO(twellington): Supply TabModelSelector as well and move initialization earlier.
          if (DeviceFormFactor.isNonMultiDisplayContextOnTablet(mActivity)) {
@@ -537,7 +537,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPer
  import org.chromium.base.Log;
  import org.chromium.base.ObserverList;
  import org.chromium.base.StreamUtil;
-@@ -56,6 +57,8 @@ import org.chromium.content_public.browser.LoadUrlParams;
+@@ -55,6 +56,8 @@ import org.chromium.content_public.browser.LoadUrlParams;
  import org.chromium.content_public.browser.UiThreadTaskTraits;
  import org.chromium.url.GURL;
  
@@ -546,7 +546,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPer
  import java.io.BufferedInputStream;
  import java.io.ByteArrayInputStream;
  import java.io.ByteArrayOutputStream;
-@@ -654,6 +657,13 @@ public class TabPersistentStore {
+@@ -643,6 +646,13 @@ public class TabPersistentStore {
                  }
              }
          }
@@ -563,9 +563,9 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPer
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProvider.java
-@@ -28,6 +28,9 @@ import org.chromium.chrome.browser.browserservices.intents.WebappExtras;
- import org.chromium.chrome.browser.flags.ActivityType;
+@@ -29,6 +29,9 @@ import org.chromium.chrome.browser.flags.ActivityType;
  import org.chromium.components.browser_ui.widget.TintedDrawable;
+ import org.chromium.device.mojom.ScreenOrientationLockType;
  
 +import org.chromium.base.ContextUtils;
 +import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor;
@@ -573,7 +573,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappI
  /**
   * Stores info about a web app.
   */
-@@ -41,6 +44,8 @@ public class WebappIntentDataProvider extends BrowserServicesIntentDataProvider
+@@ -42,6 +45,8 @@ public class WebappIntentDataProvider extends BrowserServicesIntentDataProvider
      private final Intent mIntent;
      private final ColorProviderImpl mColorProvider;
  
@@ -582,7 +582,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappI
      /**
       * Returns the toolbar color to use if a custom color is not specified by the webapp.
       */
-@@ -62,6 +67,10 @@ public class WebappIntentDataProvider extends BrowserServicesIntentDataProvider
+@@ -63,6 +68,10 @@ public class WebappIntentDataProvider extends BrowserServicesIntentDataProvider
          mWebappExtras = webappExtras;
          mWebApkExtras = webApkExtras;
          mActivityType = (webApkExtras != null) ? ActivityType.WEB_APK : ActivityType.WEBAPP;
@@ -593,7 +593,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappI
      }
  
      @Override
-@@ -150,6 +159,11 @@ public class WebappIntentDataProvider extends BrowserServicesIntentDataProvider
+@@ -151,6 +160,11 @@ public class WebappIntentDataProvider extends BrowserServicesIntentDataProvider
          return mWebApkExtras;
      }
  
@@ -603,12 +603,12 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappI
 +    }
 +
      @Override
-     public int getDefaultOrientation() {
+     public @ScreenOrientationLockType.EnumType int getDefaultOrientation() {
          return mWebappExtras.orientation;
 diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
 --- a/chrome/browser/flags/android/chrome_feature_list.cc
 +++ b/chrome/browser/flags/android/chrome_feature_list.cc
-@@ -445,7 +445,7 @@ const base::Feature kCCTIncognito{"CCTIncognito",
+@@ -455,7 +455,7 @@ const base::Feature kCCTIncognito{"CCTIncognito",
                                    base::FEATURE_ENABLED_BY_DEFAULT};
  
  const base::Feature kCCTIncognitoAvailableToThirdParty{
@@ -620,7 +620,7 @@ diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browse
 diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
 +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
-@@ -922,6 +922,19 @@ Your Google account may have other forms of browsing history like searches and a
+@@ -930,6 +930,19 @@ Your Google account may have other forms of browsing history like searches and a
        <message name="IDS_CLEAR_BROWSING_HISTORY_SUMMARY_SYNCED_NO_LINK" desc="A text for the basic tab explaining browsing history for users with history sync. This version is shown when the link to MyActivity is displayed separately.">
          Clears history from all synced devices.
        </message>

+ 54 - 72
build/patches/Add-bookmark-import-export-actions.patch

@@ -14,15 +14,15 @@ Completely remove contacts picker permission from the file dialog
  .../browser/TabbedModeTabDelegateFactory.java |   5 +-
  .../browser/bookmarks/BookmarkActionBar.java  |  12 +
  .../browser/bookmarks/BookmarkActivity.java   |  30 ++
- .../browser/bookmarks/BookmarkBridge.java     | 278 +++++++++++++++++
+ .../browser/bookmarks/BookmarkBridge.java     | 277 +++++++++++++++++
  .../browser/bookmarks/BookmarkDelegate.java   |  10 +
  .../browser/bookmarks/BookmarkManager.java    |  22 ++
  .../browser/bookmarks/BookmarkPage.java       |   8 +-
  .../native_page/NativePageFactory.java        |  11 +-
- chrome/browser/BUILD.gn                       |  11 +-
+ chrome/browser/BUILD.gn                       |   7 +
  chrome/browser/about_flags.cc                 |   6 +
  .../android/bookmarks/bookmark_bridge.cc      | 284 ++++++++++++++++++
- .../android/bookmarks/bookmark_bridge.h       |  28 +-
+ .../android/bookmarks/bookmark_bridge.h       |  29 +-
  .../browser/bookmarks/bookmark_html_writer.cc |   8 +-
  .../dialogs/DownloadLocationCustomView.java   |   8 +-
  .../DownloadLocationDialogCoordinator.java    |   8 +-
@@ -44,7 +44,7 @@ Completely remove contacts picker permission from the file dialog
  ui/shell_dialogs/select_file_dialog.h         |   2 +
  .../select_file_dialog_android.cc             |   6 +
  ui/shell_dialogs/select_file_dialog_android.h |   2 +
- 38 files changed, 891 insertions(+), 29 deletions(-)
+ 38 files changed, 889 insertions(+), 27 deletions(-)
 
 diff --git a/base/android/content_uri_utils.cc b/base/android/content_uri_utils.cc
 --- a/base/android/content_uri_utils.cc
@@ -196,7 +196,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/TabbedModeTabDe
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkActionBar.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkActionBar.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkActionBar.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkActionBar.java
-@@ -84,6 +84,12 @@ public class BookmarkActionBar extends SelectableListToolbar<BookmarkId>
+@@ -85,6 +85,12 @@ public class BookmarkActionBar extends SelectableListToolbar<BookmarkId>
          } else if (menuItem.getItemId() == R.id.search_menu_id) {
              mDelegate.openSearchUI();
              return true;
@@ -209,7 +209,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm
          }
  
          SelectionDelegate<BookmarkId> selectionDelegate = mDelegate.getSelectionDelegate();
-@@ -135,6 +141,8 @@ public class BookmarkActionBar extends SelectableListToolbar<BookmarkId>
+@@ -136,6 +142,8 @@ public class BookmarkActionBar extends SelectableListToolbar<BookmarkId>
      void showLoadingUi() {
          setTitle(null);
          setNavigationButton(NAVIGATION_BUTTON_NONE);
@@ -218,7 +218,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm
          getMenu().findItem(R.id.search_menu_id).setVisible(false);
          getMenu().findItem(R.id.edit_menu_id).setVisible(false);
      }
-@@ -144,6 +152,8 @@ public class BookmarkActionBar extends SelectableListToolbar<BookmarkId>
+@@ -145,6 +153,8 @@ public class BookmarkActionBar extends SelectableListToolbar<BookmarkId>
          super.showNormalView();
  
          if (mDelegate == null) {
@@ -227,7 +227,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm
              getMenu().findItem(R.id.search_menu_id).setVisible(false);
              getMenu().findItem(R.id.edit_menu_id).setVisible(false);
          }
-@@ -174,6 +184,8 @@ public class BookmarkActionBar extends SelectableListToolbar<BookmarkId>
+@@ -175,6 +185,8 @@ public class BookmarkActionBar extends SelectableListToolbar<BookmarkId>
      public void onFolderStateSet(BookmarkId folder) {
          mCurrentFolder = mDelegate.getModel().getBookmarkById(folder);
  
@@ -330,7 +330,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm
  import android.text.TextUtils;
  import android.util.Pair;
  
-@@ -27,8 +40,33 @@ import org.chromium.components.url_formatter.UrlFormatter;
+@@ -30,8 +43,33 @@ import org.chromium.components.url_formatter.UrlFormatter;
  import org.chromium.content_public.browser.WebContents;
  import org.chromium.url.GURL;
  
@@ -364,7 +364,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm
  
  /**
   * Provides the communication channel for Android to fetch and manipulate the
-@@ -585,6 +623,210 @@ public class BookmarkBridge {
+@@ -588,6 +626,209 @@ public class BookmarkBridge {
                  mNativeBookmarkBridge, BookmarkBridge.this, id.getId(), id.getType());
      }
  
@@ -529,7 +529,6 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm
 +                                    .with(ModalDialogProperties.CUSTOM_VIEW, mCustomView)
 +                                    .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, resources,
 +                                            R.string.export_bookmarks)
-+                                    .with(ModalDialogProperties.PRIMARY_BUTTON_FILLED, true)
 +                                    .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, resources,
 +                                            R.string.cancel)
 +                                    .build();
@@ -569,13 +568,13 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm
 +        };
 +        dialog.initialize(controller);
 +        dialog.showDialog(context, modalDialogManager, /*totalBytes*/ 0,
-+            DownloadLocationDialogType.DEFAULT, /*suggestedPath*/ "");
++            DownloadLocationDialogType.DEFAULT, /*suggestedPath*/ "", /*isIncognito*/ false);
 +    }
 +
      /**
       * Synchronously gets a list of bookmarks that match the specified search query.
       * @param query Keyword used for searching bookmarks.
-@@ -1021,6 +1263,39 @@ public class BookmarkBridge {
+@@ -1100,6 +1341,39 @@ public class BookmarkBridge {
          depthList.add(depth);
      }
  
@@ -615,7 +614,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm
      private static List<Pair<Integer, Integer>> createPairsList(int[] left, int[] right) {
          List<Pair<Integer, Integer>> pairList = new ArrayList<Pair<Integer, Integer>>();
          for (int i = 0; i < left.length; i++) {
-@@ -1088,6 +1363,9 @@ public class BookmarkBridge {
+@@ -1167,6 +1441,9 @@ public class BookmarkBridge {
          int getChildCount(long nativeBookmarkBridge, BookmarkBridge caller, long id, int type);
          void getChildIDs(long nativeBookmarkBridge, BookmarkBridge caller, long id, int type,
                  List<BookmarkId> bookmarksList);
@@ -666,7 +665,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm
      private BookmarkUndoController mUndoController;
      private final ObserverList<BookmarkUIObserver> mUIObservers = new ObserverList<>();
      private BasicNativePage mNativePage;
-@@ -331,6 +335,14 @@ public class BookmarkManager
+@@ -341,6 +345,14 @@ public class BookmarkManager
          mNativePage = nativePage;
      }
  
@@ -681,7 +680,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm
      /**
       * @return Current URL representing the UI state of bookmark manager. If no state has been shown
       *         yet in this session, on phone return last used state stored in preference; on tablet
-@@ -509,6 +521,16 @@ public class BookmarkManager
+@@ -521,6 +533,16 @@ public class BookmarkManager
          }
      }
  
@@ -748,7 +747,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/native_page/Nat
      private final BottomSheetController mBottomSheetController;
      private final BrowserControlsManager mBrowserControlsManager;
      private final Supplier<Tab> mCurrentTabSupplier;
-@@ -72,7 +73,7 @@ public class NativePageFactory {
+@@ -71,7 +72,7 @@ public class NativePageFactory {
  
      private NativePageBuilder mNativePageBuilder;
  
@@ -757,7 +756,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/native_page/Nat
              @NonNull BottomSheetController sheetController,
              @NonNull BrowserControlsManager browserControlsManager,
              @NonNull Supplier<Tab> currentTabSupplier,
-@@ -123,7 +124,7 @@ public class NativePageFactory {
+@@ -119,7 +120,7 @@ public class NativePageFactory {
  
      @VisibleForTesting
      static class NativePageBuilder {
@@ -766,7 +765,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/native_page/Nat
          private final BottomSheetController mBottomSheetController;
          private final Supplier<NewTabPageUma> mUma;
          private final BrowserControlsManager mBrowserControlsManager;
-@@ -137,7 +138,7 @@ public class NativePageFactory {
+@@ -132,7 +133,7 @@ public class NativePageFactory {
          private final JankTracker mJankTracker;
          private final Supplier<Toolbar> mToolbarSupplier;
  
@@ -775,7 +774,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/native_page/Nat
                  BottomSheetController sheetController,
                  BrowserControlsManager browserControlsManager, Supplier<Tab> currentTabSupplier,
                  Supplier<SnackbarManager> snackbarManagerSupplier,
-@@ -176,7 +177,7 @@ public class NativePageFactory {
+@@ -169,7 +170,7 @@ public class NativePageFactory {
          protected NativePage buildBookmarksPage(Tab tab) {
              return new BookmarkPage(mActivity.getComponentName(), mSnackbarManagerSupplier.get(),
                      mTabModelSelector.isIncognitoSelected(),
@@ -787,7 +786,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/native_page/Nat
 diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
 --- a/chrome/browser/BUILD.gn
 +++ b/chrome/browser/BUILD.gn
-@@ -1832,6 +1832,13 @@ static_library("browser") {
+@@ -1843,6 +1843,13 @@ static_library("browser") {
      "window_placement/window_placement_permission_context.h",
    ]
  
@@ -801,30 +800,12 @@ diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
    configs += [
      "//build/config/compiler:wexit_time_destructors",
      "//build/config:precompiled_headers",
-@@ -2965,6 +2972,8 @@ static_library("browser") {
-       "autofill/manual_filling_view_interface.h",
-       "banners/android/chrome_app_banner_manager_android.cc",
-       "banners/android/chrome_app_banner_manager_android.h",
-+      "bookmarks/bookmark_html_writer.cc",
-+      "bookmarks/bookmark_html_writer.h",
-       "browser_process_platform_part_android.cc",
-       "browser_process_platform_part_android.h",
-       "chrome_browser_field_trials_mobile.cc",
-@@ -3541,8 +3550,6 @@ static_library("browser") {
-       "badging/badge_manager_factory.h",
-       "banners/app_banner_manager_desktop.cc",
-       "banners/app_banner_manager_desktop.h",
--      "bookmarks/bookmark_html_writer.cc",
--      "bookmarks/bookmark_html_writer.h",
-       "browsing_data/chrome_browsing_data_lifetime_manager.cc",
-       "browsing_data/chrome_browsing_data_lifetime_manager.h",
-       "browsing_data/chrome_browsing_data_lifetime_manager_factory.cc",
 diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 --- a/chrome/browser/about_flags.cc
 +++ b/chrome/browser/about_flags.cc
-@@ -7802,6 +7802,12 @@ const FeatureEntry kFeatureEntries[] = {
-      flag_descriptions::kCommerceDeveloperDescription, kOsAll,
-      FEATURE_VALUE_TYPE(commerce::kCommerceDeveloper)},
+@@ -7733,6 +7733,12 @@ const FeatureEntry kFeatureEntries[] = {
+      FEATURE_VALUE_TYPE(ui::kLibinputHandleTouchpad)},
+ #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
  
 +    {"export-bookmarks-use-saf",
 +     flag_descriptions::kBookmarksExportUseSafName,
@@ -838,7 +819,7 @@ diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browser/android/bookmarks/bookmark_bridge.cc
 --- a/chrome/browser/android/bookmarks/bookmark_bridge.cc
 +++ b/chrome/browser/android/bookmarks/bookmark_bridge.cc
-@@ -39,6 +39,7 @@
+@@ -43,6 +43,7 @@
  #include "components/bookmarks/common/android/bookmark_type.h"
  #include "components/bookmarks/common/bookmark_pref_names.h"
  #include "components/bookmarks/managed/managed_bookmark_service.h"
@@ -846,7 +827,7 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browse
  #include "components/dom_distiller/core/url_utils.h"
  #include "components/prefs/pref_service.h"
  #include "components/query_parser/query_parser.h"
-@@ -48,6 +49,24 @@
+@@ -52,6 +53,24 @@
  #include "content/public/browser/browser_thread.h"
  #include "content/public/browser/web_contents.h"
  
@@ -871,7 +852,7 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browse
  using base::android::AttachCurrentThread;
  using base::android::ConvertUTF8ToJavaString;
  using base::android::ConvertUTF16ToJavaString;
-@@ -64,8 +83,93 @@ using bookmarks::BookmarkNode;
+@@ -68,8 +87,93 @@ using bookmarks::BookmarkNode;
  using bookmarks::BookmarkType;
  using content::BrowserThread;
  
@@ -965,7 +946,7 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browse
  const int kInvalidId = -1;
  
  class BookmarkTitleComparer {
-@@ -152,6 +256,10 @@ BookmarkBridge::~BookmarkBridge() {
+@@ -156,6 +260,10 @@ BookmarkBridge::~BookmarkBridge() {
    if (partner_bookmarks_shim_)
      partner_bookmarks_shim_->RemoveObserver(this);
    reading_list_manager_->RemoveObserver(this);
@@ -976,7 +957,7 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browse
  }
  
  void BookmarkBridge::Destroy(JNIEnv*, const JavaParamRef<jobject>&) {
-@@ -543,6 +651,182 @@ jint BookmarkBridge::GetTotalBookmarkCount(
+@@ -547,6 +655,182 @@ jint BookmarkBridge::GetTotalBookmarkCount(
    return count;
  }
  
@@ -1190,7 +1171,7 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.h b/chrome/browser
   public:
    BookmarkBridge(JNIEnv* env,
                   const base::android::JavaRef<jobject>& obj,
-@@ -55,6 +60,12 @@ class BookmarkBridge : public bookmarks::BaseBookmarkModelObserver,
+@@ -59,6 +64,12 @@ class BookmarkBridge : public bookmarks::BaseBookmarkModelObserver,
    bool IsDoingExtensiveChanges(JNIEnv* env,
                                 const base::android::JavaParamRef<jobject>& obj);
  
@@ -1203,7 +1184,7 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.h b/chrome/browser
    jboolean IsEditBookmarksEnabled(JNIEnv* env);
  
    void LoadEmptyPartnerBookmarkShimForTesting(
-@@ -142,6 +153,15 @@ class BookmarkBridge : public bookmarks::BaseBookmarkModelObserver,
+@@ -146,6 +157,15 @@ class BookmarkBridge : public bookmarks::BaseBookmarkModelObserver,
                               jlong id,
                               jint type);
  
@@ -1219,7 +1200,7 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.h b/chrome/browser
    void SetBookmarkTitle(JNIEnv* env,
                          const base::android::JavaParamRef<jobject>& obj,
                          jlong id,
-@@ -315,12 +335,15 @@ class BookmarkBridge : public bookmarks::BaseBookmarkModelObserver,
+@@ -347,12 +367,15 @@ class BookmarkBridge : public bookmarks::BaseBookmarkModelObserver,
    void DestroyJavaObject();
  
    Profile* profile_;
@@ -1235,16 +1216,17 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.h b/chrome/browser
  
    // Information about the Partner bookmarks (must check for IsLoaded()).
    // This is owned by profile.
-@@ -332,6 +355,9 @@ class BookmarkBridge : public bookmarks::BaseBookmarkModelObserver,
+@@ -363,6 +386,10 @@ class BookmarkBridge : public bookmarks::BaseBookmarkModelObserver,
+ 
    // Observes the profile destruction and creation.
    base::ScopedObservation<Profile, ProfileObserver> profile_observation_{this};
- 
++
 +  const std::string FileSelectedImpl(const base::FilePath& path);
 +  void FileSelectedImplOnUIThread(const base::FilePath& path,
 +                                  const std::string& contents);
-   DISALLOW_COPY_AND_ASSIGN(BookmarkBridge);
  };
  
+ #endif  // CHROME_BROWSER_ANDROID_BOOKMARKS_BOOKMARK_BRIDGE_H_
 diff --git a/chrome/browser/bookmarks/bookmark_html_writer.cc b/chrome/browser/bookmarks/bookmark_html_writer.cc
 --- a/chrome/browser/bookmarks/bookmark_html_writer.cc
 +++ b/chrome/browser/bookmarks/bookmark_html_writer.cc
@@ -1256,7 +1238,7 @@ diff --git a/chrome/browser/bookmarks/bookmark_html_writer.cc b/chrome/browser/b
  #include "chrome/browser/bookmarks/bookmark_model_factory.h"
  #include "chrome/browser/favicon/favicon_service_factory.h"
  #include "chrome/browser/profiles/profile.h"
-@@ -230,7 +231,12 @@ class Writer : public base::RefCountedThreadSafe<Writer> {
+@@ -235,7 +236,12 @@ class Writer : public base::RefCountedThreadSafe<Writer> {
    // Opens the file, returning true on success.
    bool OpenFile() {
      int flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE;
@@ -1273,7 +1255,7 @@ diff --git a/chrome/browser/bookmarks/bookmark_html_writer.cc b/chrome/browser/b
 diff --git a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationCustomView.java b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationCustomView.java
 --- a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationCustomView.java
 +++ b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationCustomView.java
-@@ -46,7 +46,7 @@ public class DownloadLocationCustomView
+@@ -49,7 +49,7 @@ public class DownloadLocationCustomView
      private TextView mFileSize;
      private Spinner mFileLocation;
      private TextView mLocationAvailableSpace;
@@ -1282,7 +1264,7 @@ diff --git a/chrome/browser/download/android/java/src/org/chromium/chrome/browse
      private @DownloadLocationDialogType int mDialogType;
      private long mTotalBytes;
  
-@@ -68,7 +68,7 @@ public class DownloadLocationCustomView
+@@ -72,7 +72,7 @@ public class DownloadLocationCustomView
          mDontShowAgain = findViewById(R.id.show_again_checkbox);
      }
  
@@ -1291,7 +1273,7 @@ diff --git a/chrome/browser/download/android/java/src/org/chromium/chrome/browse
          // TODO(xingliu): Remove this function, currently used by smart suggestion.
          mDialogType = dialogType;
          mTotalBytes = totalBytes;
-@@ -117,7 +117,7 @@ public class DownloadLocationCustomView
+@@ -125,7 +125,7 @@ public class DownloadLocationCustomView
       * @return  The text that the user inputted as the name of the file.
       */
      @Nullable
@@ -1300,7 +1282,7 @@ diff --git a/chrome/browser/download/android/java/src/org/chromium/chrome/browse
          if (mFileName == null || mFileName.getText() == null) return null;
          return mFileName.getText().toString();
      }
-@@ -126,7 +126,7 @@ public class DownloadLocationCustomView
+@@ -134,7 +134,7 @@ public class DownloadLocationCustomView
       * @return  The file path based on what the user selected as the location of the file.
       */
      @Nullable
@@ -1312,7 +1294,7 @@ diff --git a/chrome/browser/download/android/java/src/org/chromium/chrome/browse
 diff --git a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationDialogCoordinator.java b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationDialogCoordinator.java
 --- a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationDialogCoordinator.java
 +++ b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationDialogCoordinator.java
-@@ -36,12 +36,12 @@ import java.util.ArrayList;
+@@ -37,12 +37,12 @@ import java.util.ArrayList;
  public class DownloadLocationDialogCoordinator implements ModalDialogProperties.Controller {
      @NonNull
      private DownloadLocationDialogController mController;
@@ -1328,7 +1310,7 @@ diff --git a/chrome/browser/download/android/java/src/org/chromium/chrome/browse
      private long mTotalBytes;
      private @DownloadLocationDialogType int mDialogType;
      private String mSuggestedPath;
-@@ -127,7 +127,7 @@ public class DownloadLocationDialogCoordinator implements ModalDialogProperties.
+@@ -131,7 +131,7 @@ public class DownloadLocationDialogCoordinator implements ModalDialogProperties.
       * Called after retrieved the download directory options.
       * @param dirs An list of available download directories.
       */
@@ -1340,7 +1322,7 @@ diff --git a/chrome/browser/download/android/java/src/org/chromium/chrome/browse
 diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
 --- a/chrome/browser/flag_descriptions.cc
 +++ b/chrome/browser/flag_descriptions.cc
-@@ -5415,6 +5415,11 @@ const char kWebKioskEnableLacrosDescription[] =
+@@ -5474,6 +5474,11 @@ const char kWebKioskEnableLacrosDescription[] =
      "Chrome OS. When disabled, the Ash-chrome will be used";
  #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
  
@@ -1355,7 +1337,7 @@ diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descripti
 diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
 --- a/chrome/browser/flag_descriptions.h
 +++ b/chrome/browser/flag_descriptions.h
-@@ -3162,6 +3162,9 @@ extern const char kWebKioskEnableLacrosName[];
+@@ -3185,6 +3185,9 @@ extern const char kWebKioskEnableLacrosName[];
  extern const char kWebKioskEnableLacrosDescription[];
  #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
  
@@ -1368,7 +1350,7 @@ diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptio
 diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
 --- a/chrome/browser/flags/android/chrome_feature_list.cc
 +++ b/chrome/browser/flags/android/chrome_feature_list.cc
-@@ -165,6 +165,7 @@ const base::Feature* const kFeaturesExposedToJava[] = {
+@@ -174,6 +174,7 @@ const base::Feature* const kFeaturesExposedToJava[] = {
      &kBackgroundThreadPool,
      &kBentoOffline,
      &kBookmarkBottomSheet,
@@ -1376,7 +1358,7 @@ diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browse
      &kCastDeviceFilter,
      &kCloseTabSuggestions,
      &kCriticalPersistedTabData,
-@@ -812,6 +813,10 @@ const base::Feature kWebApkInstallCompleteNotification{
+@@ -824,6 +825,10 @@ const base::Feature kWebApkInstallCompleteNotification{
  const base::Feature kWebApkTrampolineOnInitialIntent{
      "WebApkTrampolineOnInitialIntent", base::FEATURE_ENABLED_BY_DEFAULT};
  
@@ -1390,7 +1372,7 @@ diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browse
 diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h
 --- a/chrome/browser/flags/android/chrome_feature_list.h
 +++ b/chrome/browser/flags/android/chrome_feature_list.h
-@@ -146,6 +146,7 @@ extern const base::Feature kToolbarMicIphAndroid;
+@@ -149,6 +149,7 @@ extern const base::Feature kToolbarMicIphAndroid;
  extern const base::Feature kToolbarUseHardwareBitmapDraw;
  extern const base::Feature kTrustedWebActivityLocationDelegation;
  extern const base::Feature kTrustedWebActivityNewDisclosure;
@@ -1401,7 +1383,7 @@ diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser
 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
 --- 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
-@@ -546,6 +546,7 @@ public abstract class ChromeFeatureList {
+@@ -552,6 +552,7 @@ public abstract class ChromeFeatureList {
              "WebApkTrampolineOnInitialIntent";
      public static final String XSURFACE_METRICS_REPORTING = "XsurfaceMetricsReporting";
      public static final String WEB_OTP_CROSS_DEVICE_SIMPLE_STRING = "WebOtpCrossDeviceSimpleString";
@@ -1455,7 +1437,7 @@ diff --git a/chrome/browser/importer/profile_writer.h b/chrome/browser/importer/
  #include "components/favicon_base/favicon_usage_data.h"
  #include "components/history/core/browser/history_types.h"
  #include "components/search_engines/template_url_service.h"
-@@ -68,6 +69,11 @@ class ProfileWriter : public base::RefCountedThreadSafe<ProfileWriter> {
+@@ -71,6 +72,11 @@ class ProfileWriter : public base::RefCountedThreadSafe<ProfileWriter> {
    virtual void AddBookmarks(const std::vector<ImportedBookmarkEntry>& bookmarks,
                              const std::u16string& top_level_folder_name);
  
@@ -1470,7 +1452,7 @@ diff --git a/chrome/browser/importer/profile_writer.h b/chrome/browser/importer/
 diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
 --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
 +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
-@@ -124,6 +124,8 @@ public final class ChromePreferenceKeys {
+@@ -121,6 +121,8 @@ public final class ChromePreferenceKeys {
      public static final String BOOKMARKS_LAST_USED_URL = "enhanced_bookmark_last_used_url";
      public static final String BOOKMARKS_LAST_USED_PARENT =
              "enhanced_bookmark_last_used_parent_folder";
@@ -1479,7 +1461,7 @@ diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/bro
  
      /**
       * Whether Chrome is set as the default browser.
-@@ -1059,6 +1061,7 @@ public final class ChromePreferenceKeys {
+@@ -1042,6 +1044,7 @@ public final class ChromePreferenceKeys {
                  AUTOFILL_ASSISTANT_PROACTIVE_HELP,
                  APP_LAUNCH_LAST_KNOWN_ACTIVE_TAB_STATE,
                  APP_LAUNCH_SEARCH_ENGINE_HAD_LOGO,
@@ -1518,7 +1500,7 @@ diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chro
 diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn
 --- a/chrome/common/BUILD.gn
 +++ b/chrome/common/BUILD.gn
-@@ -412,6 +412,9 @@ static_library("common") {
+@@ -414,6 +414,9 @@ static_library("common") {
      sources += [
        "media/chrome_media_drm_bridge_client.cc",
        "media/chrome_media_drm_bridge_client.h",
@@ -1745,7 +1727,7 @@ diff --git a/ui/android/java/strings/android_ui_strings.grd b/ui/android/java/st
 diff --git a/ui/shell_dialogs/select_file_dialog.h b/ui/shell_dialogs/select_file_dialog.h
 --- a/ui/shell_dialogs/select_file_dialog.h
 +++ b/ui/shell_dialogs/select_file_dialog.h
-@@ -202,6 +202,8 @@ class SHELL_DIALOGS_EXPORT SelectFileDialog
+@@ -205,6 +205,8 @@ class SHELL_DIALOGS_EXPORT SelectFileDialog
                    void* params);
    bool HasMultipleFileTypeChoices();
  
@@ -1773,7 +1755,7 @@ diff --git a/ui/shell_dialogs/select_file_dialog_android.cc b/ui/shell_dialogs/s
 diff --git a/ui/shell_dialogs/select_file_dialog_android.h b/ui/shell_dialogs/select_file_dialog_android.h
 --- a/ui/shell_dialogs/select_file_dialog_android.h
 +++ b/ui/shell_dialogs/select_file_dialog_android.h
-@@ -55,6 +55,8 @@ class SelectFileDialogImpl : public SelectFileDialog {
+@@ -58,6 +58,8 @@ class SelectFileDialogImpl : public SelectFileDialog {
                        gfx::NativeWindow owning_window,
                        void* params) override;
  

+ 7 - 7
build/patches/Add-custom-tab-intents-privacy-option.patch

@@ -20,7 +20,7 @@ See also: https://github.com/bromite/bromite/issues/1474
 diff --git a/chrome/android/java/res/xml/privacy_preferences.xml b/chrome/android/java/res/xml/privacy_preferences.xml
 --- a/chrome/android/java/res/xml/privacy_preferences.xml
 +++ b/chrome/android/java/res/xml/privacy_preferences.xml
-@@ -60,6 +60,16 @@
+@@ -65,6 +65,16 @@
          android:fragment="org.chromium.chrome.browser.privacy.settings.DoNotTrackSettings"
          android:key="do_not_track"
          android:title="@string/do_not_track_title"/>
@@ -123,7 +123,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/Inco
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
-@@ -90,6 +90,9 @@ public class PrivacySettings
+@@ -94,6 +94,9 @@ public class PrivacySettings
  
      private ManagedPreferenceDelegate mManagedPreferenceDelegate;
  
@@ -133,8 +133,8 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
      @Override
      public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
          PrivacyPreferencesManagerImpl privacyPrefManager =
-@@ -190,6 +193,9 @@ public class PrivacySettings
-         updateSummaries();
+@@ -232,6 +235,9 @@ public class PrivacySettings
+         incognitoReauthPreference.setChecked(lastPrefValue);
      }
  
 +    public static final String PREF_ALLOW_CUSTOM_TAB_INTENTS = "allow_custom_tab_intents";
@@ -143,7 +143,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
      @Override
      public boolean onPreferenceChange(Preference preference, Object newValue) {
          String key = preference.getKey();
-@@ -221,6 +227,14 @@ public class PrivacySettings
+@@ -266,6 +272,14 @@ public class PrivacySettings
          } else if (PREF_INCOGNITO_TAB_HISTORY_ENABLED.equals(key)) {
              UserPrefs.get(Profile.getLastUsedRegularProfile())
                      .setBoolean(Pref.INCOGNITO_TAB_HISTORY_ENABLED, (boolean) newValue);
@@ -158,7 +158,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
          }
  
          return true;
-@@ -256,6 +270,16 @@ public class PrivacySettings
+@@ -301,6 +315,16 @@ public class PrivacySettings
              canMakePaymentPref.setChecked(prefService.getBoolean(Pref.CAN_MAKE_PAYMENT_ENABLED));
          }
  
@@ -194,7 +194,7 @@ diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabAsso
 diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
 +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
-@@ -4555,6 +4555,21 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
+@@ -4615,6 +4615,21 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
        <message name="IDS_NEAR_OOM_REDUCTION_DECLINE" desc="The text of the button letting the user decline the browser's intervention, so that the page can be reloaded.">
           Show original
        </message>

+ 9 - 9
build/patches/Add-exit-menu-item.patch

@@ -14,7 +14,7 @@ Corrected Exit functionality
 diff --git a/chrome/android/java/res/menu/main_menu.xml b/chrome/android/java/res/menu/main_menu.xml
 --- a/chrome/android/java/res/menu/main_menu.xml
 +++ b/chrome/android/java/res/menu/main_menu.xml
-@@ -124,6 +124,9 @@
+@@ -150,6 +150,9 @@
              android:icon="@drawable/gm_filled_cardboard_24" />
          <item android:id="@+id/managed_by_menu_id"
              android:title="@string/managed" />
@@ -24,7 +24,7 @@ diff --git a/chrome/android/java/res/menu/main_menu.xml b/chrome/android/java/re
      </group>
  
      <!-- Items shown only in the tab switcher -->
-@@ -150,6 +153,9 @@
+@@ -176,6 +179,9 @@
          <item android:id="@id/preferences_id"
              android:title="@string/menu_settings"
              android:icon="@drawable/settings_cog" />
@@ -33,7 +33,7 @@ diff --git a/chrome/android/java/res/menu/main_menu.xml b/chrome/android/java/re
 +            android:icon="@drawable/ic_exit_to_app_white_24dp" />
      </group>
  
-     <!-- Items shown only in the tab switcher when start surface is enabled -->
+     <!-- Items shown only when the tablet has no visible tabs -->
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -46,7 +46,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedAct
  /**
   * This is the main activity for ChromeMobile when not running in document mode.  All the tabs
   * are accessible via a chrome specific tab switching UI.
-@@ -2028,6 +2030,8 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
+@@ -2032,6 +2034,8 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
          } else if (id == R.id.close_tab) {
              getCurrentTabModel().closeTab(currentTab, true, false, true);
              RecordUserAction.record("MobileTabClosed");
@@ -58,7 +58,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedAct
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
-@@ -66,6 +66,7 @@ import org.chromium.chrome.R;
+@@ -65,6 +65,7 @@ import org.chromium.chrome.R;
  import org.chromium.chrome.browser.ActivityTabProvider;
  import org.chromium.chrome.browser.ActivityUtils;
  import org.chromium.chrome.browser.AppHooks;
@@ -66,7 +66,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActiv
  import org.chromium.chrome.browser.ChromeActivitySessionTracker;
  import org.chromium.chrome.browser.ChromeApplicationImpl;
  import org.chromium.chrome.browser.ChromeKeyboardVisibilityDelegate;
-@@ -2309,6 +2310,11 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
+@@ -2316,6 +2317,11 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
              return true;
          }
  
@@ -97,9 +97,9 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeLife
 diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
 +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
-@@ -3193,6 +3193,9 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
-       <message name="IDS_MENU_REQUEST_DESKTOP_SITE_OFF" desc="Accessibility description for when Request Desktop Site is disabled.">
-         Turn on Request desktop site
+@@ -3229,6 +3229,9 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
+       <message name="IDS_MENU_AUTO_DARK_WEB_CONTENTS" desc="Menu item in Chrome's overflow/options menu. When Chrome's browser UI is set to dark theme and this option is checked, sites will have a dark theme automatically applied as well. [CHAR_LIMIT=24]">
+         Dark theme
        </message>
 +      <message name="IDS_MENU_EXIT" desc="Menu item for exit browser. [CHAR-LIMIT=27]">
 +        Exit

+ 3 - 3
build/patches/Add-flag-for-omnibox-autocomplete-filtering.patch

@@ -15,7 +15,7 @@ and internal chrome:// pages will be used for the autocomplete results.
 diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 --- a/chrome/browser/about_flags.cc
 +++ b/chrome/browser/about_flags.cc
-@@ -456,6 +456,22 @@ const FeatureEntry::FeatureVariation kReaderModeDiscoverabilityVariations[] = {
+@@ -459,6 +459,22 @@ const FeatureEntry::FeatureVariation kReaderModeDiscoverabilityVariations[] = {
       base::size(kReaderModeOfferInSettings), nullptr}};
  #endif  // OS_ANDROID
  
@@ -38,7 +38,7 @@ diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
  #if defined(OS_ANDROID)
  const FeatureEntry::FeatureParam kAdaptiveButton_AlwaysNone[] = {
      {"mode", "always-none"}};
-@@ -4973,6 +4989,11 @@ const FeatureEntry kFeatureEntries[] = {
+@@ -4916,6 +4932,11 @@ const FeatureEntry kFeatureEntries[] = {
       FEATURE_VALUE_TYPE(chrome::android::kReaderModeInCCT)},
  #endif  // !defined(OS_ANDROID)
  
@@ -102,7 +102,7 @@ diff --git a/components/omnibox/browser/search_provider.cc b/components/omnibox/
  #include "base/feature_list.h"
  #include "base/i18n/break_iterator.h"
  #include "base/i18n/case_conversion.h"
-@@ -647,6 +648,9 @@ void SearchProvider::Run(bool query_is_private) {
+@@ -646,6 +647,9 @@ void SearchProvider::Run(bool query_is_private) {
  }
  
  void SearchProvider::DoHistoryQuery(bool minimal_changes) {

+ 4 - 4
build/patches/Add-flag-for-save-data-header.patch

@@ -14,7 +14,7 @@ Subject: Add flag for save-data-header
 diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 --- a/chrome/browser/about_flags.cc
 +++ b/chrome/browser/about_flags.cc
-@@ -4700,6 +4700,9 @@ const FeatureEntry kFeatureEntries[] = {
+@@ -4655,6 +4655,9 @@ const FeatureEntry kFeatureEntries[] = {
  #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
  
  #if defined(OS_ANDROID)
@@ -27,7 +27,7 @@ diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
 --- a/chrome/browser/flag_descriptions.cc
 +++ b/chrome/browser/flag_descriptions.cc
-@@ -1058,6 +1058,10 @@ const char kDisableKeepaliveFetchDescription[] =
+@@ -1111,6 +1111,10 @@ const char kDisableKeepaliveFetchDescription[] =
      "Disable fetch with keepalive set "
      "(https://fetch.spec.whatwg.org/#request-keepalive-flag).";
  
@@ -41,7 +41,7 @@ diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descripti
 diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
 --- a/chrome/browser/flag_descriptions.h
 +++ b/chrome/browser/flag_descriptions.h
-@@ -583,6 +583,9 @@ extern const char kDiagnosticsAppNavigationDescription[];
+@@ -605,6 +605,9 @@ extern const char kDiagnosticsAppNavigationDescription[];
  extern const char kDisableKeepaliveFetchName[];
  extern const char kDisableKeepaliveFetchDescription[];
  
@@ -70,7 +70,7 @@ diff --git a/content/browser/loader/browser_initiated_resource_request.cc b/cont
 diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc
 --- a/services/network/public/cpp/features.cc
 +++ b/services/network/public/cpp/features.cc
-@@ -140,6 +140,10 @@ const base::FeatureParam<std::string>
+@@ -141,6 +141,10 @@ const base::FeatureParam<std::string>
                                                 "DisabledProviders", ""};
  
  // Disable special treatment on requests with keepalive set (see

+ 4 - 4
build/patches/Add-flag-to-configure-maximum-connections-per-host.patch

@@ -19,7 +19,7 @@ with limited CPU/memory resources and it is disabled by default.
 diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 --- a/chrome/browser/about_flags.cc
 +++ b/chrome/browser/about_flags.cc
-@@ -868,6 +868,11 @@ const FeatureEntry::Choice kForceEffectiveConnectionTypeChoices[] = {
+@@ -849,6 +849,11 @@ const FeatureEntry::Choice kForceEffectiveConnectionTypeChoices[] = {
       net::kEffectiveConnectionType4G},
  };
  
@@ -31,7 +31,7 @@ diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
  // Ensure that all effective connection types returned by Network Quality
  // Estimator (NQE) are also exposed via flags.
  static_assert(net::EFFECTIVE_CONNECTION_TYPE_LAST + 2 ==
-@@ -3974,6 +3979,9 @@ const FeatureEntry kFeatureEntries[] = {
+@@ -3918,6 +3923,9 @@ const FeatureEntry kFeatureEntries[] = {
       flag_descriptions::kAndroidPictureInPictureAPIName,
       flag_descriptions::kAndroidPictureInPictureAPIDescription, kOsAndroid,
       FEATURE_VALUE_TYPE(media::kPictureInPictureAPI)},
@@ -44,7 +44,7 @@ diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
 --- a/chrome/browser/flag_descriptions.cc
 +++ b/chrome/browser/flag_descriptions.cc
-@@ -1572,6 +1572,10 @@ const char kMediaHistoryDescription[] =
+@@ -1626,6 +1626,10 @@ const char kMediaHistoryDescription[] =
      "Enables Media History which records data around media playbacks on "
      "websites.";
  
@@ -58,7 +58,7 @@ diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descripti
 diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
 --- a/chrome/browser/flag_descriptions.h
 +++ b/chrome/browser/flag_descriptions.h
-@@ -905,6 +905,9 @@ extern const char kLogJsConsoleMessagesDescription[];
+@@ -933,6 +933,9 @@ extern const char kLogJsConsoleMessagesDescription[];
  extern const char kMediaHistoryName[];
  extern const char kMediaHistoryDescription[];
  

+ 5 - 5
build/patches/Add-flag-to-control-video-playback-resume-feature.patch

@@ -13,7 +13,7 @@ Disable it by default on Android as it is everywhere else
 diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 --- a/chrome/browser/about_flags.cc
 +++ b/chrome/browser/about_flags.cc
-@@ -2837,6 +2837,10 @@ const FeatureEntry kFeatureEntries[] = {
+@@ -2801,6 +2801,10 @@ const FeatureEntry kFeatureEntries[] = {
       flag_descriptions::kWebRtcRemoteEventLogName,
       flag_descriptions::kWebRtcRemoteEventLogDescription, kOsDesktop,
       FEATURE_VALUE_TYPE(features::kWebRtcRemoteEventLog)},
@@ -27,7 +27,7 @@ diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
 --- a/chrome/browser/flag_descriptions.cc
 +++ b/chrome/browser/flag_descriptions.cc
-@@ -1143,6 +1143,11 @@ const char kEnablePenetratingImageSelectionDescription[] =
+@@ -1196,6 +1196,11 @@ const char kEnablePenetratingImageSelectionDescription[] =
      "Enables image options to be surfaced in the context menu for nodes "
      "covered by transparent overlays.";
  
@@ -42,7 +42,7 @@ diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descripti
 diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
 --- a/chrome/browser/flag_descriptions.h
 +++ b/chrome/browser/flag_descriptions.h
-@@ -648,6 +648,9 @@ extern const char kEnablePortalsDescription[];
+@@ -673,6 +673,9 @@ extern const char kEnablePortalsDescription[];
  extern const char kEnablePortalsCrossOriginName[];
  extern const char kEnablePortalsCrossOriginDescription[];
  
@@ -55,7 +55,7 @@ diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptio
 diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
 --- a/media/base/media_switches.cc
 +++ b/media/base/media_switches.cc
-@@ -276,11 +276,7 @@ const base::Feature kPreloadMetadataLazyLoad{"PreloadMetadataLazyLoad",
+@@ -282,11 +282,7 @@ const base::Feature kPreloadMetadataLazyLoad{"PreloadMetadataLazyLoad",
  // when in background.
  const base::Feature kResumeBackgroundVideo {
    "resume-background-video",
@@ -67,7 +67,7 @@ diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
 +   base::FEATURE_DISABLED_BY_DEFAULT
  };
  
- // When enabled, MediaCapabilities will check with GPU Video Accelerator
+ // Experimental: Try to avoid destroying the media player when transferring a
 -- 
 2.20.1
 

+ 6 - 6
build/patches/Add-flag-to-disable-IPv6-probes.patch

@@ -16,7 +16,7 @@ Subject: Add flag to disable IPv6 probes
 diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 --- a/chrome/browser/about_flags.cc
 +++ b/chrome/browser/about_flags.cc
-@@ -4949,6 +4949,11 @@ const FeatureEntry kFeatureEntries[] = {
+@@ -4892,6 +4892,11 @@ const FeatureEntry kFeatureEntries[] = {
  #endif  // defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) ||
          // defined(OS_CHROMEOS)
  
@@ -31,7 +31,7 @@ diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
 --- a/chrome/browser/flag_descriptions.cc
 +++ b/chrome/browser/flag_descriptions.cc
-@@ -3070,6 +3070,10 @@ const char kContextualSearchRankerQueryDescription[] =
+@@ -3124,6 +3124,10 @@ const char kContextualSearchRankerQueryDescription[] =
  
  const char kContextualSearchSecondTapName[] =
      "Contextual Search second tap triggering";
@@ -45,7 +45,7 @@ diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descripti
 diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
 --- a/chrome/browser/flag_descriptions.h
 +++ b/chrome/browser/flag_descriptions.h
-@@ -711,6 +711,9 @@ extern const char kEnableWasmLazyCompilationName[];
+@@ -736,6 +736,9 @@ extern const char kEnableWasmLazyCompilationName[];
  extern const char kEnableWasmLazyCompilationDescription[];
  
  extern const char kEnableWasmTieringName[];
@@ -101,7 +101,7 @@ diff --git a/components/url_formatter/spoof_checks/top_domains/BUILD.gn b/compon
 diff --git a/net/dns/host_resolver_manager.cc b/net/dns/host_resolver_manager.cc
 --- a/net/dns/host_resolver_manager.cc
 +++ b/net/dns/host_resolver_manager.cc
-@@ -88,6 +88,7 @@
+@@ -89,6 +89,7 @@
  #include "net/log/net_log_event_type.h"
  #include "net/log/net_log_source.h"
  #include "net/log/net_log_source_type.h"
@@ -109,7 +109,7 @@ diff --git a/net/dns/host_resolver_manager.cc b/net/dns/host_resolver_manager.cc
  #include "net/log/net_log_with_source.h"
  #include "net/socket/client_socket_factory.h"
  #include "net/socket/datagram_client_socket.h"
-@@ -3692,8 +3693,14 @@ bool HostResolverManager::IsIPv6Reachable(const NetLogWithSource& net_log) {
+@@ -3695,8 +3696,14 @@ bool HostResolverManager::IsIPv6Reachable(const NetLogWithSource& net_log) {
    if (last_ipv6_probe_time_.is_null() ||
        (tick_clock_->NowTicks() - last_ipv6_probe_time_).InMilliseconds() >
            kIPv6ProbePeriodMs) {
@@ -128,7 +128,7 @@ diff --git a/net/dns/host_resolver_manager.cc b/net/dns/host_resolver_manager.cc
 diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc
 --- a/services/network/public/cpp/features.cc
 +++ b/services/network/public/cpp/features.cc
-@@ -42,6 +42,10 @@ const base::Feature kReporting{"Reporting", base::FEATURE_ENABLED_BY_DEFAULT};
+@@ -43,6 +43,10 @@ const base::Feature kReporting{"Reporting", base::FEATURE_ENABLED_BY_DEFAULT};
  const base::Feature kThrottleDelayable{"ThrottleDelayable",
                                         base::FEATURE_ENABLED_BY_DEFAULT};
  

+ 3 - 3
build/patches/Add-flag-to-disable-WebGL.patch

@@ -11,7 +11,7 @@ Subject: Add flag to disable WebGL
 diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 --- a/chrome/browser/about_flags.cc
 +++ b/chrome/browser/about_flags.cc
-@@ -2772,6 +2772,9 @@ const FeatureEntry::Choice kDocumentTransitionSlowdownFactorChoices[] = {
+@@ -2736,6 +2736,9 @@ const FeatureEntry::FeatureVariation kWin11StyleMenusVariations[] = {
  // When adding a new choice, add it to the end of the list.
  const FeatureEntry kFeatureEntries[] = {
  // Include generated flags for flag unexpiry; see //docs/flag_expiry.md and
@@ -24,7 +24,7 @@ diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
 --- a/chrome/browser/flag_descriptions.cc
 +++ b/chrome/browser/flag_descriptions.cc
-@@ -636,6 +636,10 @@ const char kEnableAudioFocusEnforcementName[] = "Audio Focus Enforcement";
+@@ -690,6 +690,10 @@ const char kEnableAudioFocusEnforcementName[] = "Audio Focus Enforcement";
  const char kEnableAudioFocusEnforcementDescription[] =
      "Enables enforcement of a single media session having audio focus at "
      "any one time. Requires #enable-media-session-service to be enabled too.";
@@ -38,7 +38,7 @@ diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descripti
 diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
 --- a/chrome/browser/flag_descriptions.h
 +++ b/chrome/browser/flag_descriptions.h
-@@ -354,6 +354,9 @@ extern const char kForceColorProfileSRGB[];
+@@ -380,6 +380,9 @@ extern const char kForceColorProfileSRGB[];
  extern const char kForceColorProfileP3[];
  extern const char kForceColorProfileColorSpin[];
  extern const char kForceColorProfileSCRGBLinear[];

+ 5 - 5
build/patches/Add-flag-to-disable-external-intent-requests.patch

@@ -11,7 +11,7 @@ Subject: Add flag to disable external intent requests
 diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 --- a/chrome/browser/about_flags.cc
 +++ b/chrome/browser/about_flags.cc
-@@ -2826,6 +2826,9 @@ const FeatureEntry kFeatureEntries[] = {
+@@ -2790,6 +2790,9 @@ const FeatureEntry kFeatureEntries[] = {
       flag_descriptions::kWebrtcCaptureMultiChannelApmName,
       flag_descriptions::kWebrtcCaptureMultiChannelApmDescription, kOsAll,
       FEATURE_VALUE_TYPE(features::kWebRtcEnableCaptureMultiChannelApm)},
@@ -24,9 +24,9 @@ diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
 --- a/chrome/browser/flag_descriptions.cc
 +++ b/chrome/browser/flag_descriptions.cc
-@@ -3344,6 +3344,12 @@ const char kProcessSharingWithStrictSiteInstancesDescription[] =
-     "separated like strict site isolation, but process selection puts multiple "
-     "site instances in a single process.";
+@@ -3378,6 +3378,12 @@ const char kPhotoPickerVideoSupportName[] = "Photo Picker Video Support";
+ const char kPhotoPickerVideoSupportDescription[] =
+     "Enables video files to be shown in the Photo Picker dialog";
  
 +const char kDisableExternalIntentRequestsName[] =
 +    "Never forward URL requests to external intents";
@@ -40,7 +40,7 @@ diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descripti
 diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
 --- a/chrome/browser/flag_descriptions.h
 +++ b/chrome/browser/flag_descriptions.h
-@@ -1930,6 +1930,9 @@ extern const char kQueryTilesNTPDescription[];
+@@ -1948,6 +1948,9 @@ extern const char kQueryTilesNTPDescription[];
  extern const char kQueryTilesOmniboxName[];
  extern const char kQueryTilesOmniboxDescription[];
  extern const char kQueryTilesSingleTierName[];

+ 13 - 13
build/patches/Add-flag-to-disable-vibration.patch

@@ -18,7 +18,7 @@ Subject: Add flag to disable vibration
 diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 --- a/chrome/browser/about_flags.cc
 +++ b/chrome/browser/about_flags.cc
-@@ -6412,6 +6412,10 @@ const FeatureEntry kFeatureEntries[] = {
+@@ -6357,6 +6357,10 @@ const FeatureEntry kFeatureEntries[] = {
       FEATURE_VALUE_TYPE(features::kNewMacNotificationAPI)},
  #endif
  
@@ -32,8 +32,8 @@ diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
 --- a/chrome/browser/flag_descriptions.cc
 +++ b/chrome/browser/flag_descriptions.cc
-@@ -5242,6 +5242,9 @@ const char kDefaultMeetWebAppDescription[] =
-     "Enables the Meet web app to be installed by default.";
+@@ -5283,6 +5283,9 @@ const char kDefaultCalculatorWebAppDescription[] =
+     "chrome app.";
  #endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
  
 +const char kEnableVibrationName[] = "Vibration";
@@ -45,8 +45,8 @@ diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descripti
 diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
 --- a/chrome/browser/flag_descriptions.h
 +++ b/chrome/browser/flag_descriptions.h
-@@ -3044,6 +3044,9 @@ extern const char kDefaultMeetWebAppName[];
- extern const char kDefaultMeetWebAppDescription[];
+@@ -3054,6 +3054,9 @@ extern const char kDefaultCalculatorWebAppName[];
+ extern const char kDefaultCalculatorWebAppDescription[];
  #endif  // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
  
 +extern const char kEnableVibrationName[];
@@ -69,20 +69,20 @@ diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.
 diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
 --- a/content/public/common/content_features.cc
 +++ b/content/public/common/content_features.cc
-@@ -103,6 +103,9 @@ const base::Feature kBackForwardCacheSameSiteForBots{
+@@ -103,6 +103,9 @@ const base::Feature kBackForwardCacheMemoryControls {
+ };
  
- // BackForwardCacheMemoryControls is enabled only on Android to disable
- // BackForwardCache for lower memory devices due to memory limiations.
+ // Block subresource requests whose URLs contain embedded credentials (e.g.
 +// Enables vibration; an user gesture will still be required if enabled.
 +const base::Feature kVibration{"Vibration",
 +                                    base::FEATURE_DISABLED_BY_DEFAULT};
- const base::Feature kBackForwardCacheMemoryControls{
-   "BackForwardCacheMemoryControls",
- 
+ // `https://user:pass@example.com/resource`).
+ const base::Feature kBlockCredentialedSubresources{
+     "BlockCredentialedSubresources", base::FEATURE_ENABLED_BY_DEFAULT};
 diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
 --- a/content/public/common/content_features.h
 +++ b/content/public/common/content_features.h
-@@ -273,6 +273,8 @@ CONTENT_EXPORT extern const base::Feature kWarmUpNetworkProcess;
+@@ -274,6 +274,8 @@ CONTENT_EXPORT extern const base::Feature kWarmUpNetworkProcess;
  CONTENT_EXPORT extern const base::Feature kWebNfc;
  #endif  // defined(OS_ANDROID)
  
@@ -139,7 +139,7 @@ diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.c
 diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
-@@ -1575,6 +1575,10 @@
+@@ -1577,6 +1577,10 @@
        name: "OrientationEvent",
        status: {"Android": "stable"},
      },

+ 54 - 53
build/patches/Add-history-support-in-incognito-mode.patch

@@ -17,7 +17,7 @@ See also: https://github.com/bromite/bromite/pull/1427
  .../CustomTabAppMenuPropertiesDelegate.java   |   3 +
  .../browser/download/DownloadUtils.java       |  16 +-
  .../browser/history/HistoryManager.java       |  17 +-
- .../chrome/browser/history/HistoryPage.java   |  14 +
+ .../chrome/browser/history/HistoryPage.java   |  15 +
  .../chrome/browser/ntp/RecentTabsManager.java |   8 +-
  .../privacy/settings/PrivacySettings.java     |  18 +
  .../browser/tab/HistoricalTabSaver.java       |  12 +-
@@ -35,9 +35,9 @@ See also: https://github.com/bromite/bromite/pull/1427
  .../android/offline_page_bridge.cc            |  13 +-
  .../android/offline_page_model_factory.cc     |  21 +-
  .../android/request_coordinator_factory.cc    |  17 +
- .../offline_page_model_factory.h              |   2 +
+ .../offline_page_model_factory.h              |   1 +
  .../offline_pages/recent_tab_helper.cc        |  12 +
- .../request_coordinator_factory.h             |   3 +
+ .../request_coordinator_factory.h             |   2 +
  chrome/browser/prefs/browser_prefs.cc         |   3 +
  .../browser/ui/android/native_page/BUILD.gn   |   2 +
  .../browser/ui/native_page/NativePage.java    |   6 +-
@@ -46,7 +46,7 @@ See also: https://github.com/bromite/bromite/pull/1427
  chrome/common/pref_names.cc                   |   5 +
  chrome/common/pref_names.h                    |   4 +
  chrome/test/BUILD.gn                          |   5 +
- 36 files changed, 1046 insertions(+), 38 deletions(-)
+ 36 files changed, 1045 insertions(+), 38 deletions(-)
  create mode 100644 chrome/android/javatests/src/org/chromium/chrome/browser/history/Bromite_HistoryManagerTest.java
  create mode 100644 chrome/android/javatests/src/org/chromium/chrome/browser/privacy/settings/Bromite_PrivacySettingsFragmentTest_HistoryInAlwaysIncognito.java
  create mode 100644 chrome/android/junit/src/org/chromium/chrome/browser/app/appmenu/Bromite_AppMenuPropertiesDelegateUnitTest.java
@@ -56,7 +56,7 @@ See also: https://github.com/bromite/bromite/pull/1427
 diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni
 --- a/chrome/android/chrome_junit_test_java_sources.gni
 +++ b/chrome/android/chrome_junit_test_java_sources.gni
-@@ -225,3 +225,7 @@ chrome_junit_test_java_sources = [
+@@ -226,3 +226,7 @@ chrome_junit_test_java_sources = [
    "junit/src/org/chromium/chrome/browser/webapps/WebappLauncherActivityTest.java",
    "junit/src/org/chromium/chrome/browser/webapps/WebappRegistryTest.java",
  ]
@@ -68,7 +68,7 @@ diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/
 diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni
 --- a/chrome/android/chrome_test_java_sources.gni
 +++ b/chrome/android/chrome_test_java_sources.gni
-@@ -649,3 +649,9 @@ chrome_test_java_sources = [
+@@ -653,3 +653,9 @@ chrome_test_java_sources = [
  if (enable_feed_v2) {
    chrome_test_java_sources += [ "javatests/src/org/chromium/chrome/browser/ntp/NewTabPageColorWithFeedV2Test.java" ]
  }
@@ -81,7 +81,7 @@ diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome
 diff --git a/chrome/android/java/res/xml/privacy_preferences.xml b/chrome/android/java/res/xml/privacy_preferences.xml
 --- a/chrome/android/java/res/xml/privacy_preferences.xml
 +++ b/chrome/android/java/res/xml/privacy_preferences.xml
-@@ -46,6 +46,11 @@
+@@ -51,6 +51,11 @@
          android:title="@string/close_tabs_on_exit_title"
          android:summary="@string/close_tabs_on_exit_summary"
          android:defaultValue="false" />
@@ -96,9 +96,9 @@ diff --git a/chrome/android/java/res/xml/privacy_preferences.xml b/chrome/androi
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
-@@ -75,6 +75,10 @@ import java.lang.annotation.RetentionPolicy;
- import java.util.ArrayList;
+@@ -92,6 +92,10 @@ import java.util.ArrayList;
  import java.util.List;
+ import java.util.Map;
  
 +import org.chromium.components.prefs.PrefService;
 +import org.chromium.components.user_prefs.UserPrefs;
@@ -107,7 +107,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/App
  /**
   * Base implementation of {@link AppMenuPropertiesDelegate} that handles hiding and showing menu
   * items based on activity state.
-@@ -133,6 +137,13 @@ public class AppMenuPropertiesDelegateImpl implements AppMenuPropertiesDelegate
+@@ -153,6 +157,13 @@ public class AppMenuPropertiesDelegateImpl implements AppMenuPropertiesDelegate
      protected BookmarkBridge mBookmarkBridge;
      protected Runnable mAppMenuInvalidator;
  
@@ -121,7 +121,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/App
      /**
       * Construct a new {@link AppMenuPropertiesDelegateImpl}.
       * @param context The activity context.
-@@ -379,7 +390,8 @@ public class AppMenuPropertiesDelegateImpl implements AppMenuPropertiesDelegate
+@@ -539,7 +550,8 @@ public class AppMenuPropertiesDelegateImpl implements AppMenuPropertiesDelegate
      }
  
      private void prepareCommonMenuItems(Menu menu, @MenuGroup int menuGroup, boolean isIncognito) {
@@ -131,7 +131,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/App
              final MenuItem newTabOption = menu.findItem(R.id.new_tab_menu_id);
              if (newTabOption != null)
                  newTabOption.setVisible(false);
-@@ -444,7 +456,15 @@ public class AppMenuPropertiesDelegateImpl implements AppMenuPropertiesDelegate
+@@ -601,7 +613,15 @@ public class AppMenuPropertiesDelegateImpl implements AppMenuPropertiesDelegate
              }
  
              if (item.getItemId() == R.id.recent_tabs_menu_id) {
@@ -148,7 +148,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/App
              }
              if (item.getItemId() == R.id.menu_group_tabs) {
                  item.setVisible(isMenuGroupTabsVisible);
-@@ -632,7 +652,10 @@ public class AppMenuPropertiesDelegateImpl implements AppMenuPropertiesDelegate
+@@ -811,7 +831,10 @@ public class AppMenuPropertiesDelegateImpl implements AppMenuPropertiesDelegate
          //                is not persisted when adding to the homescreen.
          // * If creating shortcuts it not supported by the current home screen.
          return WebappsUtils.isAddToHomeIntentSupported() && !isChromeScheme && !isFileScheme
@@ -163,7 +163,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/App
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java
-@@ -169,6 +169,9 @@ public class CustomTabAppMenuPropertiesDelegate extends AppMenuPropertiesDelegat
+@@ -170,6 +170,9 @@ public class CustomTabAppMenuPropertiesDelegate extends AppMenuPropertiesDelegat
                  downloadItemVisible = false;
                  openInChromeItemVisible = false;
              }
@@ -209,7 +209,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/Downlo
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
-@@ -42,6 +42,12 @@ import org.chromium.ui.base.Clipboard;
+@@ -41,6 +41,12 @@ import org.chromium.ui.base.Clipboard;
  
  import java.util.List;
  
@@ -222,7 +222,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/History
  /**
   * Combines and manages the different UI components of browsing history.
   */
-@@ -216,7 +222,16 @@ public class HistoryManager implements OnMenuItemClickListener, SelectionObserve
+@@ -213,7 +219,16 @@ public class HistoryManager implements OnMenuItemClickListener, SelectionObserve
                                                  : mSelectableListLayout;
      }
  
@@ -243,7 +243,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/History
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryPage.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryPage.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryPage.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryPage.java
-@@ -17,6 +17,12 @@ import org.chromium.chrome.browser.ui.native_page.BasicNativePage;
+@@ -16,6 +16,12 @@ import org.chromium.chrome.browser.ui.native_page.BasicNativePage;
  import org.chromium.chrome.browser.ui.native_page.NativePageHost;
  import org.chromium.components.embedder_support.util.UrlConstants;
  
@@ -256,8 +256,8 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/History
  /**
   * Native page for managing browsing history.
   */
-@@ -40,6 +46,14 @@ public class HistoryPage extends BasicNativePage {
-             boolean isIncognito, TabCreatorManager tabCreatorManager, Supplier<Tab> tabSupplier) {
+@@ -37,8 +43,17 @@ public class HistoryPage extends BasicNativePage {
+             boolean isIncognito, Supplier<Tab> tabSupplier) {
          super(host);
  
 +        if (isIncognito &&
@@ -268,13 +268,16 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/History
 +            if (historyEnabledInIncognito == true) isIncognito = false;
 +        }
 +
-         mHistoryManager = new HistoryManager(
-                 activity, false, snackbarManager, isIncognito, tabCreatorManager, tabSupplier);
+         mHistoryManager =
+                 new HistoryManager(activity, false, snackbarManager, isIncognito, tabSupplier);
++
          mTitle = host.getContext().getResources().getString(R.string.menu_history);
+ 
+         initWithView(mHistoryManager.getView());
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsManager.java
-@@ -86,15 +86,15 @@ public class RecentTabsManager implements SignInStateObserver,
+@@ -87,15 +87,15 @@ public class RecentTabsManager implements SignInStateObserver,
       */
      public RecentTabsManager(
              Tab tab, Profile profile, Context context, Runnable showHistoryManager) {
@@ -305,7 +308,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
  import org.chromium.chrome.R;
  import org.chromium.chrome.browser.feedback.HelpAndFeedbackLauncherImpl;
  import org.chromium.chrome.browser.flags.ChromeFeatureList;
-@@ -136,6 +137,11 @@ public class PrivacySettings
+@@ -149,6 +150,11 @@ public class PrivacySettings
          Preference secureDnsPref = findPreference(PREF_SECURE_DNS);
          secureDnsPref.setVisible(SecureDnsSettings.isUiEnabled());
  
@@ -314,13 +317,13 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
 +        historyInIncognitoPref.setOnPreferenceChangeListener(this);
 +        historyInIncognitoPref.setManagedPreferenceDelegate(mManagedPreferenceDelegate);
 +
-         updateSummaries();
+         updatePreferences();
      }
  
-@@ -158,11 +164,16 @@ public class PrivacySettings
-         } else if (PREF_HTTPS_FIRST_MODE.equals(key)) {
+@@ -203,11 +209,16 @@ public class PrivacySettings
+         } else if (PREF_INCOGNITO_LOCK.equals(key)) {
              UserPrefs.get(Profile.getLastUsedRegularProfile())
-                     .setBoolean(Pref.HTTPS_ONLY_MODE_ENABLED, (boolean) newValue);
+                     .setBoolean(Pref.INCOGNITO_REAUTHENTICATION_FOR_ANDROID, (boolean) newValue);
 +        } else if (PREF_INCOGNITO_TAB_HISTORY_ENABLED.equals(key)) {
 +            UserPrefs.get(Profile.getLastUsedRegularProfile())
 +                    .setBoolean(Pref.INCOGNITO_TAB_HISTORY_ENABLED, (boolean) newValue);
@@ -334,20 +337,20 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
      @Override
      public void onResume() {
          super.onResume();
-@@ -203,6 +214,13 @@ public class PrivacySettings
-                 (ChromeSwitchPreference) findPreference(PREF_CLOSE_TABS_ON_EXIT);
+@@ -249,6 +260,13 @@ public class PrivacySettings
          closeTabsOnExitPref.setOnPreferenceChangeListener(this);
          closeTabsOnExitPref.setManagedPreferenceDelegate(mManagedPreferenceDelegate);
-+
+ 
 +        ChromeSwitchPreference historyInIncognitoPref =
 +                (ChromeSwitchPreference) findPreference(PREF_INCOGNITO_TAB_HISTORY_ENABLED);
 +        if (historyInIncognitoPref != null) {
 +            historyInIncognitoPref.setChecked(
 +                    prefService.getBoolean(Pref.INCOGNITO_TAB_HISTORY_ENABLED));
 +        }
++
+         updateIncognitoReauthPreference();
      }
  
-     private ChromeManagedPreferenceDelegate createManagedPreferenceDelegate() {
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/HistoricalTabSaver.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/HistoricalTabSaver.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/HistoricalTabSaver.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/HistoricalTabSaver.java
@@ -389,7 +392,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/HistoricalT
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
-@@ -153,7 +153,10 @@ public class TabPersistentStore {
+@@ -150,7 +150,10 @@ public class TabPersistentStore {
              @Override
              public void didCloseTab(Tab tab) {
                  PersistedTabData.onTabClose(tab);
@@ -1265,7 +1268,7 @@ diff --git a/chrome/browser/history/history_tab_helper.cc b/chrome/browser/histo
 --- a/chrome/browser/history/history_tab_helper.cc
 +++ b/chrome/browser/history/history_tab_helper.cc
 @@ -27,6 +27,9 @@
- #include "chrome/browser/android/feed/v2/feed_service_factory.h"
+ #include "chrome/browser/feed/android/feed_service_factory.h"
  #include "components/feed/core/v2/public/feed_api.h"
  #include "components/feed/core/v2/public/feed_service.h"
 +#include "chrome/common/pref_names.h"
@@ -1274,7 +1277,7 @@ diff --git a/chrome/browser/history/history_tab_helper.cc b/chrome/browser/histo
  #else
  #include "chrome/browser/ui/browser.h"
  #include "chrome/browser/ui/browser_finder.h"
-@@ -345,6 +348,13 @@ void HistoryTabHelper::TitleWasSet(NavigationEntry* entry) {
+@@ -352,6 +355,13 @@ void HistoryTabHelper::TitleWasSet(NavigationEntry* entry) {
  history::HistoryService* HistoryTabHelper::GetHistoryService() {
    Profile* profile =
        Profile::FromBrowserContext(web_contents()->GetBrowserContext());
@@ -1288,7 +1291,7 @@ diff --git a/chrome/browser/history/history_tab_helper.cc b/chrome/browser/histo
    if (profile->IsOffTheRecord())
      return NULL;
  
-@@ -352,6 +362,12 @@ history::HistoryService* HistoryTabHelper::GetHistoryService() {
+@@ -359,6 +369,12 @@ history::HistoryService* HistoryTabHelper::GetHistoryService() {
        profile, ServiceAccessType::IMPLICIT_ACCESS);
  }
  
@@ -1313,8 +1316,8 @@ diff --git a/chrome/browser/history/history_tab_helper.h b/chrome/browser/histor
  
  namespace history {
  struct HistoryAddPageArgs;
-@@ -39,6 +41,11 @@ class HistoryTabHelper : public content::WebContentsObserver,
-     force_eligibile_tab_for_testing_ = force;
+@@ -42,6 +44,11 @@ class HistoryTabHelper : public content::WebContentsObserver,
+     force_eligible_tab_for_testing_ = force;
    }
  
 +  static void RegisterProfilePrefs(PrefRegistrySimple* registry);
@@ -1325,7 +1328,7 @@ diff --git a/chrome/browser/history/history_tab_helper.h b/chrome/browser/histor
   private:
    explicit HistoryTabHelper(content::WebContents* web_contents);
    friend class content::WebContentsUserData<HistoryTabHelper>;
-@@ -65,9 +72,6 @@ class HistoryTabHelper : public content::WebContentsObserver,
+@@ -68,9 +75,6 @@ class HistoryTabHelper : public content::WebContentsObserver,
                             bool started_from_context_menu,
                             bool renderer_initiated) override;
  
@@ -1516,15 +1519,14 @@ diff --git a/chrome/browser/offline_pages/android/request_coordinator_factory.cc
 diff --git a/chrome/browser/offline_pages/offline_page_model_factory.h b/chrome/browser/offline_pages/offline_page_model_factory.h
 --- a/chrome/browser/offline_pages/offline_page_model_factory.h
 +++ b/chrome/browser/offline_pages/offline_page_model_factory.h
-@@ -47,6 +47,8 @@ class OfflinePageModelFactory : public SimpleKeyedServiceFactory {
+@@ -49,6 +49,7 @@ class OfflinePageModelFactory : public SimpleKeyedServiceFactory {
+ 
    std::unique_ptr<KeyedService> BuildServiceInstanceFor(
        SimpleFactoryKey* key) const override;
- 
 +  SimpleFactoryKey* GetKeyToUse(SimpleFactoryKey* key) const override;
-+
-   DISALLOW_COPY_AND_ASSIGN(OfflinePageModelFactory);
  };
  
+ }  // namespace offline_pages
 diff --git a/chrome/browser/offline_pages/recent_tab_helper.cc b/chrome/browser/offline_pages/recent_tab_helper.cc
 --- a/chrome/browser/offline_pages/recent_tab_helper.cc
 +++ b/chrome/browser/offline_pages/recent_tab_helper.cc
@@ -1557,20 +1559,19 @@ diff --git a/chrome/browser/offline_pages/recent_tab_helper.cc b/chrome/browser/
 diff --git a/chrome/browser/offline_pages/request_coordinator_factory.h b/chrome/browser/offline_pages/request_coordinator_factory.h
 --- a/chrome/browser/offline_pages/request_coordinator_factory.h
 +++ b/chrome/browser/offline_pages/request_coordinator_factory.h
-@@ -34,6 +34,9 @@ class RequestCoordinatorFactory : public BrowserContextKeyedServiceFactory {
+@@ -37,6 +37,8 @@ class RequestCoordinatorFactory : public BrowserContextKeyedServiceFactory {
+ 
    KeyedService* BuildServiceInstanceFor(
        content::BrowserContext* context) const override;
- 
 +  content::BrowserContext* GetBrowserContextToUse(
 +      content::BrowserContext* context) const override;
-+
-   DISALLOW_COPY_AND_ASSIGN(RequestCoordinatorFactory);
  };
  
+ }  // namespace offline_pages
 diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
 --- a/chrome/browser/prefs/browser_prefs.cc
 +++ b/chrome/browser/prefs/browser_prefs.cc
-@@ -212,6 +212,8 @@
+@@ -216,6 +216,8 @@
  #endif
  
  #if defined(OS_ANDROID)
@@ -1579,7 +1580,7 @@ diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browse
  #include "chrome/browser/android/bookmarks/partner_bookmarks_shim.h"
  #include "chrome/browser/android/explore_sites/history_statistics_reporter.h"
  #include "chrome/browser/android/ntp/recent_tabs_page_prefs.h"
-@@ -1239,6 +1241,7 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry,
+@@ -1259,6 +1261,7 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry,
    variations::VariationsService::RegisterProfilePrefs(registry);
    video_tutorials::RegisterPrefs(registry);
    feed::prefs::RegisterFeedSharedProfilePrefs(registry);
@@ -1613,7 +1614,7 @@ diff --git a/chrome/browser/ui/android/native_page/java/src/org/chromium/chrome/
  /**
   * An interface for pages that will be using Android views instead of html/rendered Web content.
   */
-@@ -156,7 +158,9 @@ public interface NativePage {
+@@ -158,7 +160,9 @@ public interface NativePage {
              return NativePageType.DOWNLOADS;
          } else if (UrlConstants.HISTORY_HOST.equals(host)) {
              return NativePageType.HISTORY;
@@ -1668,7 +1669,7 @@ diff --git a/chrome/browser/ui/android/native_page/java/src/org/chromium/chrome/
 diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
 +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
-@@ -953,6 +953,12 @@ Your Google account may have other forms of browsing history like searches and a
+@@ -961,6 +961,12 @@ Your Google account may have other forms of browsing history like searches and a
        <message name="IDS_UI_RELAUNCH_NOTICE" desc="Summary for always incognito mode">
          Your changes will take effect the next time you relaunch Bromite.
        </message>
@@ -1684,7 +1685,7 @@ diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chro
 diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
 --- a/chrome/common/pref_names.cc
 +++ b/chrome/common/pref_names.cc
-@@ -3238,6 +3238,11 @@ const char kShowCaretBrowsingDialog[] =
+@@ -3276,6 +3276,11 @@ const char kShowCaretBrowsingDialog[] =
  const char kLacrosLaunchSwitch[] = "lacros_launch_switch";
  #endif
  
@@ -1699,7 +1700,7 @@ diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
 diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
 --- a/chrome/common/pref_names.h
 +++ b/chrome/common/pref_names.h
-@@ -1192,6 +1192,10 @@ extern const char kLastWhatsNewVersion[];
+@@ -1201,6 +1201,10 @@ extern const char kLastWhatsNewVersion[];
  extern const char kLensRegionSearchEnabled[];
  #endif
  
@@ -1713,7 +1714,7 @@ diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
 diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
 --- a/chrome/test/BUILD.gn
 +++ b/chrome/test/BUILD.gn
-@@ -4837,6 +4837,11 @@ test("unit_tests") {
+@@ -4818,6 +4818,11 @@ test("unit_tests") {
      ]
    }
  

+ 34 - 34
build/patches/Add-menu-item-to-bookmark-all-tabs.patch

@@ -40,7 +40,7 @@ diff --git a/chrome/android/java/res/menu/main_menu.xml b/chrome/android/java/re
          <item android:id="@+id/recent_tabs_menu_id"
              android:title="@string/menu_recent_tabs"
              android:icon="@drawable/devices_black_24dp" />
-@@ -147,6 +151,9 @@
+@@ -173,6 +177,9 @@
          <item android:id="@+id/menu_group_tabs"
              android:title="@string/menu_group_tabs"
              android:icon="@drawable/ic_widgets" />
@@ -62,7 +62,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedAct
  import org.chromium.chrome.browser.bookmarks.BookmarkUtils;
  import org.chromium.chrome.browser.browserservices.intents.WebappConstants;
  import org.chromium.chrome.browser.compositor.CompositorViewHolder;
-@@ -2040,6 +2042,8 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
+@@ -2044,6 +2046,8 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
              // Close both incognito and normal tabs
              getTabModelSelector().closeAllTabs();
              RecordUserAction.record("MobileMenuCloseAllTabs");
@@ -71,7 +71,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedAct
          } else if (id == R.id.close_all_incognito_tabs_menu_id) {
              // Close only incognito tabs
              getTabModelSelector().getModel(true).closeAllTabs();
-@@ -2089,6 +2093,28 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
+@@ -2093,6 +2097,28 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
          mTabModalHandler.onOmniboxFocusChanged(hasFocus);
      }
  
@@ -103,16 +103,16 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedAct
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java
-@@ -25,6 +25,7 @@ import androidx.annotation.Nullable;
- import androidx.annotation.VisibleForTesting;
+@@ -27,6 +27,7 @@ import androidx.annotation.VisibleForTesting;
+ import com.google.protobuf.InvalidProtocolBufferException;
  
  import org.chromium.base.ContextUtils;
 +import org.chromium.base.Log;
  import org.chromium.base.ObserverList;
  import org.chromium.base.ThreadUtils;
  import org.chromium.base.annotations.CalledByNative;
-@@ -33,6 +34,10 @@ import org.chromium.base.metrics.RecordHistogram;
- import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksShim;
+@@ -36,6 +37,10 @@ import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksShim;
+ import org.chromium.chrome.browser.power_bookmarks.PowerBookmarkMeta;
  import org.chromium.chrome.browser.profiles.Profile;
  import org.chromium.chrome.browser.tab.Tab;
 +import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar;
@@ -122,7 +122,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm
  import org.chromium.components.bookmarks.BookmarkId;
  import org.chromium.components.bookmarks.BookmarkType;
  import org.chromium.components.url_formatter.SchemeDisplay;
-@@ -73,6 +78,7 @@ import java.io.File;
+@@ -76,6 +81,7 @@ import java.io.File;
   * bookmark model stored in native.
   */
  public class BookmarkBridge {
@@ -130,7 +130,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm
      private final Profile mProfile;
      private boolean mIsDoingExtensiveChanges;
      private long mNativeBookmarkBridge;
-@@ -554,6 +560,16 @@ public class BookmarkBridge {
+@@ -557,6 +563,16 @@ public class BookmarkBridge {
                  mNativeBookmarkBridge, BookmarkBridge.this);
      }
  
@@ -147,7 +147,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm
      /**
       * @return Id representing the special "other" folder from bookmark model.
       */
-@@ -1100,6 +1116,49 @@ public class BookmarkBridge {
+@@ -1178,6 +1194,49 @@ public class BookmarkBridge {
                  mNativeBookmarkBridge, BookmarkBridge.this, title, url);
      }
  
@@ -197,7 +197,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm
      /**
       * @param url The URL of the reading list item.
       * @return The reading list item with the URL, or null if no such reading list item.
-@@ -1356,6 +1415,7 @@ public class BookmarkBridge {
+@@ -1434,6 +1493,7 @@ public class BookmarkBridge {
          void getAllFoldersWithDepths(long nativeBookmarkBridge, BookmarkBridge caller,
                  List<BookmarkId> folderList, List<Integer> depthList);
          BookmarkId getRootFolderId(long nativeBookmarkBridge, BookmarkBridge caller);
@@ -208,7 +208,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java
-@@ -515,6 +515,7 @@ public class BookmarkUtils {
+@@ -595,6 +595,7 @@ public class BookmarkUtils {
          List<BookmarkId> topLevelFolders = new ArrayList<>();
          BookmarkId desktopNodeId = bookmarkModel.getDesktopFolderId();
          BookmarkId mobileNodeId = bookmarkModel.getMobileFolderId();
@@ -216,7 +216,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm
          BookmarkId othersNodeId = bookmarkModel.getOtherFolderId();
  
          List<BookmarkId> specialFoldersIds =
-@@ -540,6 +541,9 @@ public class BookmarkUtils {
+@@ -620,6 +621,9 @@ public class BookmarkUtils {
          if (bookmarkModel.isFolderVisible(mobileNodeId)) {
              topLevelFolders.add(mobileNodeId);
          }
@@ -229,7 +229,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/Bookm
 diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browser/android/bookmarks/bookmark_bridge.cc
 --- a/chrome/browser/android/bookmarks/bookmark_bridge.cc
 +++ b/chrome/browser/android/bookmarks/bookmark_bridge.cc
-@@ -424,6 +424,11 @@ void BookmarkBridge::GetTopLevelFolderIDs(
+@@ -428,6 +428,11 @@ void BookmarkBridge::GetTopLevelFolderIDs(
          top_level_folders.push_back(node.get());
      }
  
@@ -241,7 +241,7 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browse
      for (const auto& node : bookmark_model_->bookmark_bar_node()->children()) {
        if (node->is_folder())
          top_level_folders.push_back(node.get());
-@@ -462,6 +467,7 @@ void BookmarkBridge::GetAllFoldersWithDepths(
+@@ -466,6 +471,7 @@ void BookmarkBridge::GetAllFoldersWithDepths(
    // Vector to temporarily contain all child bookmarks at same level for sorting
    std::vector<const BookmarkNode*> bookmarks = {
        bookmark_model_->mobile_node(),
@@ -249,7 +249,7 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browse
        bookmark_model_->bookmark_bar_node(),
        bookmark_model_->other_node(),
    };
-@@ -516,6 +522,17 @@ ScopedJavaLocalRef<jobject> BookmarkBridge::GetMobileFolderId(
+@@ -520,6 +526,17 @@ ScopedJavaLocalRef<jobject> BookmarkBridge::GetMobileFolderId(
    return folder_id_obj;
  }
  
@@ -270,7 +270,7 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browse
 diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.h b/chrome/browser/android/bookmarks/bookmark_bridge.h
 --- a/chrome/browser/android/bookmarks/bookmark_bridge.h
 +++ b/chrome/browser/android/bookmarks/bookmark_bridge.h
-@@ -110,6 +110,10 @@ class BookmarkBridge : public bookmarks::BaseBookmarkModelObserver,
+@@ -114,6 +114,10 @@ class BookmarkBridge : public bookmarks::BaseBookmarkModelObserver,
        JNIEnv* env,
        const base::android::JavaParamRef<jobject>& obj);
  
@@ -284,7 +284,7 @@ diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.h b/chrome/browser
 diff --git a/chrome/browser/bookmarks/bookmark_html_writer.cc b/chrome/browser/bookmarks/bookmark_html_writer.cc
 --- a/chrome/browser/bookmarks/bookmark_html_writer.cc
 +++ b/chrome/browser/bookmarks/bookmark_html_writer.cc
-@@ -186,6 +186,8 @@ class Writer : public base::RefCountedThreadSafe<Writer> {
+@@ -191,6 +191,8 @@ class Writer : public base::RefCountedThreadSafe<Writer> {
          roots->FindDictKey(BookmarkCodec::kOtherBookmarkFolderNameKey);
      base::Value* mobile_folder_value =
          roots->FindDictKey(BookmarkCodec::kMobileBookmarkFolderNameKey);
@@ -293,7 +293,7 @@ diff --git a/chrome/browser/bookmarks/bookmark_html_writer.cc b/chrome/browser/b
      DCHECK(root_folder_value);
      DCHECK(other_folder_value);
      DCHECK(mobile_folder_value);
-@@ -197,7 +199,9 @@ class Writer : public base::RefCountedThreadSafe<Writer> {
+@@ -202,7 +204,9 @@ class Writer : public base::RefCountedThreadSafe<Writer> {
          !WriteNode(*static_cast<base::DictionaryValue*>(other_folder_value),
                     BookmarkNode::OTHER_NODE) ||
          !WriteNode(*static_cast<base::DictionaryValue*>(mobile_folder_value),
@@ -304,7 +304,7 @@ diff --git a/chrome/browser/bookmarks/bookmark_html_writer.cc b/chrome/browser/b
        NotifyOnFinish(BookmarksExportObserver::Result::kCouldNotWriteNodes);
        return;
      }
-@@ -464,6 +468,8 @@ void BookmarkFaviconFetcher::ExportBookmarks() {
+@@ -467,6 +471,8 @@ void BookmarkFaviconFetcher::ExportBookmarks() {
        BookmarkModelFactory::GetForBrowserContext(profile_)->other_node());
    ExtractUrls(
        BookmarkModelFactory::GetForBrowserContext(profile_)->mobile_node());
@@ -316,7 +316,7 @@ diff --git a/chrome/browser/bookmarks/bookmark_html_writer.cc b/chrome/browser/b
 diff --git a/chrome/browser/bookmarks/chrome_bookmark_client.cc b/chrome/browser/bookmarks/chrome_bookmark_client.cc
 --- a/chrome/browser/bookmarks/chrome_bookmark_client.cc
 +++ b/chrome/browser/bookmarks/chrome_bookmark_client.cc
-@@ -105,6 +105,8 @@ bool ChromeBookmarkClient::IsPermanentNodeVisibleWhenEmpty(
+@@ -117,6 +117,8 @@ bool ChromeBookmarkClient::IsPermanentNodeVisibleWhenEmpty(
        return !is_mobile;
      case bookmarks::BookmarkNode::MOBILE:
        return is_mobile;
@@ -328,7 +328,7 @@ diff --git a/chrome/browser/bookmarks/chrome_bookmark_client.cc b/chrome/browser
 diff --git a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationCustomView.java b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationCustomView.java
 --- a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationCustomView.java
 +++ b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationCustomView.java
-@@ -75,7 +75,7 @@ public class DownloadLocationCustomView
+@@ -79,7 +79,7 @@ public class DownloadLocationCustomView
          mDirectoryAdapter.update();
      }
  
@@ -337,7 +337,7 @@ diff --git a/chrome/browser/download/android/java/src/org/chromium/chrome/browse
          mTitle.setText(title);
      }
  
-@@ -83,7 +83,7 @@ public class DownloadLocationCustomView
+@@ -87,7 +87,7 @@ public class DownloadLocationCustomView
          mSubtitleView.setText(subtitle);
      }
  
@@ -349,7 +349,7 @@ diff --git a/chrome/browser/download/android/java/src/org/chromium/chrome/browse
 diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
 +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
-@@ -3273,6 +3273,9 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
+@@ -3312,6 +3312,9 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
        <message name="IDS_MENU_TRACK_PRICES" desc="Menu item for tracking prices on tabs. [CHAR_LIMIT=27]">
          Track prices
        </message>
@@ -491,7 +491,7 @@ diff --git a/components/bookmarks/browser/bookmark_codec.cc b/components/bookmar
 diff --git a/components/bookmarks/browser/bookmark_codec.h b/components/bookmarks/browser/bookmark_codec.h
 --- a/components/bookmarks/browser/bookmark_codec.h
 +++ b/components/bookmarks/browser/bookmark_codec.h
-@@ -46,6 +46,7 @@ class BookmarkCodec {
+@@ -50,6 +50,7 @@ class BookmarkCodec {
    base::Value Encode(const BookmarkNode* bookmark_bar_node,
                       const BookmarkNode* other_folder_node,
                       const BookmarkNode* mobile_folder_node,
@@ -499,7 +499,7 @@ diff --git a/components/bookmarks/browser/bookmark_codec.h b/components/bookmark
                       const BookmarkNode::MetaInfoMap* model_meta_info_map,
                       const std::string& sync_metadata_str);
  
-@@ -58,6 +59,7 @@ class BookmarkCodec {
+@@ -62,6 +63,7 @@ class BookmarkCodec {
                BookmarkNode* bb_node,
                BookmarkNode* other_folder_node,
                BookmarkNode* mobile_folder_node,
@@ -507,7 +507,7 @@ diff --git a/components/bookmarks/browser/bookmark_codec.h b/components/bookmark
                int64_t* max_node_id,
                std::string* sync_metadata_str);
  
-@@ -103,6 +105,7 @@ class BookmarkCodec {
+@@ -107,6 +109,7 @@ class BookmarkCodec {
    // Allows the BookmarkClient to read and a write a string blob from the JSON
    // file. That string captures the bookmarks sync metadata.
    static const char kSyncMetadata[];
@@ -515,7 +515,7 @@ diff --git a/components/bookmarks/browser/bookmark_codec.h b/components/bookmark
  
    // Possible values for kTypeKey.
    static const char kTypeURL[];
-@@ -119,6 +122,7 @@ class BookmarkCodec {
+@@ -123,6 +126,7 @@ class BookmarkCodec {
    bool DecodeHelper(BookmarkNode* bb_node,
                      BookmarkNode* other_folder_node,
                      BookmarkNode* mobile_folder_node,
@@ -523,7 +523,7 @@ diff --git a/components/bookmarks/browser/bookmark_codec.h b/components/bookmark
                      const base::Value& value,
                      std::string* sync_metadata_str);
  
-@@ -130,7 +134,8 @@ class BookmarkCodec {
+@@ -134,7 +138,8 @@ class BookmarkCodec {
    // Reassigns bookmark IDs for all nodes.
    void ReassignIDs(BookmarkNode* bb_node,
                     BookmarkNode* other_node,
@@ -569,7 +569,7 @@ diff --git a/components/bookmarks/browser/bookmark_load_details.h b/components/b
 diff --git a/components/bookmarks/browser/bookmark_model.cc b/components/bookmarks/browser/bookmark_model.cc
 --- a/components/bookmarks/browser/bookmark_model.cc
 +++ b/components/bookmarks/browser/bookmark_model.cc
-@@ -562,7 +562,7 @@ bool BookmarkModel::HasBookmarks() {
+@@ -564,7 +564,7 @@ bool BookmarkModel::HasBookmarks() {
  bool BookmarkModel::HasNoUserCreatedBookmarksOrFolders() {
    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
    return bookmark_bar_node_->children().empty() &&
@@ -578,7 +578,7 @@ diff --git a/components/bookmarks/browser/bookmark_model.cc b/components/bookmar
  }
  
  bool BookmarkModel::IsBookmarked(const GURL& url) {
-@@ -804,6 +804,7 @@ void BookmarkModel::DoneLoading(std::unique_ptr<BookmarkLoadDetails> details) {
+@@ -806,6 +806,7 @@ void BookmarkModel::DoneLoading(std::unique_ptr<BookmarkLoadDetails> details) {
    bookmark_bar_node_ = details->bb_node();
    other_node_ = details->other_folder_node();
    mobile_node_ = details->mobile_folder_node();
@@ -589,7 +589,7 @@ diff --git a/components/bookmarks/browser/bookmark_model.cc b/components/bookmar
 diff --git a/components/bookmarks/browser/bookmark_model.h b/components/bookmarks/browser/bookmark_model.h
 --- a/components/bookmarks/browser/bookmark_model.h
 +++ b/components/bookmarks/browser/bookmark_model.h
-@@ -116,6 +116,12 @@ class BookmarkModel : public BookmarkUndoProvider,
+@@ -120,6 +120,12 @@ class BookmarkModel : public BookmarkUndoProvider,
      return mobile_node_;
    }
  
@@ -602,7 +602,7 @@ diff --git a/components/bookmarks/browser/bookmark_model.h b/components/bookmark
    bool is_root_node(const BookmarkNode* node) const {
      DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
      return node == root_;
-@@ -391,6 +397,7 @@ class BookmarkModel : public BookmarkUndoProvider,
+@@ -395,6 +401,7 @@ class BookmarkModel : public BookmarkUndoProvider,
    BookmarkPermanentNode* bookmark_bar_node_ = nullptr;
    BookmarkPermanentNode* other_node_ = nullptr;
    BookmarkPermanentNode* mobile_node_ = nullptr;
@@ -661,7 +661,7 @@ diff --git a/components/bookmarks/browser/bookmark_node.h b/components/bookmarks
    static const char kManagedNodeGuid[];
  
    // A bug in sync caused some problematic GUIDs to be produced.
-@@ -247,6 +249,9 @@ class BookmarkPermanentNode : public BookmarkNode {
+@@ -251,6 +253,9 @@ class BookmarkPermanentNode : public BookmarkNode {
    static std::unique_ptr<BookmarkPermanentNode> CreateMobileBookmarks(
        int64_t id,
        bool visible_when_empty);

+ 11 - 11
build/patches/Add-menu-item-to-view-source.patch

@@ -28,7 +28,7 @@ diff --git a/chrome/android/java/res/menu/custom_tabs_menu.xml b/chrome/android/
 diff --git a/chrome/android/java/res/menu/main_menu.xml b/chrome/android/java/res/menu/main_menu.xml
 --- a/chrome/android/java/res/menu/main_menu.xml
 +++ b/chrome/android/java/res/menu/main_menu.xml
-@@ -88,6 +88,9 @@
+@@ -103,6 +103,9 @@
          <item android:id="@+id/add_to_homescreen_id"
              android:title="@string/menu_add_to_homescreen"
              android:icon="@drawable/ic_add_to_home_screen" />
@@ -41,7 +41,7 @@ diff --git a/chrome/android/java/res/menu/main_menu.xml b/chrome/android/java/re
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
-@@ -2063,6 +2063,8 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
+@@ -2067,6 +2067,8 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
                  NewTabPageUma.recordAction(NewTabPageUma.ACTION_OPENED_DOWNLOADS_MANAGER);
              }
              RecordUserAction.record("MobileMenuDownloadManager");
@@ -53,7 +53,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedAct
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
-@@ -2436,6 +2436,11 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
+@@ -2451,6 +2451,11 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
              return true;
          }
  
@@ -68,15 +68,15 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActiv
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
-@@ -355,6 +355,7 @@ public class AppMenuPropertiesDelegateImpl implements AppMenuPropertiesDelegate
+@@ -511,6 +511,7 @@ public class AppMenuPropertiesDelegateImpl implements AppMenuPropertiesDelegate
                          isChromeScheme, isFileScheme, isContentScheme, isIncognito, url));
  
-         updateRequestDesktopSiteMenuItem(menu, currentTab, true /* can show */);
+         updateRequestDesktopSiteMenuItem(menu, currentTab, true /* can show */, isChromeScheme);
 +        updateViewSourceMenuItem(menu, currentTab);
  
-         // Only display reader mode settings menu option if the current page is in reader mode.
-         menu.findItem(R.id.reader_mode_prefs_id).setVisible(shouldShowReaderModePrefs(currentTab));
-@@ -845,6 +846,19 @@ public class AppMenuPropertiesDelegateImpl implements AppMenuPropertiesDelegate
+         updateAutoDarkMenuItem(menu, currentTab, isChromeScheme);
+ 
+@@ -1027,6 +1028,19 @@ public class AppMenuPropertiesDelegateImpl implements AppMenuPropertiesDelegate
          }
      }
  
@@ -99,10 +99,10 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/App
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabAppMenuPropertiesDelegate.java
-@@ -214,6 +214,7 @@ public class CustomTabAppMenuPropertiesDelegate extends AppMenuPropertiesDelegat
-             }
+@@ -217,6 +217,7 @@ public class CustomTabAppMenuPropertiesDelegate extends AppMenuPropertiesDelegat
  
-             updateRequestDesktopSiteMenuItem(menu, currentTab, requestDesktopSiteVisible);
+             updateRequestDesktopSiteMenuItem(
+                     menu, currentTab, requestDesktopSiteVisible, isChromeScheme);
 +            updateViewSourceMenuItem(menu, currentTab);
              prepareAddToHomescreenMenuItem(menu, currentTab, addToHomeScreenVisible);
          }

+ 43 - 29
build/patches/Add-option-to-force-tablet-UI.patch

@@ -3,17 +3,17 @@ Date: Mon, 1 Feb 2021 19:18:55 +0200
 Subject: Add option to force tablet UI
 
 ---
- .../android/java/res/xml/accessibility_preferences.xml |  5 +++++
- .../accessibility/settings/AccessibilitySettings.java  | 10 ++++++++++
- .../browser/preferences/ChromePreferenceKeys.java      |  1 +
- .../preferences/LegacyChromePreferenceKeys.java        |  1 +
- .../chrome/browser/omnibox/LocationBarCoordinator.java |  2 +-
- .../ui/android/strings/android_chrome_strings.grd      |  6 ++++++
- .../browser/toolbar/top/ToolbarControlContainer.java   |  2 +-
- components/BUILD.gn                                    |  4 ++--
- ui/android/BUILD.gn                                    |  2 ++
- .../src/org/chromium/ui/base/DeviceFormFactor.java     |  5 +++++
- 10 files changed, 34 insertions(+), 4 deletions(-)
+ .../java/res/xml/accessibility_preferences.xml   |  5 +++++
+ .../settings/AccessibilitySettings.java          | 10 ++++++++++
+ .../preferences/ChromePreferenceKeys.java        |  1 +
+ .../preferences/LegacyChromePreferenceKeys.java  |  1 +
+ .../browser/omnibox/LocationBarCoordinator.java  |  2 +-
+ .../android/strings/android_chrome_strings.grd   |  6 ++++++
+ .../toolbar/top/ToolbarControlContainer.java     | 16 ----------------
+ components/BUILD.gn                              |  4 ++--
+ ui/android/BUILD.gn                              |  2 ++
+ .../org/chromium/ui/base/DeviceFormFactor.java   |  5 +++++
+ 10 files changed, 33 insertions(+), 19 deletions(-)
 
 diff --git a/chrome/android/java/res/xml/accessibility_preferences.xml b/chrome/android/java/res/xml/accessibility_preferences.xml
 --- a/chrome/android/java/res/xml/accessibility_preferences.xml
@@ -33,15 +33,15 @@ diff --git a/chrome/android/java/res/xml/accessibility_preferences.xml b/chrome/
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/accessibility/settings/AccessibilitySettings.java b/chrome/android/java/src/org/chromium/chrome/browser/accessibility/settings/AccessibilitySettings.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/accessibility/settings/AccessibilitySettings.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/accessibility/settings/AccessibilitySettings.java
-@@ -37,6 +37,7 @@ public class AccessibilitySettings
+@@ -35,6 +35,7 @@ public class AccessibilitySettings
+     static final String PREF_CAPTIONS = "captions";
      static final String PREF_IMAGE_DESCRIPTIONS = "image_descriptions";
-     static final String PREF_ACCESSIBILITY_PAGE_ZOOM = "accessibility_page_zoom";
  
 +    static final String PREF_FORCE_TABLET_UI = "force_tablet_ui";
      private TextScalePreference mTextScalePref;
      private ChromeBaseCheckBoxPreference mForceEnableZoomPref;
      private boolean mRecordFontSizeChangeOnStop;
-@@ -82,6 +83,12 @@ public class AccessibilitySettings
+@@ -80,6 +81,12 @@ public class AccessibilitySettings
                                                        .getBoolean(Pref.READER_FOR_ACCESSIBILITY));
          readerForAccessibilityPref.setOnPreferenceChangeListener(this);
  
@@ -54,7 +54,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/accessibility/s
          ChromeBaseCheckBoxPreference mAccessibilityTabSwitcherPref =
                  (ChromeBaseCheckBoxPreference) findPreference(
                          ChromePreferenceKeys.ACCESSIBILITY_TAB_SWITCHER);
-@@ -137,6 +144,9 @@ public class AccessibilitySettings
+@@ -131,6 +138,9 @@ public class AccessibilitySettings
              mFontSizePrefs.setUserFontScaleFactor((Float) newValue);
          } else if (PREF_FORCE_ENABLE_ZOOM.equals(preference.getKey())) {
              mFontSizePrefs.setForceEnableZoomFromUser((Boolean) newValue);
@@ -67,7 +67,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/accessibility/s
 diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
 --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
 +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
-@@ -543,6 +543,7 @@ public final class ChromePreferenceKeys {
+@@ -516,6 +516,7 @@ public final class ChromePreferenceKeys {
      public static final String FONT_USER_SET_FORCE_ENABLE_ZOOM = "user_set_force_enable_zoom";
  
      public static final String HISTORY_SHOW_HISTORY_INFO = "history_home_show_info";
@@ -78,7 +78,7 @@ diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/bro
 diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/LegacyChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/LegacyChromePreferenceKeys.java
 --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/LegacyChromePreferenceKeys.java
 +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/LegacyChromePreferenceKeys.java
-@@ -99,6 +99,7 @@ public class LegacyChromePreferenceKeys {
+@@ -98,6 +98,7 @@ public class LegacyChromePreferenceKeys {
                  ChromePreferenceKeys.FLAGS_CACHED_SWAP_PIXEL_FORMAT_TO_FIX_CONVERT_FROM_TRANSLUCENT,
                  ChromePreferenceKeys.FLAGS_CACHED_TAB_GROUPS_ANDROID_ENABLED,
                  ChromePreferenceKeys.FONT_USER_FONT_SCALE_FACTOR,
@@ -89,7 +89,7 @@ diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/bro
 diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarCoordinator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarCoordinator.java
 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarCoordinator.java
 +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarCoordinator.java
-@@ -348,7 +348,7 @@ public final class LocationBarCoordinator implements LocationBar, NativeInitObse
+@@ -355,7 +355,7 @@ public final class LocationBarCoordinator implements LocationBar, NativeInitObse
      // OmniboxSuggestionsDropdownEmbedder implementation
      @Override
      public boolean isTablet() {
@@ -101,7 +101,7 @@ diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/brow
 diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
 +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
-@@ -1223,6 +1223,12 @@ Your Google account may have other forms of browsing history like searches and a
+@@ -1234,6 +1234,12 @@ Your Google account may have other forms of browsing history like searches and a
        <message name="IDS_SAFE_BROWSING_NO_PROTECTION_CONFIRMATION_DIALOG_CONFIRM" desc="Message for Safe Browsing no protection confirmation button.">
          Turn off
        </message>
@@ -117,19 +117,33 @@ diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chro
 diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java
 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java
 +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java
-@@ -109,7 +109,7 @@ public class ToolbarControlContainer extends OptimizedFrameLayout implements Con
-             // On tablet, draw a fake tab strip and toolbar until the compositor is
-             // ready to draw the real tab strip. (On phone, the toolbar is made entirely
-             // of Android views, which are already initialized.)
--            setBackgroundResource(R.drawable.toolbar_background);
-+//             setBackgroundResource(R.drawable.toolbar_background);
-         }
+@@ -106,22 +106,6 @@ public class ToolbarControlContainer extends OptimizedFrameLayout implements Con
+     public void setToolbar(Toolbar toolbar, boolean isIncognito) {
+         mToolbar = toolbar;
+         mToolbarContainer.setToolbar(mToolbar);
+-
+-        View toolbarView = findViewById(R.id.toolbar);
+-        assert toolbarView != null;
+-
+-        if (toolbarView instanceof ToolbarTablet) {
+-            // On tablet, draw a fake tab strip and toolbar until the compositor is
+-            // ready to draw the real tab strip. (On phone, the toolbar is made entirely
+-            // of Android views, which are already initialized.)
+-            final Drawable backgroundDrawable =
+-                    AppCompatResources.getDrawable(getContext(), R.drawable.toolbar_background)
+-                            .mutate();
+-            backgroundDrawable.setTint(
+-                    ChromeColors.getDefaultThemeColor(getContext(), isIncognito));
+-            backgroundDrawable.setTintMode(PorterDuff.Mode.MULTIPLY);
+-            setBackground(backgroundDrawable);
+-        }
      }
  
+     @Override
 diff --git a/components/BUILD.gn b/components/BUILD.gn
 --- a/components/BUILD.gn
 +++ b/components/BUILD.gn
-@@ -549,7 +549,7 @@ test("components_unittests") {
+@@ -555,7 +555,7 @@ test("components_unittests") {
  
    # On LaCrOS, tests use ash - chrome as a window manager, thus the dependency.
    # On other platforms, no components should depend on Chrome.
@@ -138,7 +152,7 @@ diff --git a/components/BUILD.gn b/components/BUILD.gn
      assert_no_deps = [ "//chrome/*" ]
    }
  
-@@ -798,7 +798,7 @@ if (!is_ios) {
+@@ -804,7 +804,7 @@ if (!is_ios) {
  
      # On LaCrOS, tests use ash - chrome as a window manager, thus the dependency.
      # On other platforms, no components should depend on Chrome.
@@ -150,7 +164,7 @@ diff --git a/components/BUILD.gn b/components/BUILD.gn
 diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn
 --- a/ui/android/BUILD.gn
 +++ b/ui/android/BUILD.gn
-@@ -369,6 +369,8 @@ android_library("ui_no_recycler_view_java") {
+@@ -359,6 +359,8 @@ android_library("ui_no_recycler_view_java") {
      ":ui_java_resources",
      ":ui_utils_java",
      "//base:base_java",

+ 9 - 9
build/patches/Add-option-to-not-persist-tabs-across-sessions.patch

@@ -12,7 +12,7 @@ Subject: Add option to not persist tabs across sessions
 diff --git a/chrome/android/java/res/xml/privacy_preferences.xml b/chrome/android/java/res/xml/privacy_preferences.xml
 --- a/chrome/android/java/res/xml/privacy_preferences.xml
 +++ b/chrome/android/java/res/xml/privacy_preferences.xml
-@@ -37,6 +37,11 @@
+@@ -42,6 +42,11 @@
          android:title="@string/always_incognito_title"
          android:summary="@string/always_incognito_summary"
          android:defaultValue="false" />
@@ -59,16 +59,16 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
  import org.chromium.chrome.R;
  import org.chromium.chrome.browser.feedback.HelpAndFeedbackLauncherImpl;
  import org.chromium.chrome.browser.flags.ChromeFeatureList;
-@@ -59,6 +62,8 @@ public class PrivacySettings
-     private static final String PREF_PRIVACY_SANDBOX = "privacy_sandbox";
+@@ -63,6 +66,8 @@ public class PrivacySettings
      private static final String PREF_PRIVACY_REVIEW = "privacy_review";
+     private static final String PREF_INCOGNITO_LOCK = "incognito_lock";
  
 +    private static final String PREF_CLOSE_TABS_ON_EXIT = "close_tabs_on_exit";
 +
      private ManagedPreferenceDelegate mManagedPreferenceDelegate;
  
      @Override
-@@ -136,7 +141,11 @@ public class PrivacySettings
+@@ -178,7 +183,11 @@ public class PrivacySettings
      @Override
      public boolean onPreferenceChange(Preference preference, Object newValue) {
          String key = preference.getKey();
@@ -81,22 +81,22 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
              UserPrefs.get(Profile.getLastUsedRegularProfile())
                      .setBoolean(Pref.CAN_MAKE_PAYMENT_ENABLED, (boolean) newValue);
          } else if (PREF_NETWORK_PREDICTIONS.equals(key)) {
-@@ -188,6 +197,11 @@ public class PrivacySettings
-             privacySandboxPreference.setSummary(
+@@ -234,6 +243,11 @@ public class PrivacySettings
                      PrivacySandboxSettingsFragment.getStatusString(getContext()));
          }
-+
+ 
 +        ChromeSwitchPreference closeTabsOnExitPref =
 +                (ChromeSwitchPreference) findPreference(PREF_CLOSE_TABS_ON_EXIT);
 +        closeTabsOnExitPref.setOnPreferenceChangeListener(this);
 +        closeTabsOnExitPref.setManagedPreferenceDelegate(mManagedPreferenceDelegate);
++
+         updateIncognitoReauthPreference();
      }
  
-     private ChromeManagedPreferenceDelegate createManagedPreferenceDelegate() {
 diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
 +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
-@@ -4081,6 +4081,12 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
+@@ -4132,6 +4132,12 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
        <message name="IDS_CONTEXTMENU_IMAGE_TITLE" desc="The title of a context menu tab when the item pressed contains more than one type. This indicates that all the actions are related to the image.">
          IMAGE
        </message>

+ 6 - 6
build/patches/Add-option-to-use-home-page-as-NTP.patch

@@ -35,7 +35,7 @@ diff --git a/chrome/android/java/res/xml/homepage_preferences.xml b/chrome/andro
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/homepage/HomepageManager.java b/chrome/android/java/src/org/chromium/chrome/browser/homepage/HomepageManager.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/homepage/HomepageManager.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/homepage/HomepageManager.java
-@@ -209,6 +209,22 @@ public class HomepageManager implements HomepagePolicyManager.HomepagePolicyStat
+@@ -214,6 +214,22 @@ public class HomepageManager implements HomepagePolicyManager.HomepagePolicyStat
          notifyHomepageUpdated();
      }
  
@@ -132,10 +132,10 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/Chrome
 diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
 --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
 +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
-@@ -550,6 +550,7 @@ public final class ChromePreferenceKeys {
-     public static final String HOMEPAGE_ENABLED = "homepage";
-     public static final String HOMEPAGE_USE_CHROME_NTP = "Chrome.Homepage.UseNTP";
+@@ -524,6 +524,7 @@ public final class ChromePreferenceKeys {
      public static final String HOMEPAGE_USE_DEFAULT_URI = "homepage_partner_enabled";
+     public static final String HOMEPAGE_PARTNER_CUSTOMIZED_DEFAULT_URI =
+             "Chrome.Homepage.PartnerCustomizedDefaultUri";
 +    public static final String HOMEPAGE_NTP_IS_HOMEPAGE = "newtabpage_is_homepage";
  
      /**
@@ -143,7 +143,7 @@ diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/bro
 diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/LegacyChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/LegacyChromePreferenceKeys.java
 --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/LegacyChromePreferenceKeys.java
 +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/LegacyChromePreferenceKeys.java
-@@ -105,6 +105,7 @@ public class LegacyChromePreferenceKeys {
+@@ -103,6 +103,7 @@ public class LegacyChromePreferenceKeys {
                  ChromePreferenceKeys.HOMEPAGE_CUSTOM_URI,
                  ChromePreferenceKeys.HOMEPAGE_ENABLED,
                  ChromePreferenceKeys.HOMEPAGE_USE_DEFAULT_URI,
@@ -154,7 +154,7 @@ diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/bro
 diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
 +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
-@@ -1050,6 +1050,9 @@ Your Google account may have other forms of browsing history like searches and a
+@@ -1010,6 +1010,9 @@ Your Google account may have other forms of browsing history like searches and a
        <message name="IDS_CLEAR_BROWSING_DATA_TAB_PERIOD_HOUR" desc="The option to delete browsing data from the last hour.">
          Last hour
        </message>

+ 15 - 15
build/patches/Allow-building-without-enable_reporting.patch

@@ -25,7 +25,7 @@ Subject: Allow building without enable_reporting
 diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
 --- a/content/browser/BUILD.gn
 +++ b/content/browser/BUILD.gn
-@@ -1251,6 +1251,10 @@ source_set("browser") {
+@@ -1275,6 +1275,10 @@ source_set("browser") {
      "net/browser_online_state_observer.cc",
      "net/browser_online_state_observer.h",
      "net/cookie_store_factory.cc",
@@ -36,7 +36,7 @@ diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
      "net/network_errors_listing_ui.cc",
      "net/network_errors_listing_ui.h",
      "net/network_quality_observer_impl.cc",
-@@ -3009,10 +3013,6 @@ source_set("browser") {
+@@ -3035,10 +3039,6 @@ source_set("browser") {
  
    if (enable_reporting) {
      sources += [
@@ -69,7 +69,7 @@ diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/brow
 diff --git a/content/browser/devtools/protocol/network_handler.h b/content/browser/devtools/protocol/network_handler.h
 --- a/content/browser/devtools/protocol/network_handler.h
 +++ b/content/browser/devtools/protocol/network_handler.h
-@@ -304,8 +304,10 @@ class NetworkHandler : public DevToolsDomainHandler,
+@@ -309,8 +309,10 @@ class NetworkHandler : public DevToolsDomainHandler,
        Response response,
        mojo::ScopedDataPipeConsumerHandle pipe,
        const std::string& mime_type);
@@ -83,7 +83,7 @@ diff --git a/content/browser/devtools/protocol/network_handler.h b/content/brows
 diff --git a/content/browser/net/cross_origin_embedder_policy_reporter.cc b/content/browser/net/cross_origin_embedder_policy_reporter.cc
 --- a/content/browser/net/cross_origin_embedder_policy_reporter.cc
 +++ b/content/browser/net/cross_origin_embedder_policy_reporter.cc
-@@ -107,6 +107,7 @@ void CrossOriginEmbedderPolicyReporter::QueueAndNotify(
+@@ -112,6 +112,7 @@ void CrossOriginEmbedderPolicyReporter::QueueAndNotify(
          kType, context_url_, blink::mojom::ReportBody::New(std::move(list))));
    }
    if (endpoint) {
@@ -91,7 +91,7 @@ diff --git a/content/browser/net/cross_origin_embedder_policy_reporter.cc b/cont
      base::DictionaryValue body_to_pass;
      for (const auto& pair : body) {
        body_to_pass.SetString(pair.first, pair.second);
-@@ -117,6 +118,7 @@ void CrossOriginEmbedderPolicyReporter::QueueAndNotify(
+@@ -122,6 +123,7 @@ void CrossOriginEmbedderPolicyReporter::QueueAndNotify(
          kType, *endpoint, context_url_, reporting_source_,
          network_isolation_key_,
          /*user_agent=*/absl::nullopt, std::move(body_to_pass));
@@ -179,7 +179,7 @@ diff --git a/content/browser/net/cross_origin_opener_policy_reporter.cc b/conten
 diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc
 --- a/content/browser/renderer_host/render_frame_host_impl.cc
 +++ b/content/browser/renderer_host/render_frame_host_impl.cc
-@@ -10653,6 +10653,7 @@ void RenderFrameHostImpl::OnSameDocumentCommitProcessed(
+@@ -10649,6 +10649,7 @@ void RenderFrameHostImpl::OnSameDocumentCommitProcessed(
  void RenderFrameHostImpl::MaybeGenerateCrashReport(
      base::TerminationStatus status,
      int exit_code) {
@@ -187,7 +187,7 @@ diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/b
    if (!last_committed_url_.SchemeIsHTTPOrHTTPS())
      return;
  
-@@ -10702,6 +10703,7 @@ void RenderFrameHostImpl::MaybeGenerateCrashReport(
+@@ -10698,6 +10699,7 @@ void RenderFrameHostImpl::MaybeGenerateCrashReport(
        /*type=*/"crash", /*group=*/"default", last_committed_url_,
        GetReportingSource(), isolation_info_.network_isolation_key(),
        absl::nullopt /* user_agent */, std::move(body));
@@ -240,7 +240,7 @@ diff --git a/content/public/common/content_switch_dependent_feature_overrides.cc
 diff --git a/net/reporting/reporting_service.cc b/net/reporting/reporting_service.cc
 --- a/net/reporting/reporting_service.cc
 +++ b/net/reporting/reporting_service.cc
-@@ -202,6 +202,12 @@ class ReportingServiceImpl : public ReportingService {
+@@ -206,6 +206,12 @@ class ReportingServiceImpl : public ReportingService {
        std::unique_ptr<const base::Value> body,
        int depth,
        base::TimeTicks queued_ticks) {
@@ -256,7 +256,7 @@ diff --git a/net/reporting/reporting_service.cc b/net/reporting/reporting_servic
 diff --git a/services/network/network_context.cc b/services/network/network_context.cc
 --- a/services/network/network_context.cc
 +++ b/services/network/network_context.cc
-@@ -1118,25 +1118,9 @@ void NetworkContext::SetDocumentReportingEndpoints(
+@@ -1121,25 +1121,9 @@ void NetworkContext::SetDocumentReportingEndpoints(
  
  void NetworkContext::SendReportsAndRemoveSource(
      const base::UnguessableToken& reporting_source) {
@@ -286,7 +286,7 @@ diff --git a/services/network/network_context.cc b/services/network/network_cont
 diff --git a/services/network/network_context.h b/services/network/network_context.h
 --- a/services/network/network_context.h
 +++ b/services/network/network_context.h
-@@ -415,17 +415,6 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
+@@ -418,17 +418,6 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
        const base::flat_map<std::string, std::string>& endpoints) override;
    void SendReportsAndRemoveSource(
        const base::UnguessableToken& reporting_source) override;
@@ -307,7 +307,7 @@ diff --git a/services/network/network_context.h b/services/network/network_conte
 diff --git a/services/network/public/mojom/BUILD.gn b/services/network/public/mojom/BUILD.gn
 --- a/services/network/public/mojom/BUILD.gn
 +++ b/services/network/public/mojom/BUILD.gn
-@@ -888,6 +888,9 @@ mojom("mojom") {
+@@ -916,6 +916,9 @@ mojom("mojom") {
      export_class_attribute_blink = "BLINK_PLATFORM_EXPORT"
      export_define_blink = "BLINK_PLATFORM_IMPLEMENTATION=1"
      export_header_blink = "third_party/blink/public/platform/web_common.h"
@@ -320,7 +320,7 @@ diff --git a/services/network/public/mojom/BUILD.gn b/services/network/public/mo
 diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
 --- a/services/network/public/mojom/network_context.mojom
 +++ b/services/network/public/mojom/network_context.mojom
-@@ -972,6 +972,7 @@ interface NetworkContext {
+@@ -986,6 +986,7 @@ interface NetworkContext {
    // provided |network_isolation_key|.
    //
    // Spec: https://w3c.github.io/reporting/#concept-reports
@@ -328,7 +328,7 @@ diff --git a/services/network/public/mojom/network_context.mojom b/services/netw
    QueueReport(string type,
                string group,
                url.mojom.Url url,
-@@ -985,6 +986,7 @@ interface NetworkContext {
+@@ -999,6 +1000,7 @@ interface NetworkContext {
    // Note that this queued report will never be delivered if no reporting
    // endpoint matching is registered for with the provided
    // |network_isolation_key|.
@@ -347,7 +347,7 @@ diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/
  #include "services/data_decoder/public/mojom/resource_snapshot_for_web_bundle.mojom-blink.h"
  #include "services/network/public/cpp/features.h"
  #include "services/network/public/mojom/content_security_policy.mojom-blink.h"
-@@ -2282,9 +2283,11 @@ const base::UnguessableToken& LocalFrame::GetAgentClusterId() const {
+@@ -2302,9 +2303,11 @@ const base::UnguessableToken& LocalFrame::GetAgentClusterId() const {
    return base::UnguessableToken::Null();
  }
  
@@ -373,7 +373,7 @@ diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/b
  #include "services/device/public/mojom/device_posture_provider.mojom-blink-forward.h"
  #include "services/network/public/mojom/fetch_api.mojom-blink-forward.h"
  #include "third_party/blink/public/common/frame/frame_ad_evidence.h"
-@@ -544,9 +544,9 @@ class CORE_EXPORT LocalFrame final : public Frame,
+@@ -545,9 +545,9 @@ class CORE_EXPORT LocalFrame final : public Frame,
    }
  
    SmoothScrollSequencer& GetSmoothScrollSequencer();

+ 2 - 2
build/patches/Allow-playing-audio-in-background.patch

@@ -23,7 +23,7 @@ diff --git a/third_party/blink/public/platform/media/web_media_player_impl.h b/t
 diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.cc b/third_party/blink/renderer/platform/media/web_media_player_impl.cc
 --- a/third_party/blink/renderer/platform/media/web_media_player_impl.cc
 +++ b/third_party/blink/renderer/platform/media/web_media_player_impl.cc
-@@ -1120,6 +1120,12 @@ bool WebMediaPlayerImpl::HasAudio() const {
+@@ -1115,6 +1115,12 @@ bool WebMediaPlayerImpl::HasAudio() const {
    return pipeline_metadata_.has_audio;
  }
  
@@ -36,7 +36,7 @@ diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.cc
  void WebMediaPlayerImpl::EnabledAudioTracksChanged(
      const WebVector<WebMediaPlayer::TrackId>& enabledTrackIds) {
    DCHECK(main_task_runner_->BelongsToCurrentThread());
-@@ -3492,7 +3498,11 @@ bool WebMediaPlayerImpl::ShouldPausePlaybackWhenHidden() const {
+@@ -3479,7 +3485,11 @@ bool WebMediaPlayerImpl::ShouldPausePlaybackWhenHidden() const {
    // Audio only stream is allowed to play when in background.
    // TODO: We should check IsBackgroundOptimizationCandidate here. But we need
    // to move the logic of checking video frames out of that function.

+ 4 - 4
build/patches/Allow-website-sign-in-without-account-sign-in.patch

@@ -10,10 +10,10 @@ Disable prefs::kSigninAllowedOnNextStartup by default. The setting can be found
 diff --git a/chrome/browser/signin/account_consistency_mode_manager.cc b/chrome/browser/signin/account_consistency_mode_manager.cc
 --- a/chrome/browser/signin/account_consistency_mode_manager.cc
 +++ b/chrome/browser/signin/account_consistency_mode_manager.cc
-@@ -127,7 +127,7 @@ void AccountConsistencyModeManager::RegisterProfilePrefs(
- #if BUILDFLAG(ENABLE_DICE_SUPPORT)
-   registry->RegisterBooleanPref(kDiceMigrationCompletePref, false);
- #endif
+@@ -113,7 +113,7 @@ AccountConsistencyModeManager::~AccountConsistencyModeManager() {}
+ // static
+ void AccountConsistencyModeManager::RegisterProfilePrefs(
+     user_prefs::PrefRegistrySyncable* registry) {
 -  registry->RegisterBooleanPref(prefs::kSigninAllowedOnNextStartup, true);
 +  registry->RegisterBooleanPref(prefs::kSigninAllowedOnNextStartup, false);
  }

+ 1 - 1
build/patches/Always-allow-partner-customisation.patch

@@ -9,7 +9,7 @@ Subject: Always allow partner customisation
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java b/chrome/android/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java
-@@ -324,14 +324,14 @@ public class PartnerBrowserCustomizations {
+@@ -329,14 +329,14 @@ public class PartnerBrowserCustomizations {
              @Override
              protected Void doInBackground() {
                  try {

+ 2 - 2
build/patches/Always-use-new-tab-page-for-default-home-page.patch

@@ -17,9 +17,9 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/homepage/Homepa
 -        if (PartnerBrowserCustomizations.getInstance().isHomepageProviderAvailableAndEnabled()) {
 -            return PartnerBrowserCustomizations.getInstance().getHomePageUrl();
 -        }
-         return UrlConstants.NTP_NON_NATIVE_URL;
-     }
  
+         String homepagePartnerDefaultUri = SharedPreferencesManager.getInstance().readString(
+                 ChromePreferenceKeys.HOMEPAGE_PARTNER_CUSTOMIZED_DEFAULT_URI, "");
 -- 
 2.20.1
 

+ 3 - 3
build/patches/Ask-user-before-close-all-tabs.patch → build/patches/Ask-user-before-closing-all-tabs.patch

@@ -1,6 +1,6 @@
 From: uazo <uazo@users.noreply.github.com>
 Date: Sat, 20 Nov 2021 17:42:41 +0000
-Subject: Ask user before close all tabs
+Subject: Ask user before closing all tabs
 
 ---
  .../chrome/browser/ChromeTabbedActivity.java  | 20 +++++++++++++++++--
@@ -18,7 +18,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedAct
  
  import org.chromium.base.CallbackController;
  import org.chromium.base.CommandLine;
-@@ -2040,8 +2041,23 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
+@@ -2044,8 +2045,23 @@ public class ChromeTabbedActivity extends ChromeActivity<ChromeActivityComponent
              ApplicationLifetime.terminate(false);
          } else if (id == R.id.close_all_tabs_menu_id) {
              // Close both incognito and normal tabs
@@ -47,7 +47,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedAct
 diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
 +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
-@@ -3333,6 +3333,9 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
+@@ -3303,6 +3303,9 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
        <message name="IDS_MENU_CLOSE_ALL_TABS" desc="Menu item for closing all open tabs. [CHAR_LIMIT=27]">
          Close all tabs
        </message>

+ 1 - 1
build/patches/AudioBuffer-AnalyserNode-fp-mitigations.patch

@@ -46,7 +46,7 @@ diff --git a/third_party/blink/renderer/modules/webaudio/audio_buffer.idl b/thir
 diff --git a/third_party/blink/renderer/modules/webaudio/audio_context.cc b/third_party/blink/renderer/modules/webaudio/audio_context.cc
 --- a/third_party/blink/renderer/modules/webaudio/audio_context.cc
 +++ b/third_party/blink/renderer/modules/webaudio/audio_context.cc
-@@ -458,7 +458,9 @@ double AudioContext::baseLatency() const {
+@@ -457,7 +457,9 @@ double AudioContext::baseLatency() const {
    DCHECK(IsMainThread());
    DCHECK(destination());
  

File diff suppressed because it is too large
+ 153 - 112
build/patches/Automated-domain-substitution.patch


+ 3 - 3
build/patches/Block-gateway-attacks-via-websockets.patch

@@ -28,7 +28,7 @@ diff --git a/third_party/blink/renderer/core/loader/base_fetch_context.h b/third
 diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.cc b/third_party/blink/renderer/core/loader/frame_fetch_context.cc
 --- a/third_party/blink/renderer/core/loader/frame_fetch_context.cc
 +++ b/third_party/blink/renderer/core/loader/frame_fetch_context.cc
-@@ -579,6 +579,24 @@ bool FrameFetchContext::ShouldBlockRequestByInspector(const KURL& url) const {
+@@ -566,6 +566,24 @@ bool FrameFetchContext::ShouldBlockRequestByInspector(const KURL& url) const {
    return should_block_request;
  }
  
@@ -56,7 +56,7 @@ diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.cc b/thi
 diff --git a/third_party/blink/renderer/core/loader/frame_fetch_context.h b/third_party/blink/renderer/core/loader/frame_fetch_context.h
 --- a/third_party/blink/renderer/core/loader/frame_fetch_context.h
 +++ b/third_party/blink/renderer/core/loader/frame_fetch_context.h
-@@ -165,6 +165,7 @@ class CORE_EXPORT FrameFetchContext final : public BaseFetchContext,
+@@ -166,6 +166,7 @@ class CORE_EXPORT FrameFetchContext final : public BaseFetchContext,
    bool ShouldBlockWebSocketByMixedContentCheck(const KURL&) const override;
    std::unique_ptr<WebSocketHandshakeThrottle> CreateWebSocketHandshakeThrottle()
        override;
@@ -197,7 +197,7 @@ diff --git a/third_party/blink/renderer/modules/websockets/websocket_common.h b/
  #include "third_party/blink/renderer/modules/modules_export.h"
  #include "third_party/blink/renderer/platform/weborigin/kurl.h"
  #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-@@ -51,6 +53,8 @@ class MODULES_EXPORT WebSocketCommon {
+@@ -55,6 +57,8 @@ class MODULES_EXPORT WebSocketCommon {
    void SetState(State state) { state_ = state; }
    const KURL& Url() const { return url_; }
  

+ 5 - 5
build/patches/Block-qjz9zk-or-trk-requests.patch

@@ -61,7 +61,7 @@ diff --git a/chrome/browser/ui/singleton_tabs.cc b/chrome/browser/ui/singleton_t
 diff --git a/components/omnibox/browser/autocomplete_input.cc b/components/omnibox/browser/autocomplete_input.cc
 --- a/components/omnibox/browser/autocomplete_input.cc
 +++ b/components/omnibox/browser/autocomplete_input.cc
-@@ -81,10 +81,15 @@ void OffsetComponentsExcludingScheme(url::Parsed* parts, int offset) {
+@@ -82,10 +82,15 @@ void OffsetComponentsExcludingScheme(url::Parsed* parts, int offset) {
  bool HasScheme(const std::u16string& input, const char* scheme) {
    std::string utf8_input(base::UTF16ToUTF8(input));
    url::Component view_source_scheme;
@@ -77,7 +77,7 @@ diff --git a/components/omnibox/browser/autocomplete_input.cc b/components/omnib
    return url::FindAndCompareScheme(utf8_input, scheme, nullptr);
  }
  
-@@ -532,7 +537,8 @@ void AutocompleteInput::ParseForEmphasizeComponents(
+@@ -533,7 +538,8 @@ void AutocompleteInput::ParseForEmphasizeComponents(
    // For the view-source and blob schemes, we should emphasize the host of the
    // URL qualified by the view-source or blob prefix.
    if ((base::LowerCaseEqualsASCII(scheme_str, kViewSourceScheme) ||
@@ -104,7 +104,7 @@ diff --git a/components/url_formatter/url_fixer.cc b/components/url_formatter/ur
 diff --git a/content/browser/child_process_security_policy_impl.cc b/content/browser/child_process_security_policy_impl.cc
 --- a/content/browser/child_process_security_policy_impl.cc
 +++ b/content/browser/child_process_security_policy_impl.cc
-@@ -821,6 +821,7 @@ ChildProcessSecurityPolicyImpl::ChildProcessSecurityPolicyImpl()
+@@ -861,6 +861,7 @@ ChildProcessSecurityPolicyImpl::ChildProcessSecurityPolicyImpl()
  #endif  // BUILDFLAG(ENABLE_WEBSOCKETS)
    RegisterWebSafeScheme(url::kFtpScheme);
    RegisterWebSafeScheme(url::kDataScheme);
@@ -115,7 +115,7 @@ diff --git a/content/browser/child_process_security_policy_impl.cc b/content/bro
 diff --git a/net/BUILD.gn b/net/BUILD.gn
 --- a/net/BUILD.gn
 +++ b/net/BUILD.gn
-@@ -1037,6 +1037,8 @@ component("net") {
+@@ -1039,6 +1039,8 @@ component("net") {
      "url_request/url_request_http_job.cc",
      "url_request/url_request_http_job.h",
      "url_request/url_request_interceptor.cc",
@@ -209,7 +209,7 @@ diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc
  
  using base::Time;
  using std::string;
-@@ -584,6 +586,12 @@ URLRequest::URLRequest(const GURL& url,
+@@ -595,6 +597,12 @@ URLRequest::URLRequest(const GURL& url,
    // Sanity check out environment.
    DCHECK(base::ThreadTaskRunnerHandle::IsSet());
  

+ 35 - 35
build/patches/Bromite-AdBlockUpdaterService.patch

@@ -59,7 +59,7 @@ Fix RestoreForeignSessionTab by recreating the tab (issue #681)
 diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni
 --- a/chrome/android/chrome_java_resources.gni
 +++ b/chrome/android/chrome_java_resources.gni
-@@ -564,6 +564,7 @@ chrome_java_resources = [
+@@ -557,6 +557,7 @@ chrome_java_resources = [
    "java/res/layout/account_chooser_dialog_title.xml",
    "java/res/layout/account_divider_preference.xml",
    "java/res/layout/account_management_account_row.xml",
@@ -67,7 +67,7 @@ diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_ja
    "java/res/layout/auto_sign_in_first_run_dialog.xml",
    "java/res/layout/autofill_billing_address_dropdown.xml",
    "java/res/layout/autofill_card_unmask_prompt.xml",
-@@ -776,6 +777,7 @@ chrome_java_resources = [
+@@ -774,6 +775,7 @@ chrome_java_resources = [
    "java/res/xml/about_chrome_preferences.xml",
    "java/res/xml/accessibility_preferences.xml",
    "java/res/xml/account_management_preferences.xml",
@@ -78,9 +78,9 @@ diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_ja
 diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
 --- a/chrome/android/chrome_java_sources.gni
 +++ b/chrome/android/chrome_java_sources.gni
-@@ -990,6 +990,8 @@ chrome_java_sources = [
-   "java/src/org/chromium/chrome/browser/payments/ui/ShoppingCart.java",
+@@ -986,6 +986,8 @@ chrome_java_sources = [
    "java/src/org/chromium/chrome/browser/permissions/PermissionSettingsBridge.java",
+   "java/src/org/chromium/chrome/browser/permissions/PermissionUpdateRequester.java",
    "java/src/org/chromium/chrome/browser/photo_picker/DecoderServiceImpl.java",
 +  "java/src/org/chromium/chrome/browser/settings/AdBlockEditor.java",
 +  "java/src/org/chromium/chrome/browser/settings/AdBlockPreferences.java",
@@ -162,7 +162,7 @@ new file mode 100644
 diff --git a/chrome/android/java/res/values/styles.xml b/chrome/android/java/res/values/styles.xml
 --- a/chrome/android/java/res/values/styles.xml
 +++ b/chrome/android/java/res/values/styles.xml
-@@ -199,6 +199,24 @@
+@@ -198,6 +198,24 @@
          </item>
      </style>
  
@@ -422,7 +422,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabMod
 diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
 --- a/chrome/app/generated_resources.grd
 +++ b/chrome/app/generated_resources.grd
-@@ -10853,6 +10853,16 @@ Please help our engineers fix this problem. Tell us what happened right before y
+@@ -11012,6 +11012,16 @@ Please help our engineers fix this problem. Tell us what happened right before y
        Never show this again.
      </message>
  
@@ -483,7 +483,7 @@ diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h
  namespace extensions {
  class EventRouterForwarder;
  }
-@@ -238,6 +243,7 @@ class BrowserProcess {
+@@ -242,6 +247,7 @@ class BrowserProcess {
  #endif
  
    virtual component_updater::ComponentUpdateService* component_updater() = 0;
@@ -494,7 +494,7 @@ diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h
 diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
 --- a/chrome/browser/browser_process_impl.cc
 +++ b/chrome/browser/browser_process_impl.cc
-@@ -1070,6 +1070,26 @@ BrowserProcessImpl::component_updater() {
+@@ -1075,6 +1075,26 @@ BrowserProcessImpl::component_updater() {
    return component_updater_.get();
  }
  
@@ -524,7 +524,7 @@ diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_pro
 diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h
 --- a/chrome/browser/browser_process_impl.h
 +++ b/chrome/browser/browser_process_impl.h
-@@ -200,6 +200,7 @@ class BrowserProcessImpl : public BrowserProcess,
+@@ -204,6 +204,7 @@ class BrowserProcessImpl : public BrowserProcess,
  #endif
  
    component_updater::ComponentUpdateService* component_updater() override;
@@ -532,7 +532,7 @@ diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_proc
    MediaFileSystemRegistry* media_file_system_registry() override;
    WebRtcLogUploader* webrtc_log_uploader() override;
    network_time::NetworkTimeTracker* network_time_tracker() override;
-@@ -386,6 +387,7 @@ class BrowserProcessImpl : public BrowserProcess,
+@@ -390,6 +391,7 @@ class BrowserProcessImpl : public BrowserProcess,
    // to concerns over integrity of data shared between profiles,
    // but some users of component updater only install per-user.
    std::unique_ptr<component_updater::ComponentUpdateService> component_updater_;
@@ -543,7 +543,7 @@ diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_proc
 diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
 --- a/chrome/browser/chrome_browser_main.cc
 +++ b/chrome/browser/chrome_browser_main.cc
-@@ -1649,6 +1649,8 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
+@@ -1653,6 +1653,8 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
      speech::SodaInstaller::GetInstance()->Init(profile_->GetPrefs(),
                                                 browser_process_->local_state());
  #endif  // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
@@ -555,7 +555,7 @@ diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_brows
 diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
 --- a/chrome/browser/chrome_content_browser_client.cc
 +++ b/chrome/browser/chrome_content_browser_client.cc
-@@ -61,7 +61,6 @@
+@@ -62,7 +62,6 @@
  #include "chrome/browser/hid/chrome_hid_delegate.h"
  #include "chrome/browser/interstitials/enterprise_util.h"
  #include "chrome/browser/lifetime/browser_shutdown.h"
@@ -563,7 +563,7 @@ diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/ch
  #include "chrome/browser/media/audio_service_util.h"
  #include "chrome/browser/media/router/media_router_feature.h"
  #include "chrome/browser/media/webrtc/audio_debug_recordings_handler.h"
-@@ -3916,16 +3915,6 @@ ChromeContentBrowserClient::CreateThrottlesForNavigation(
+@@ -4091,16 +4090,6 @@ ChromeContentBrowserClient::CreateThrottlesForNavigation(
      content::NavigationHandle* handle) {
    std::vector<std::unique_ptr<content::NavigationThrottle>> throttles;
  
@@ -580,7 +580,7 @@ diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/ch
  #if BUILDFLAG(IS_CHROMEOS_ASH)
    MaybeAddThrottle(
        ash::WebTimeLimitNavigationThrottle::MaybeCreateThrottleFor(handle),
-@@ -4027,10 +4016,6 @@ ChromeContentBrowserClient::CreateThrottlesForNavigation(
+@@ -4198,10 +4187,6 @@ ChromeContentBrowserClient::CreateThrottlesForNavigation(
                     &throttles);
  #endif
  
@@ -619,7 +619,7 @@ diff --git a/chrome/browser/flags/android/cached_feature_flags.cc b/chrome/brows
 diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
 +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
-@@ -264,6 +264,14 @@ public class CachedFeatureFlags {
+@@ -267,6 +267,14 @@ public class CachedFeatureFlags {
                  ChromeFeatureList.isEnabled(ChromeFeatureList.BACKGROUND_THREAD_POOL));
      }
  
@@ -634,7 +634,7 @@ diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/f
      /**
       * Caches flags that must take effect on startup but are set via native code.
       */
-@@ -469,5 +477,7 @@ public class CachedFeatureFlags {
+@@ -472,5 +480,7 @@ public class CachedFeatureFlags {
      @NativeMethods
      interface Natives {
          boolean isNetworkServiceWarmUpEnabled();
@@ -645,7 +645,7 @@ diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/f
 diff --git a/chrome/browser/net/system_network_context_manager.cc b/chrome/browser/net/system_network_context_manager.cc
 --- a/chrome/browser/net/system_network_context_manager.cc
 +++ b/chrome/browser/net/system_network_context_manager.cc
-@@ -348,6 +348,8 @@ SystemNetworkContextManager::SystemNetworkContextManager(
+@@ -351,6 +351,8 @@ SystemNetworkContextManager::SystemNetworkContextManager(
            SSLConfigServiceManager::CreateDefaultManager(local_state_)),
        proxy_config_monitor_(local_state_),
        stub_resolver_config_reader_(local_state_) {
@@ -654,7 +654,7 @@ diff --git a/chrome/browser/net/system_network_context_manager.cc b/chrome/brows
  #if !defined(OS_ANDROID)
    // QuicAllowed was not part of Android policy.
    const base::Value* value =
-@@ -418,6 +420,8 @@ SystemNetworkContextManager::~SystemNetworkContextManager() {
+@@ -421,6 +423,8 @@ SystemNetworkContextManager::~SystemNetworkContextManager() {
  void SystemNetworkContextManager::RegisterPrefs(PrefRegistrySimple* registry) {
    StubResolverConfigReader::RegisterPrefs(registry);
  
@@ -704,7 +704,7 @@ diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chro
 diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
 --- a/chrome/common/pref_names.cc
 +++ b/chrome/common/pref_names.cc
-@@ -2194,6 +2194,9 @@ const char kAudioCaptureAllowed[] = "hardware.audio_capture_enabled";
+@@ -2221,6 +2221,9 @@ const char kAudioCaptureAllowed[] = "hardware.audio_capture_enabled";
  // capture devices without prompt.
  const char kAudioCaptureAllowedUrls[] = "hardware.audio_capture_allowed_urls";
  
@@ -1528,7 +1528,7 @@ diff --git a/components/subresource_filter/content/browser/ruleset_service.cc b/
  }
  
  // Implements operations on a `sentinel file`, which is used as a safeguard to
-@@ -228,10 +226,13 @@ RulesetService::RulesetService(
+@@ -229,10 +227,13 @@ RulesetService::RulesetService(
  RulesetService::~RulesetService() {}
  
  void RulesetService::IndexAndStoreAndPublishRulesetIfNeeded(
@@ -1544,7 +1544,7 @@ diff --git a/components/subresource_filter/content/browser/ruleset_service.cc b/
    // Trying to store a ruleset with the same version for a second time would
    // not only be futile, but would fail on Windows due to "File System
    // Tunneling" as long as the previously stored copy of the rules is still
-@@ -241,13 +242,16 @@ void RulesetService::IndexAndStoreAndPublishRulesetIfNeeded(
+@@ -242,13 +243,16 @@ void RulesetService::IndexAndStoreAndPublishRulesetIfNeeded(
    if (most_recently_indexed_version.IsCurrentFormatVersion() &&
        most_recently_indexed_version.content_version ==
            unindexed_ruleset_info.content_version) {
@@ -1561,7 +1561,7 @@ diff --git a/components/subresource_filter/content/browser/ruleset_service.cc b/
      return;
    }
  
-@@ -266,6 +270,18 @@ IndexedRulesetVersion RulesetService::GetMostRecentlyIndexedVersion() const {
+@@ -267,6 +271,18 @@ IndexedRulesetVersion RulesetService::GetMostRecentlyIndexedVersion() const {
  IndexedRulesetVersion RulesetService::IndexAndWriteRuleset(
      const base::FilePath& indexed_ruleset_base_dir,
      const UnindexedRulesetInfo& unindexed_ruleset_info) {
@@ -1580,7 +1580,7 @@ diff --git a/components/subresource_filter/content/browser/ruleset_service.cc b/
    base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                  base::BlockingType::MAY_BLOCK);
  
-@@ -273,6 +289,7 @@ IndexedRulesetVersion RulesetService::IndexAndWriteRuleset(
+@@ -274,6 +290,7 @@ IndexedRulesetVersion RulesetService::IndexAndWriteRuleset(
        unindexed_ruleset_info);
  
    if (!unindexed_ruleset_stream_generator.ruleset_stream()) {
@@ -1588,7 +1588,7 @@ diff --git a/components/subresource_filter/content/browser/ruleset_service.cc b/
      RecordIndexAndWriteRulesetResult(
          IndexAndWriteRulesetResult::FAILED_OPENING_UNINDEXED_RULESET);
      return IndexedRulesetVersion();
-@@ -286,6 +303,7 @@ IndexedRulesetVersion RulesetService::IndexAndWriteRuleset(
+@@ -287,6 +304,7 @@ IndexedRulesetVersion RulesetService::IndexAndWriteRuleset(
            indexed_ruleset_base_dir, indexed_version);
  
    if (!base::CreateDirectory(indexed_ruleset_version_dir)) {
@@ -1596,7 +1596,7 @@ diff --git a/components/subresource_filter/content/browser/ruleset_service.cc b/
      RecordIndexAndWriteRulesetResult(
          IndexAndWriteRulesetResult::FAILED_CREATING_VERSION_DIR);
      return IndexedRulesetVersion();
-@@ -311,6 +329,7 @@ IndexedRulesetVersion RulesetService::IndexAndWriteRuleset(
+@@ -312,6 +330,7 @@ IndexedRulesetVersion RulesetService::IndexAndWriteRuleset(
  
    RulesetIndexer indexer;
    if (!(*g_index_ruleset_func)(&unindexed_ruleset_stream_generator, &indexer)) {
@@ -1604,7 +1604,7 @@ diff --git a/components/subresource_filter/content/browser/ruleset_service.cc b/
      RecordIndexAndWriteRulesetResult(
          IndexAndWriteRulesetResult::FAILED_PARSING_UNINDEXED_RULESET);
      return IndexedRulesetVersion();
-@@ -331,6 +350,8 @@ IndexedRulesetVersion RulesetService::IndexAndWriteRuleset(
+@@ -332,6 +351,8 @@ IndexedRulesetVersion RulesetService::IndexAndWriteRuleset(
    if (result != IndexAndWriteRulesetResult::SUCCESS)
      return IndexedRulesetVersion();
  
@@ -1613,7 +1613,7 @@ diff --git a/components/subresource_filter/content/browser/ruleset_service.cc b/
    DCHECK(indexed_version.IsValid());
    return indexed_version;
  }
-@@ -455,6 +476,7 @@ void RulesetService::IndexAndStoreRuleset(
+@@ -456,6 +477,7 @@ void RulesetService::IndexAndStoreRuleset(
  void RulesetService::OnWrittenRuleset(WriteRulesetCallback result_callback,
                                        const IndexedRulesetVersion& version) {
    DCHECK(!result_callback.is_null());
@@ -1621,7 +1621,7 @@ diff --git a/components/subresource_filter/content/browser/ruleset_service.cc b/
    if (!version.IsValid())
      return;
    version.SaveToPrefs(local_state_);
-@@ -467,7 +489,6 @@ void RulesetService::OpenAndPublishRuleset(
+@@ -468,7 +490,6 @@ void RulesetService::OpenAndPublishRuleset(
        IndexedRulesetLocator::GetRulesetDataFilePath(
            IndexedRulesetLocator::GetSubdirectoryPathForVersion(
                indexed_ruleset_base_dir_, version));
@@ -1632,7 +1632,7 @@ diff --git a/components/subresource_filter/content/browser/ruleset_service.cc b/
 diff --git a/components/subresource_filter/content/browser/ruleset_service.h b/components/subresource_filter/content/browser/ruleset_service.h
 --- a/components/subresource_filter/content/browser/ruleset_service.h
 +++ b/components/subresource_filter/content/browser/ruleset_service.h
-@@ -180,7 +180,7 @@ class RulesetService : public base::SupportsWeakPtr<RulesetService> {
+@@ -184,7 +184,7 @@ class RulesetService : public base::SupportsWeakPtr<RulesetService> {
    //
    // Virtual so that it can be mocked out in tests.
    virtual void IndexAndStoreAndPublishRulesetIfNeeded(
@@ -1641,7 +1641,7 @@ diff --git a/components/subresource_filter/content/browser/ruleset_service.h b/c
  
    // Get the ruleset version associated with the current local_state_.
    IndexedRulesetVersion GetMostRecentlyIndexedVersion() const;
-@@ -213,6 +213,11 @@ class RulesetService : public base::SupportsWeakPtr<RulesetService> {
+@@ -217,6 +217,11 @@ class RulesetService : public base::SupportsWeakPtr<RulesetService> {
        const base::FilePath& indexed_ruleset_base_dir,
        const UnindexedRulesetInfo& unindexed_ruleset_info);
  
@@ -1691,8 +1691,8 @@ diff --git a/components/subresource_filter/content/browser/verified_ruleset_deal
 diff --git a/components/subresource_filter/core/browser/subresource_filter_features.cc b/components/subresource_filter/core/browser/subresource_filter_features.cc
 --- a/components/subresource_filter/core/browser/subresource_filter_features.cc
 +++ b/components/subresource_filter/core/browser/subresource_filter_features.cc
-@@ -54,69 +54,7 @@ class CommaSeparatedStrings {
-   DISALLOW_COPY_AND_ASSIGN(CommaSeparatedStrings);
+@@ -55,69 +55,7 @@ class CommaSeparatedStrings {
+   const std::vector<base::StringPiece> pieces_;
  };
  
 -std::string TakeVariationParamOrReturnEmpty(
@@ -1762,7 +1762,7 @@ diff --git a/components/subresource_filter/core/browser/subresource_filter_featu
    // If ad tagging is enabled, turn on the dryrun automatically.
    bool ad_tagging_enabled = base::FeatureList::IsEnabled(kAdTagging);
    const struct {
-@@ -124,23 +62,16 @@ std::vector<Configuration> FillEnabledPresetConfigurations(
+@@ -125,23 +63,16 @@ std::vector<Configuration> FillEnabledPresetConfigurations(
      bool enabled_by_default;
      Configuration (*factory_method)();
    } kAvailablePresetConfigurations[] = {
@@ -1788,7 +1788,7 @@ diff --git a/components/subresource_filter/core/browser/subresource_filter_featu
        enabled_configurations.push_back(available_preset.factory_method());
      }
    }
-@@ -148,46 +79,10 @@ std::vector<Configuration> FillEnabledPresetConfigurations(
+@@ -149,46 +80,10 @@ std::vector<Configuration> FillEnabledPresetConfigurations(
    return enabled_configurations;
  }
  
@@ -1862,7 +1862,7 @@ diff --git a/components/subresource_filter/core/common/indexed_ruleset.cc b/comp
 diff --git a/content/browser/renderer_host/navigation_throttle_runner.cc b/content/browser/renderer_host/navigation_throttle_runner.cc
 --- a/content/browser/renderer_host/navigation_throttle_runner.cc
 +++ b/content/browser/renderer_host/navigation_throttle_runner.cc
-@@ -180,11 +180,6 @@ void NavigationThrottleRunner::RegisterNavigationThrottles() {
+@@ -184,11 +184,6 @@ void NavigationThrottleRunner::RegisterNavigationThrottles() {
    // than other throttles that might care about those navigations, e.g.
    // throttles handling pages with 407 errors that require extra authentication.
    AddThrottle(HttpErrorNavigationThrottle::MaybeCreateThrottleFor(*request));

+ 10 - 10
build/patches/Bromite-auto-updater.patch

@@ -41,7 +41,7 @@ diff --git a/build/android/java/templates/BuildConfig.template b/build/android/j
 diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
 --- a/build/config/android/rules.gni
 +++ b/build/config/android/rules.gni
-@@ -1967,6 +1967,9 @@ if (enable_java_templates) {
+@@ -1970,6 +1970,9 @@ if (enable_java_templates) {
            ]
          }
        }
@@ -54,7 +54,7 @@ diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
 diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
 --- a/chrome/android/chrome_java_sources.gni
 +++ b/chrome/android/chrome_java_sources.gni
-@@ -886,6 +886,7 @@ chrome_java_sources = [
+@@ -892,6 +892,7 @@ chrome_java_sources = [
    "java/src/org/chromium/chrome/browser/omaha/inline/InlineUpdateController.java",
    "java/src/org/chromium/chrome/browser/omaha/inline/InlineUpdateControllerFactory.java",
    "java/src/org/chromium/chrome/browser/omaha/inline/NoopInlineUpdateController.java",
@@ -591,7 +591,7 @@ diff --git a/chrome/browser/endpoint_fetcher/endpoint_fetcher.cc b/chrome/browse
  EndpointFetcher::~EndpointFetcher() = default;
  
  void EndpointFetcher::Fetch(EndpointFetcherCallback endpoint_fetcher_callback) {
-@@ -293,6 +311,77 @@ std::string EndpointFetcher::GetUrlForTesting() {
+@@ -292,6 +310,77 @@ std::string EndpointFetcher::GetUrlForTesting() {
    return url_.spec();
  }
  
@@ -669,7 +669,7 @@ diff --git a/chrome/browser/endpoint_fetcher/endpoint_fetcher.cc b/chrome/browse
  #if defined(OS_ANDROID)
  namespace {
  static void OnEndpointFetcherComplete(
-@@ -309,6 +398,25 @@ static void OnEndpointFetcherComplete(
+@@ -308,6 +397,25 @@ static void OnEndpointFetcherComplete(
                         base::android::AttachCurrentThread(),
                         std::move(endpoint_response->response))));
  }
@@ -695,7 +695,7 @@ diff --git a/chrome/browser/endpoint_fetcher/endpoint_fetcher.cc b/chrome/browse
  }  // namespace
  
  // TODO(crbug.com/1077537) Create a KeyProvider so
-@@ -398,4 +506,25 @@ static void JNI_EndpointFetcher_NativeFetchWithNoAuth(
+@@ -397,4 +505,25 @@ static void JNI_EndpointFetcher_NativeFetchWithNoAuth(
        nullptr);
  }
  
@@ -862,7 +862,7 @@ new file mode 100644
 diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
 --- a/chrome/browser/flag-metadata.json
 +++ b/chrome/browser/flag-metadata.json
-@@ -2121,7 +2121,7 @@
+@@ -2079,7 +2079,7 @@
    {
      "name": "enable-inline-update-flow",
      "owners": [ "nyquist", "dtrainor" ],
@@ -874,7 +874,7 @@ diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.js
 diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
 --- a/chrome/browser/flag_descriptions.cc
 +++ b/chrome/browser/flag_descriptions.cc
-@@ -3657,10 +3657,9 @@ const char kVoiceButtonInTopToolbarDescription[] =
+@@ -3697,10 +3697,9 @@ const char kVoiceButtonInTopToolbarDescription[] =
      "Enables showing the voice search button in the top toolbar. Enabling "
      "Adaptive Button overrides this.";
  
@@ -890,7 +890,7 @@ diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descripti
 diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
 --- a/chrome/browser/flags/android/chrome_feature_list.cc
 +++ b/chrome/browser/flags/android/chrome_feature_list.cc
-@@ -631,7 +631,7 @@ const base::Feature kIncognitoScreenshot{"IncognitoScreenshot",
+@@ -644,7 +644,7 @@ const base::Feature kIncognitoScreenshot{"IncognitoScreenshot",
                                           base::FEATURE_DISABLED_BY_DEFAULT};
  
  const base::Feature kInlineUpdateFlow{"InlineUpdateFlow",
@@ -902,7 +902,7 @@ diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browse
 diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
 +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
-@@ -1703,6 +1703,12 @@ Your Google account may have other forms of browsing history like searches and a
+@@ -1704,6 +1704,12 @@ Your Google account may have other forms of browsing history like searches and a
        <message name="IDS_DEPRECATION_WARNING" desc="Warning about Chrome updates no longer being supported">
          Chrome updates are no longer supported for this version of Android
        </message>
@@ -915,7 +915,7 @@ diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chro
  
        <!-- Account management UI strings. -->
        <message name="IDS_ACCOUNT_MANAGEMENT_TITLE" desc="Header title for the account management screen. [CHAR_LIMIT=32]">
-@@ -3199,7 +3205,7 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
+@@ -3220,7 +3226,7 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
  
        <!-- Main menu items -->
        <message name="IDS_MENU_UPDATE" desc="Menu item for updating chrome. [CHAR_LIMIT=24]">

+ 1 - 1
build/patches/Change-default-webRTC-policy-to-not-use-any-address.patch

@@ -12,7 +12,7 @@ See also: https://github.com/bromite/bromite/issues/553
 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
 --- a/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc
 +++ b/third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.cc
-@@ -663,12 +663,13 @@ PeerConnectionDependencyFactory::CreatePortAllocator(
+@@ -657,12 +657,13 @@ PeerConnectionDependencyFactory::CreatePortAllocator(
            port_config.enable_nonproxied_udp = false;
            break;
          case DEFAULT:

+ 3 - 3
build/patches/Disable-AGSA-by-default.patch

@@ -10,7 +10,7 @@ Subject: Disable AGSA by default
 diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
 --- a/chrome/browser/flags/android/chrome_feature_list.cc
 +++ b/chrome/browser/flags/android/chrome_feature_list.cc
-@@ -609,7 +609,7 @@ const base::Feature kEnhancedProtectionPromoCard{
+@@ -622,7 +622,7 @@ const base::Feature kEnhancedProtectionPromoCard{
      "EnhancedProtectionPromoCard", base::FEATURE_DISABLED_BY_DEFAULT};
  
  const base::Feature kExperimentsForAgsa{"ExperimentsForAgsa",
@@ -22,15 +22,15 @@ diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browse
 diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
 +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
-@@ -85,7 +85,7 @@ public class CachedFeatureFlags {
+@@ -90,7 +90,7 @@ public class CachedFeatureFlags {
                      .put(ChromeFeatureList.CCT_REMOVE_REMOTE_VIEW_IDS, true)
                      .put(ChromeFeatureList.OFFLINE_MEASUREMENTS_BACKGROUND_TASK, false)
                      .put(ChromeFeatureList.CCT_INCOGNITO, true)
 -                    .put(ChromeFeatureList.EXPERIMENTS_FOR_AGSA, true)
 +                    .put(ChromeFeatureList.EXPERIMENTS_FOR_AGSA, false)
                      .put(ChromeFeatureList.APP_MENU_MOBILE_SITE_OPTION, false)
-                     .put(ChromeFeatureList.CLIPBOARD_SUGGESTION_CONTENT_HIDDEN, false)
                      .put(ChromeFeatureList.OPTIMIZATION_GUIDE_PUSH_NOTIFICATIONS, false)
+                     .put(ChromeFeatureList.APP_TO_WEB_ATTRIBUTION, false)
 -- 
 2.20.1
 

+ 1 - 1
build/patches/Disable-Accessibility-service-by-default.patch

@@ -26,7 +26,7 @@ diff --git a/chrome/android/java/res/xml/accessibility_preferences.xml b/chrome/
 diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
 +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
-@@ -1279,6 +1279,12 @@ Your Google account may have other forms of browsing history like searches and a
+@@ -1290,6 +1290,12 @@ Your Google account may have other forms of browsing history like searches and a
        <message name="IDS_PREFS_ACCESSIBILITY" desc="Title of Accessibility settings, which allows the user to change webpage font sizes. [CHAR_LIMIT=32]">
          Accessibility
        </message>

+ 1 - 1
build/patches/Disable-DRM-media-origin-IDs-preprovisioning.patch

@@ -9,7 +9,7 @@ Subject: Disable DRM media origin IDs preprovisioning
 diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
 --- a/media/base/media_switches.cc
 +++ b/media/base/media_switches.cc
-@@ -645,7 +645,7 @@ const base::Feature kMediaDrmPersistentLicense{
+@@ -655,7 +655,7 @@ const base::Feature kMediaDrmPersistentLicense{
  // MediaDrmBridge. If disabled, MediaDrmBridge will get unprovisioned origin IDs
  // which will trigger provisioning process after MediaDrmBridge is created.
  const base::Feature kMediaDrmPreprovisioning{"MediaDrmPreprovisioning",

+ 23 - 24
build/patches/Disable-FLoC.patch

@@ -28,7 +28,7 @@ Also added the disabling of blink features through the DisabledForBromite tag
 diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
 --- a/chrome/browser/chrome_content_browser_client.cc
 +++ b/chrome/browser/chrome_content_browser_client.cc
-@@ -2674,6 +2674,10 @@ bool ChromeContentBrowserClient::IsConversionMeasurementOperationAllowed(
+@@ -2773,6 +2773,10 @@ bool ChromeContentBrowserClient::IsConversionMeasurementOperationAllowed(
      const url::Origin* impression_origin,
      const url::Origin* conversion_origin,
      const url::Origin* reporting_origin) {
@@ -42,7 +42,7 @@ diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/ch
 diff --git a/chrome/browser/component_updater/floc_component_installer.cc b/chrome/browser/component_updater/floc_component_installer.cc
 --- a/chrome/browser/component_updater/floc_component_installer.cc
 +++ b/chrome/browser/component_updater/floc_component_installer.cc
-@@ -18,7 +18,7 @@ namespace component_updater {
+@@ -19,7 +19,7 @@ namespace component_updater {
  // The extension id is: cmahhnpholdijhjokonmfdjbfmklppij
  constexpr uint8_t kFlocComponentPublicKeySHA256[32] = {
      0x2c, 0x07, 0x7d, 0xf7, 0xeb, 0x38, 0x97, 0x9e, 0xae, 0xdc, 0x53,
@@ -51,9 +51,9 @@ diff --git a/chrome/browser/component_updater/floc_component_installer.cc b/chro
      0x8f, 0x68, 0x3a, 0xf9, 0x21, 0x91, 0x9f, 0xc1, 0x84, 0xa1};
  
  constexpr char kFlocComponentFetcherManifestName[] =
-@@ -55,10 +55,6 @@ void FlocComponentInstallerPolicy::ComponentReady(
+@@ -56,10 +56,6 @@ void FlocComponentInstallerPolicy::ComponentReady(
      const base::FilePath& install_dir,
-     std::unique_ptr<base::DictionaryValue> manifest) {
+     base::Value manifest) {
    DCHECK(!install_dir.empty());
 -
 -  floc_sorting_lsh_clusters_service_->OnSortingLshClustersFileReady(
@@ -62,7 +62,7 @@ diff --git a/chrome/browser/component_updater/floc_component_installer.cc b/chro
  }
  
  // Called during startup and installation before ComponentReady().
-@@ -101,10 +97,6 @@ void RegisterFlocComponent(
+@@ -102,10 +98,6 @@ void RegisterFlocComponent(
      ComponentUpdateService* cus,
      federated_learning::FlocSortingLshClustersService*
          floc_sorting_lsh_clusters_service) {
@@ -135,8 +135,8 @@ diff --git a/chrome/browser/federated_learning/floc_eligibility_observer.cc b/ch
  }
  
  void FlocEligibilityObserver::OnAdResource() {
-@@ -84,17 +43,6 @@ FlocEligibilityObserver::FlocEligibilityObserver(content::RenderFrameHost* rfh)
-     : web_contents_(content::WebContents::FromRenderFrameHost(rfh)) {}
+@@ -85,17 +44,6 @@ FlocEligibilityObserver::FlocEligibilityObserver(content::RenderFrameHost* rfh)
+       web_contents_(content::WebContents::FromRenderFrameHost(rfh)) {}
  
  void FlocEligibilityObserver::OnOptInSignalObserved() {
 -  if (!eligible_commit_ || observed_opt_in_signal_)
@@ -152,7 +152,7 @@ diff --git a/chrome/browser/federated_learning/floc_eligibility_observer.cc b/ch
 -  observed_opt_in_signal_ = true;
  }
  
- RENDER_DOCUMENT_HOST_USER_DATA_KEY_IMPL(FlocEligibilityObserver)
+ RENDER_DOCUMENT_HOST_USER_DATA_KEY_IMPL(FlocEligibilityObserver);
 diff --git a/chrome/browser/federated_learning/floc_id_provider_impl.cc b/chrome/browser/federated_learning/floc_id_provider_impl.cc
 --- a/chrome/browser/federated_learning/floc_id_provider_impl.cc
 +++ b/chrome/browser/federated_learning/floc_id_provider_impl.cc
@@ -171,7 +171,7 @@ diff --git a/chrome/browser/federated_learning/floc_id_provider_impl.cc b/chrome
 diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc b/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc
 --- a/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc
 +++ b/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc
-@@ -182,6 +182,9 @@ PrivacySandboxSettings::PrivacySandboxSettings(
+@@ -181,6 +181,9 @@ PrivacySandboxSettings::PrivacySandboxSettings(
  
    // as default, privacy sandbox is disabled
    pref_service_->SetBoolean(prefs::kPrivacySandboxApisEnabled, false);
@@ -181,7 +181,7 @@ diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc b/chrome
    // On first entering the privacy sandbox experiment, users may have the
    // privacy sandbox disabled (or "reconciled") based on their current cookie
    // settings (e.g. blocking 3P cookies). Depending on the state of the sync
-@@ -301,7 +304,8 @@ bool PrivacySandboxSettings::IsFlocPrefEnabled() const {
+@@ -300,7 +303,8 @@ bool PrivacySandboxSettings::IsFlocPrefEnabled() const {
  }
  
  void PrivacySandboxSettings::SetFlocPrefEnabled(bool enabled) const {
@@ -191,7 +191,7 @@ diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc b/chrome
    base::RecordAction(base::UserMetricsAction(
        enabled ? "Settings.PrivacySandbox.FlocEnabled"
                : "Settings.PrivacySandbox.FlocDisabled"));
-@@ -454,6 +458,7 @@ void PrivacySandboxSettings::MaybeReconcilePrivacySandboxPref() {
+@@ -453,6 +457,7 @@ void PrivacySandboxSettings::MaybeReconcilePrivacySandboxPref() {
    // this code could be eliminated in the future, as initially
    // the feauture was tied to the cookies flag
    pref_service_->SetBoolean(prefs::kPrivacySandboxApisEnabled, false);
@@ -199,7 +199,7 @@ diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc b/chrome
    if((true))
      return;
  
-@@ -552,11 +557,8 @@ void PrivacySandboxSettings::ReconcilePrivacySandboxPref() {
+@@ -551,11 +556,8 @@ void PrivacySandboxSettings::ReconcilePrivacySandboxPref() {
  
  void PrivacySandboxSettings::SetFlocDataAccessibleFromNow(
      bool reset_calculate_timer) const {
@@ -232,7 +232,7 @@ diff --git a/components/federated_learning/features/features.cc b/components/fed
  
  // If enabled, pages that had ad resources will be included in floc computation;
  // otherwise, only pages that used the document.interestCohort API will be
-@@ -27,19 +27,19 @@ const base::Feature kFlocIdComputedEventLogging{
+@@ -27,18 +27,18 @@ const base::Feature kFlocIdComputedEventLogging{
  // criteria.
  const base::Feature kFlocPagesWithAdResourcesDefaultIncludedInFlocComputation{
      "FlocPagesWithAdResourcesDefaultIncludedInFlocComputation",
@@ -247,9 +247,8 @@ diff --git a/components/federated_learning/features/features.cc b/components/fed
 -    "FederatedLearningOfCohorts", base::FEATURE_DISABLED_BY_DEFAULT};
 +    "FederatedLearningOfCohorts", base::FEATURE_DISABLED_BY_DEFAULT}; // guard this
  constexpr base::FeatureParam<base::TimeDelta> kFlocIdScheduledUpdateInterval{
-     &kFederatedLearningOfCohorts, "update_interval",
--    base::TimeDelta::FromDays(7)};
-+    base::TimeDelta::FromDays(1)};
+-    &kFederatedLearningOfCohorts, "update_interval", base::Days(7)};
++    &kFederatedLearningOfCohorts, "update_interval", base::Days(1)};
  constexpr base::FeatureParam<int> kFlocIdMinimumHistoryDomainSizeRequired{
 -    &kFederatedLearningOfCohorts, "minimum_history_domain_size_required", 3};
 +    &kFederatedLearningOfCohorts, "minimum_history_domain_size_required", 99999};
@@ -302,7 +301,7 @@ diff --git a/components/federated_learning/floc_id.cc b/components/federated_lea
 diff --git a/components/history/core/browser/history_backend.cc b/components/history/core/browser/history_backend.cc
 --- a/components/history/core/browser/history_backend.cc
 +++ b/components/history/core/browser/history_backend.cc
-@@ -463,18 +463,7 @@ void HistoryBackend::SetFlocAllowed(ContextID context_id,
+@@ -462,18 +462,7 @@ void HistoryBackend::SetFlocAllowed(ContextID context_id,
    if (!visit_id)
      return;
  
@@ -362,7 +361,7 @@ diff --git a/components/history/core/browser/url_row.h b/components/history/core
 diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
 --- a/third_party/blink/common/features.cc
 +++ b/third_party/blink/common/features.cc
-@@ -883,11 +883,11 @@ const base::Feature kDeclarativeShadowDOM{"DeclarativeShadowDOM",
+@@ -883,11 +883,11 @@ const base::Feature kSendCnameAliasesToSubresourceFilterFromRenderer{
  // API exposure will be disabled regardless of the OT config.
  // (See https://github.com/WICG/floc.)
  const base::Feature kInterestCohortAPIOriginTrial{
@@ -374,12 +373,12 @@ diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/fea
 -    "InterestCohortFeaturePolicy", base::FEATURE_DISABLED_BY_DEFAULT};
 +    "InterestCohortFeaturePolicy", base::FEATURE_DISABLED_BY_DEFAULT}; // guard this
  
- // Changes the default background color of the Text Fragment from
- // bright yellow rgb(255, 255, 0) to light purple rgb(233, 210, 253)
+ const base::Feature kDisableDocumentDomainByDefault{
+     "DisableDocumentDomainByDefault", base::FEATURE_DISABLED_BY_DEFAULT};
 diff --git a/third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom b/third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom
 --- a/third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom
 +++ b/third_party/blink/public/mojom/permissions_policy/permissions_policy_feature.mojom
-@@ -126,11 +126,6 @@ enum PermissionsPolicyFeature {
+@@ -125,11 +125,6 @@ enum PermissionsPolicyFeature {
    // Controls access to screen capture via getDisplayMedia().
    kDisplayCapture = 81,
  
@@ -394,7 +393,7 @@ diff --git a/third_party/blink/public/mojom/permissions_policy/permissions_polic
 diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
 --- a/third_party/blink/renderer/core/dom/document.cc
 +++ b/third_party/blink/renderer/core/dom/document.cc
-@@ -6009,8 +6009,7 @@ ScriptPromise Document::interestCohort(ScriptState* script_state,
+@@ -5998,8 +5998,7 @@ ScriptPromise Document::interestCohort(ScriptState* script_state,
      return ScriptPromise();
    }
  
@@ -429,7 +428,7 @@ diff --git a/third_party/blink/renderer/core/dom/interest_cohort.idl b/third_par
 diff --git a/third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5 b/third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5
 --- a/third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5
 +++ b/third_party/blink/renderer/core/permissions_policy/permissions_policy_features.json5
-@@ -256,12 +256,6 @@
+@@ -251,12 +251,6 @@
        permissions_policy_name: "idle-detection",
        depends_on: ["IdleDetection"],
      },
@@ -445,7 +444,7 @@ diff --git a/third_party/blink/renderer/core/permissions_policy/permissions_poli
 diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
-@@ -1216,12 +1216,11 @@
+@@ -1225,12 +1225,11 @@
      },
      {
        name: "InterestCohortAPI",

+ 0 - 54
build/patches/Disable-HEAD-requests-for-single-word-Omnibar-searches.patch

@@ -1,54 +0,0 @@
-From: csagan5 <32685696+csagan5@users.noreply.github.com>
-Date: Sun, 27 Oct 2019 10:21:19 +0100
-Subject: Disable HEAD requests for single-word Omnibar searches
-
-Patch from https://github.com/Eloston/ungoogled-chromium/issues/814#issuecomment-526873727
----
- .../ui/omnibox/chrome_omnibox_navigation_observer.cc      | 8 ++++----
- .../ui/omnibox/chrome_omnibox_navigation_observer.h       | 2 +-
- 2 files changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer.cc b/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer.cc
---- a/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer.cc
-+++ b/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer.cc
-@@ -86,8 +86,8 @@ ChromeOmniboxNavigationObserver::ChromeOmniboxNavigationObserver(
-       shortcuts_backend_(ShortcutsBackendFactory::GetForProfile(profile)),
-       load_state_(LOAD_NOT_SEEN),
-       fetch_state_(FETCH_NOT_COMPLETE) {
--  if (alternate_nav_match_.destination_url.is_valid())
--    CreateLoader(alternate_nav_match_.destination_url);
-+//  if (alternate_nav_match_.destination_url.is_valid())
-+//    CreateLoader(alternate_nav_match_.destination_url);
- 
-   // We need to start by listening to AllSources, since we don't know which tab
-   // the navigation might occur in.
-@@ -291,7 +291,7 @@ void ChromeOmniboxNavigationObserver::OnAllLoadingFinished() {
-   delete this;
- }
- 
--void ChromeOmniboxNavigationObserver::CreateLoader(
-+/*void ChromeOmniboxNavigationObserver::CreateLoader(
-     const GURL& destination_url) {
-   net::NetworkTrafficAnnotationTag traffic_annotation =
-       net::DefineNetworkTrafficAnnotation("omnibox_navigation_observer", R"(
-@@ -336,4 +336,4 @@ void ChromeOmniboxNavigationObserver::CreateLoader(
-   loader_->SetAllowHttpErrorResults(true);
-   loader_->SetOnRedirectCallback(base::BindRepeating(
-       &ChromeOmniboxNavigationObserver::OnURLRedirect, base::Unretained(this)));
--}
-+}*/
-diff --git a/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer.h b/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer.h
---- a/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer.h
-+++ b/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer.h
-@@ -130,7 +130,7 @@ class ChromeOmniboxNavigationObserver : public OmniboxNavigationObserver,
- 
-   // Creates a URL loader for |destination_url| and stores it in |loader_|.
-   // Does not start the loader.
--  void CreateLoader(const GURL& destination_url);
-+  //void CreateLoader(const GURL& destination_url);
- 
-   const std::u16string text_;
-   const AutocompleteMatch match_;
--- 
-2.20.1
-

+ 2 - 2
build/patches/Disable-all-promo-dialogs.patch

@@ -9,7 +9,7 @@ Subject: Disable all promo dialogs
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
-@@ -823,7 +823,7 @@ public class TabbedRootUiCoordinator extends RootUiCoordinator {
+@@ -847,7 +847,7 @@ public class TabbedRootUiCoordinator extends RootUiCoordinator {
       * displayed.
       */
      private boolean triggerPromo(boolean intentWithEffect) {
@@ -18,7 +18,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/Tab
              if (CommandLine.getInstance().hasSwitch(ChromeSwitches.DISABLE_STARTUP_PROMOS)) {
                  return false;
              }
-@@ -858,8 +858,8 @@ public class TabbedRootUiCoordinator extends RootUiCoordinator {
+@@ -882,8 +882,8 @@ public class TabbedRootUiCoordinator extends RootUiCoordinator {
                  preferenceManager.writeBoolean(
                          ChromePreferenceKeys.PROMOS_SKIPPED_ON_FIRST_START, true);
              }

+ 49 - 48
build/patches/Disable-conversion-measurement-api.patch

@@ -14,18 +14,18 @@ being sent and being saved to disk, although it is currently in uncalled code.
  .../embedder_support/origin_trials/features.cc  |  3 ++-
  .../render_view_context_menu_base.cc            |  3 ---
  .../browser/android/navigation_handle_proxy.cc  | 10 ----------
- content/browser/conversions/conversion_host.cc  |  8 --------
- content/browser/conversions/conversion_host.h   |  3 ---
- .../conversions/conversion_host_utils.cc        |  6 ++++++
- .../conversion_network_sender_impl.cc           | 17 ++++++++++-------
- .../conversions/conversion_storage_sql.cc       |  2 +-
- .../navigation_controller_android.cc            | 15 ---------------
+ .../attribution_reporting/attribution_host.cc   |  8 --------
+ .../attribution_reporting/attribution_host.h    |  3 ---
+ .../attribution_host_utils.cc                   |  6 ++++++
+ .../attribution_network_sender_impl.cc          | 17 ++++++++++-------
+ .../attribution_storage_sql.cc                  |  2 +-
+ .../navigation_controller_android.cc            | 16 ----------------
  content/browser/storage_partition_impl.cc       |  7 +------
  .../browser/AttributionReporterImpl.java        |  4 ----
  content/public/browser/navigation_controller.cc |  1 -
  third_party/blink/common/features.cc            |  2 +-
  .../platform/runtime_enabled_features.json5     | 13 +++++++++----
- 17 files changed, 32 insertions(+), 81 deletions(-)
+ 17 files changed, 32 insertions(+), 82 deletions(-)
 
 diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml
 --- a/chrome/android/java/AndroidManifest.xml
@@ -67,7 +67,7 @@ diff --git a/chrome/browser/attribution_reporting/android/internal/java/src/org/
 diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
 --- a/chrome/browser/flags/android/chrome_feature_list.cc
 +++ b/chrome/browser/flags/android/chrome_feature_list.cc
-@@ -416,7 +416,7 @@ const base::Feature kAppMenuMobileSiteOption{"AppMenuMobileSiteOption",
+@@ -426,7 +426,7 @@ const base::Feature kAppMenuMobileSiteOption{"AppMenuMobileSiteOption",
                                               base::FEATURE_DISABLED_BY_DEFAULT};
  
  const base::Feature kAppToWebAttribution{"AppToWebAttribution",
@@ -113,7 +113,7 @@ diff --git a/content/browser/android/navigation_handle_proxy.cc b/content/browse
 -  std::vector<uint8_t> byte_vector;
 -  if (cpp_navigation_handle_->GetImpression()) {
 -    blink::mojom::ImpressionPtr impression =
--        ConversionHost::MojoImpressionFromImpression(
+-        AttributionHost::MojoImpressionFromImpression(
 -            *cpp_navigation_handle_->GetImpression());
 -    byte_vector = blink::mojom::Impression::Serialize(&impression);
 -    impression_byte_buffer = base::android::ScopedJavaLocalRef<jobject>(
@@ -123,15 +123,15 @@ diff --git a/content/browser/android/navigation_handle_proxy.cc b/content/browse
    java_navigation_handle_ = Java_NavigationHandle_Constructor(
        env, reinterpret_cast<jlong>(this),
        url::GURLAndroid::FromNativeGURL(env, cpp_navigation_handle_->GetURL()),
-diff --git a/content/browser/conversions/conversion_host.cc b/content/browser/conversions/conversion_host.cc
---- a/content/browser/conversions/conversion_host.cc
-+++ b/content/browser/conversions/conversion_host.cc
-@@ -400,14 +400,6 @@ void ConversionHost::BindReceiver(
+diff --git a/content/browser/attribution_reporting/attribution_host.cc b/content/browser/attribution_reporting/attribution_host.cc
+--- a/content/browser/attribution_reporting/attribution_host.cc
++++ b/content/browser/attribution_reporting/attribution_host.cc
+@@ -417,14 +417,6 @@ void AttributionHost::BindReceiver(
    conversion_host->receivers_.Bind(rfh, std::move(receiver));
  }
  
 -// static
--blink::mojom::ImpressionPtr ConversionHost::MojoImpressionFromImpression(
+-blink::mojom::ImpressionPtr AttributionHost::MojoImpressionFromImpression(
 -    const blink::Impression& impression) {
 -  return blink::mojom::Impression::New(
 -      impression.conversion_destination, impression.reporting_origin,
@@ -139,12 +139,12 @@ diff --git a/content/browser/conversions/conversion_host.cc b/content/browser/co
 -}
 -
  // static
- void ConversionHost::SetReceiverImplForTesting(ConversionHost* impl) {
+ void AttributionHost::SetReceiverImplForTesting(AttributionHost* impl) {
    g_receiver_for_testing = impl;
-diff --git a/content/browser/conversions/conversion_host.h b/content/browser/conversions/conversion_host.h
---- a/content/browser/conversions/conversion_host.h
-+++ b/content/browser/conversions/conversion_host.h
-@@ -58,9 +58,6 @@ class CONTENT_EXPORT ConversionHost
+diff --git a/content/browser/attribution_reporting/attribution_host.h b/content/browser/attribution_reporting/attribution_host.h
+--- a/content/browser/attribution_reporting/attribution_host.h
++++ b/content/browser/attribution_reporting/attribution_host.h
+@@ -58,9 +58,6 @@ class CONTENT_EXPORT AttributionHost
        const url::Origin& impression_origin,
        const blink::Impression& impression);
  
@@ -152,12 +152,12 @@ diff --git a/content/browser/conversions/conversion_host.h b/content/browser/con
 -      const blink::Impression& impression) WARN_UNUSED_RESULT;
 -
    // Overrides the target object to bind |receiver| to in BindReceiver().
-   static void SetReceiverImplForTesting(ConversionHost* impl);
+   static void SetReceiverImplForTesting(AttributionHost* impl);
  
-diff --git a/content/browser/conversions/conversion_host_utils.cc b/content/browser/conversions/conversion_host_utils.cc
---- a/content/browser/conversions/conversion_host_utils.cc
-+++ b/content/browser/conversions/conversion_host_utils.cc
-@@ -18,6 +18,8 @@
+diff --git a/content/browser/attribution_reporting/attribution_host_utils.cc b/content/browser/attribution_reporting/attribution_host_utils.cc
+--- a/content/browser/attribution_reporting/attribution_host_utils.cc
++++ b/content/browser/attribution_reporting/attribution_host_utils.cc
+@@ -19,6 +19,8 @@
  #include "url/gurl.h"
  #include "url/origin.h"
  
@@ -165,8 +165,8 @@ diff --git a/content/browser/conversions/conversion_host_utils.cc b/content/brow
 +
  namespace content {
  
- namespace conversion_host_utils {
-@@ -77,6 +79,10 @@ absl::optional<blink::Impression> ParseImpressionFromApp(
+ namespace attribution_host_utils {
+@@ -79,6 +81,10 @@ absl::optional<blink::Impression> ParseImpressionFromApp(
    // Java API should have rejected these already.
    DCHECK(!source_event_id.empty() && !destination.empty());
  
@@ -177,10 +177,10 @@ diff --git a/content/browser/conversions/conversion_host_utils.cc b/content/brow
    blink::Impression impression;
    if (!base::StringToUint64(source_event_id, &impression.impression_data))
      return absl::nullopt;
-diff --git a/content/browser/conversions/conversion_network_sender_impl.cc b/content/browser/conversions/conversion_network_sender_impl.cc
---- a/content/browser/conversions/conversion_network_sender_impl.cc
-+++ b/content/browser/conversions/conversion_network_sender_impl.cc
-@@ -144,13 +144,9 @@ void ConversionNetworkSenderImpl::SendReport(ConversionReport report,
+diff --git a/content/browser/attribution_reporting/attribution_network_sender_impl.cc b/content/browser/attribution_reporting/attribution_network_sender_impl.cc
+--- a/content/browser/attribution_reporting/attribution_network_sender_impl.cc
++++ b/content/browser/attribution_reporting/attribution_network_sender_impl.cc
+@@ -146,13 +146,9 @@ void AttributionNetworkSenderImpl::SendReport(
  
    LogMetricsOnReportSend(report);
  
@@ -188,7 +188,7 @@ diff --git a/content/browser/conversions/conversion_network_sender_impl.cc b/con
 -  // deleted before |this|.
 -  simple_url_loader_ptr->DownloadHeadersOnly(
 -      url_loader_factory_.get(),
--      base::BindOnce(&ConversionNetworkSenderImpl::OnReportSent,
+-      base::BindOnce(&AttributionNetworkSenderImpl::OnReportSent,
 -                     base::Unretained(this), std::move(it), std::move(report),
 -                     std::move(sent_callback)));
 +  // this code is never called but if it were, nothing would be sent
@@ -196,9 +196,9 @@ diff --git a/content/browser/conversions/conversion_network_sender_impl.cc b/con
 +    nullptr);
  }
  
- void ConversionNetworkSenderImpl::SetURLLoaderFactoryForTesting(
-@@ -163,6 +159,13 @@ void ConversionNetworkSenderImpl::OnReportSent(
-     ConversionReport report,
+ void AttributionNetworkSenderImpl::SetURLLoaderFactoryForTesting(
+@@ -165,6 +161,13 @@ void AttributionNetworkSenderImpl::OnReportSent(
+     AttributionReport report,
      ReportSentCallback sent_callback,
      scoped_refptr<net::HttpResponseHeaders> headers) {
 +  if ((true)) {
@@ -211,22 +211,22 @@ diff --git a/content/browser/conversions/conversion_network_sender_impl.cc b/con
    network::SimpleURLLoader* loader = it->get();
  
    // Consider a non-200 HTTP code as a non-internal error.
-diff --git a/content/browser/conversions/conversion_storage_sql.cc b/content/browser/conversions/conversion_storage_sql.cc
---- a/content/browser/conversions/conversion_storage_sql.cc
-+++ b/content/browser/conversions/conversion_storage_sql.cc
-@@ -227,7 +227,7 @@ void ConversionStorageSql::RunInMemoryForTesting() {
+diff --git a/content/browser/attribution_reporting/attribution_storage_sql.cc b/content/browser/attribution_reporting/attribution_storage_sql.cc
+--- a/content/browser/attribution_reporting/attribution_storage_sql.cc
++++ b/content/browser/attribution_reporting/attribution_storage_sql.cc
+@@ -239,7 +239,7 @@ void AttributionStorageSql::RunInMemoryForTesting() {
  }
  
  // static
--bool ConversionStorageSql::g_run_in_memory_ = false;
-+bool ConversionStorageSql::g_run_in_memory_ = true; // use in-memory db
+-bool AttributionStorageSql::g_run_in_memory_ = false;
++bool AttributionStorageSql::g_run_in_memory_ = true;
  
- ConversionStorageSql::ConversionStorageSql(
+ AttributionStorageSql::AttributionStorageSql(
      const base::FilePath& path_to_database,
 diff --git a/content/browser/renderer_host/navigation_controller_android.cc b/content/browser/renderer_host/navigation_controller_android.cc
 --- a/content/browser/renderer_host/navigation_controller_android.cc
 +++ b/content/browser/renderer_host/navigation_controller_android.cc
-@@ -316,21 +316,6 @@ void NavigationControllerAndroid::LoadUrl(
+@@ -318,22 +318,6 @@ void NavigationControllerAndroid::LoadUrl(
    if (input_start != 0)
      params.input_start = base::TimeTicks::FromUptimeMillis(input_start);
  
@@ -237,7 +237,7 @@ diff --git a/content/browser/renderer_host/navigation_controller_android.cc b/co
 -    params.initiator_origin = OriginFromAndroidPackageName(
 -        ConvertJavaStringToUTF8(env, source_package_name));
 -
--    params.impression = conversion_host_utils::ParseImpressionFromApp(
+-    params.impression = attribution_host_utils::ParseImpressionFromApp(
 -        ConvertJavaStringToUTF8(env, attribution_source_event_id),
 -        ConvertJavaStringToUTF8(env, attribution_destination),
 -        attribution_report_to
@@ -245,13 +245,14 @@ diff --git a/content/browser/renderer_host/navigation_controller_android.cc b/co
 -            : "",
 -        attribution_expiry);
 -  }
- 
+-
    params.override_user_agent = static_cast<NavigationController::UserAgentOverrideOption>(
      user_agent_override_option);
+ 
 diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
 --- a/content/browser/storage_partition_impl.cc
 +++ b/content/browser/storage_partition_impl.cc
-@@ -1338,12 +1338,7 @@ void StoragePartitionImpl::Initialize(
+@@ -1299,12 +1299,7 @@ void StoragePartitionImpl::Initialize(
    bucket_context_ = base::MakeRefCounted<BucketContext>();
    bucket_context_->Initialize();
  
@@ -263,7 +264,7 @@ diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage
 -  }
 +  // The Conversion Measurement API is not available in Bromite.
  
-   if (base::FeatureList::IsEnabled(blink::features::kFledgeInterestGroups)) {
+   if (base::FeatureList::IsEnabled(blink::features::kInterestGroupStorage)) {
      interest_group_manager_ = std::make_unique<InterestGroupManager>(
 diff --git a/content/public/android/java/src/org/chromium/content/browser/AttributionReporterImpl.java b/content/public/android/java/src/org/chromium/content/browser/AttributionReporterImpl.java
 --- a/content/public/android/java/src/org/chromium/content/browser/AttributionReporterImpl.java
@@ -300,7 +301,7 @@ diff --git a/content/public/browser/navigation_controller.cc b/content/public/br
 diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
 --- a/third_party/blink/common/features.cc
 +++ b/third_party/blink/common/features.cc
-@@ -32,7 +32,7 @@ const base::Feature kCSSContainerQueries{"CSSContainerQueries",
+@@ -37,7 +37,7 @@ const base::Feature kCSSContainerQueries{"CSSContainerQueries",
  
  // Controls whether the Conversion Measurement API infrastructure is enabled.
  const base::Feature kConversionMeasurement{"ConversionMeasurement",
@@ -326,7 +327,7 @@ diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5
      {
        name: "Accelerated2dCanvas",
        settable_from_internals: true,
-@@ -463,13 +470,11 @@
+@@ -474,13 +481,11 @@
      },
      {
        name: "ConversionMeasurement",

+ 1 - 1
build/patches/Disable-feeds-support-by-default.patch

@@ -29,7 +29,7 @@ diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/
 diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
 +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
-@@ -76,7 +76,7 @@ public class CachedFeatureFlags {
+@@ -81,7 +81,7 @@ public class CachedFeatureFlags {
                      .put(ChromeFeatureList.TAB_TO_GTS_ANIMATION, true)
                      .put(ChromeFeatureList.TEST_DEFAULT_DISABLED, false)
                      .put(ChromeFeatureList.TEST_DEFAULT_ENABLED, true)

+ 7 - 7
build/patches/Disable-fetching-of-all-field-trials.patch

@@ -50,7 +50,7 @@ diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/s
 diff --git a/chrome/browser/metrics/chrome_metrics_services_manager_client.cc b/chrome/browser/metrics/chrome_metrics_services_manager_client.cc
 --- a/chrome/browser/metrics/chrome_metrics_services_manager_client.cc
 +++ b/chrome/browser/metrics/chrome_metrics_services_manager_client.cc
-@@ -174,6 +174,8 @@ ChromeMetricsServicesManagerClient::~ChromeMetricsServicesManagerClient() {}
+@@ -186,6 +186,8 @@ ChromeMetricsServicesManagerClient::GetMetricsStateManagerForTesting() {
  void ChromeMetricsServicesManagerClient::CreateFallbackSamplingTrial(
      version_info::Channel channel,
      base::FeatureList* feature_list) {
@@ -147,8 +147,8 @@ diff --git a/components/variations/net/omnibox_http_headers.cc b/components/vari
 diff --git a/components/variations/net/variations_http_headers.cc b/components/variations/net/variations_http_headers.cc
 --- a/components/variations/net/variations_http_headers.cc
 +++ b/components/variations/net/variations_http_headers.cc
-@@ -235,6 +235,9 @@ class VariationsHeaderHelper {
-   }
+@@ -238,6 +238,9 @@ class VariationsHeaderHelper {
+   VariationsHeaderHelper& operator=(const VariationsHeaderHelper&) = delete;
  
    bool AppendHeaderIfNeeded(const GURL& url, InIncognito incognito) {
 +    if((true))
@@ -160,7 +160,7 @@ diff --git a/components/variations/net/variations_http_headers.cc b/components/v
 diff --git a/components/variations/service/variations_field_trial_creator.cc b/components/variations/service/variations_field_trial_creator.cc
 --- a/components/variations/service/variations_field_trial_creator.cc
 +++ b/components/variations/service/variations_field_trial_creator.cc
-@@ -263,8 +263,8 @@ bool VariationsFieldTrialCreator::SetupFieldTrials(
+@@ -271,8 +271,8 @@ bool VariationsFieldTrialCreator::SetupFieldTrials(
    // instance is set.
    feature_list->RegisterExtraFeatureOverrides(extra_overrides);
  
@@ -170,7 +170,7 @@ diff --git a/components/variations/service/variations_field_trial_creator.cc b/c
    if (!command_line->HasSwitch(switches::kDisableFieldTrialTestingConfig) &&
        !command_line->HasSwitch(::switches::kForceFieldTrials) &&
        !command_line->HasSwitch(switches::kVariationsServerURL)) {
-@@ -278,10 +278,12 @@ bool VariationsFieldTrialCreator::SetupFieldTrials(
+@@ -286,10 +286,12 @@ bool VariationsFieldTrialCreator::SetupFieldTrials(
    }
  #endif  // BUILDFLAG(FIELDTRIAL_TESTING_ENABLED)
    bool used_seed = false;
@@ -186,7 +186,7 @@ diff --git a/components/variations/service/variations_field_trial_creator.cc b/c
 diff --git a/components/variations/service/variations_service.cc b/components/variations/service/variations_service.cc
 --- a/components/variations/service/variations_service.cc
 +++ b/components/variations/service/variations_service.cc
-@@ -240,17 +240,8 @@ bool GetInstanceManipulations(const net::HttpResponseHeaders* headers,
+@@ -238,17 +238,8 @@ bool GetInstanceManipulations(const net::HttpResponseHeaders* headers,
  // Variations seed fetching is only enabled in official Chrome builds, if a URL
  // is specified on the command line, and for testing.
  bool IsFetchingEnabled() {
@@ -206,7 +206,7 @@ diff --git a/components/variations/service/variations_service.cc b/components/va
  }
  
  std::unique_ptr<SeedResponse> MaybeImportFirstRunSeed(
-@@ -610,7 +601,7 @@ bool VariationsService::DoFetchFromURL(const GURL& url, bool is_http_retry) {
+@@ -608,7 +599,7 @@ bool VariationsService::DoFetchFromURL(const GURL& url, bool is_http_retry) {
    // debugger or if the machine was suspended) and OnURLFetchComplete() hasn't
    // had a chance to run yet from the previous request. In this case, don't
    // start a new request and just let the previous one finish.

+ 2 - 2
build/patches/Disable-media-router-and-remoting-by-default.patch

@@ -56,7 +56,7 @@ diff --git a/chrome/browser/media/router/media_router_feature.cc b/chrome/browse
 diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc
 --- a/chrome/browser/profiles/profile.cc
 +++ b/chrome/browser/profiles/profile.cc
-@@ -365,7 +365,7 @@ void Profile::RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
+@@ -358,7 +358,7 @@ void Profile::RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
        media_router::prefs::kMediaRouterEnableCloudServices, false,
        user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
    registry->RegisterBooleanPref(
@@ -68,7 +68,7 @@ diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profil
 diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
 --- a/chrome/browser/profiles/profile_impl.cc
 +++ b/chrome/browser/profiles/profile_impl.cc
-@@ -445,7 +445,7 @@ void ProfileImpl::RegisterProfilePrefs(
+@@ -415,7 +415,7 @@ void ProfileImpl::RegisterProfilePrefs(
  #endif
  
    registry->RegisterBooleanPref(prefs::kForceEphemeralProfiles, false);

+ 4 - 4
build/patches/Disable-metrics-collection-for-NTP-tiles.patch

@@ -26,7 +26,7 @@ diff --git a/chrome/browser/android/ntp/most_visited_sites_bridge.cc b/chrome/br
  
  namespace {
  
-@@ -230,7 +228,6 @@ void MostVisitedSitesBridge::RecordPageImpression(
+@@ -232,7 +230,6 @@ void MostVisitedSitesBridge::RecordPageImpression(
      JNIEnv* env,
      const JavaParamRef<jobject>& obj,
      jint jtiles_count) {
@@ -34,7 +34,7 @@ diff --git a/chrome/browser/android/ntp/most_visited_sites_bridge.cc b/chrome/br
  }
  
  void MostVisitedSitesBridge::RecordTileImpression(
-@@ -242,6 +239,7 @@ void MostVisitedSitesBridge::RecordTileImpression(
+@@ -244,6 +241,7 @@ void MostVisitedSitesBridge::RecordTileImpression(
      jint jtitle_source,
      jint jsource,
      const JavaParamRef<jobject>& jurl) {
@@ -42,7 +42,7 @@ diff --git a/chrome/browser/android/ntp/most_visited_sites_bridge.cc b/chrome/br
    std::unique_ptr<GURL> url = url::GURLAndroid::ToNativeGURL(env, jurl);
    TileTitleSource title_source = static_cast<TileTitleSource>(jtitle_source);
    TileSource source = static_cast<TileSource>(jsource);
-@@ -251,6 +249,7 @@ void MostVisitedSitesBridge::RecordTileImpression(
+@@ -253,6 +251,7 @@ void MostVisitedSitesBridge::RecordTileImpression(
  
    ntp_tiles::metrics::RecordTileImpression(ntp_tiles::NTPTileImpression(
        jindex, source, title_source, visual_type, icon_type, *url));
@@ -50,7 +50,7 @@ diff --git a/chrome/browser/android/ntp/most_visited_sites_bridge.cc b/chrome/br
  }
  
  void MostVisitedSitesBridge::RecordOpenedMostVisitedItem(
-@@ -260,11 +259,6 @@ void MostVisitedSitesBridge::RecordOpenedMostVisitedItem(
+@@ -262,11 +261,6 @@ void MostVisitedSitesBridge::RecordOpenedMostVisitedItem(
      jint tile_type,
      jint title_source,
      jint source) {

+ 1 - 1
build/patches/Disable-metrics-on-all-I-O-threads.patch

@@ -9,7 +9,7 @@ Subject: Disable metrics on all I/O threads
 diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
 --- a/chrome/browser/browser_process_impl.cc
 +++ b/chrome/browser/browser_process_impl.cc
-@@ -982,7 +982,7 @@ void BrowserProcessImpl::RegisterPrefs(PrefRegistrySimple* registry) {
+@@ -989,7 +989,7 @@ void BrowserProcessImpl::RegisterPrefs(PrefRegistrySimple* registry) {
  #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
  
    registry->RegisterBooleanPref(metrics::prefs::kMetricsReportingEnabled,

+ 1 - 1
build/patches/Disable-plugins-enumeration.patch

@@ -9,7 +9,7 @@ Subject: Disable plugins enumeration
 diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
 --- a/third_party/blink/renderer/core/frame/local_frame.cc
 +++ b/third_party/blink/renderer/core/frame/local_frame.cc
-@@ -1851,10 +1851,8 @@ WebContentSettingsClient* LocalFrame::GetContentSettingsClient() {
+@@ -1871,10 +1871,8 @@ WebContentSettingsClient* LocalFrame::GetContentSettingsClient() {
  }
  
  PluginData* LocalFrame::GetPluginData() const {

+ 11 - 11
build/patches/Disable-privacy-sandbox.patch

@@ -12,7 +12,7 @@ Remove the ui from the settings and set the flags to inactive
 diff --git a/chrome/android/java/res/xml/privacy_preferences.xml b/chrome/android/java/res/xml/privacy_preferences.xml
 --- a/chrome/android/java/res/xml/privacy_preferences.xml
 +++ b/chrome/android/java/res/xml/privacy_preferences.xml
-@@ -70,10 +70,6 @@
+@@ -75,10 +75,6 @@
          android:title="@string/open_external_links_incognito_title"
          android:summary="@string/open_external_links_incognito_summary"
          android:defaultValue="false" />
@@ -26,15 +26,15 @@ diff --git a/chrome/android/java/res/xml/privacy_preferences.xml b/chrome/androi
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java
-@@ -70,7 +70,6 @@ public class PrivacySettings
+@@ -73,7 +73,6 @@ public class PrivacySettings
      private static final String PREF_SECURE_DNS = "secure_dns";
      private static final String PREF_DO_NOT_TRACK = "do_not_track";
      private static final String PREF_CLEAR_BROWSING_DATA = "clear_browsing_data";
 -    private static final String PREF_PRIVACY_SANDBOX = "privacy_sandbox";
      private static final String PREF_PRIVACY_REVIEW = "privacy_review";
+     private static final String PREF_INCOGNITO_LOCK = "incognito_lock";
  
-     private static final String PREF_CLOSE_TABS_ON_EXIT = "close_tabs_on_exit";
-@@ -100,18 +99,6 @@ public class PrivacySettings
+@@ -104,18 +103,6 @@ public class PrivacySettings
          SettingsUtils.addPreferencesFromResource(this, R.xml.privacy_preferences);
          getActivity().setTitle(R.string.prefs_privacy_security);
  
@@ -50,10 +50,10 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
 -            return true;
 -        });
 -
+         Preference privacyReviewPreference = findPreference(PREF_PRIVACY_REVIEW);
          if (!ChromeFeatureList.isEnabled(ChromeFeatureList.PRIVACY_REVIEW)) {
-             getPreferenceScreen().removePreference(findPreference(PREF_PRIVACY_REVIEW));
-         }
-@@ -292,12 +279,6 @@ public class PrivacySettings
+             getPreferenceScreen().removePreference(privacyReviewPreference);
+@@ -337,12 +324,6 @@ public class PrivacySettings
              secureDnsPref.setSummary(SecureDnsSettings.getSummary(getContext()));
          }
  
@@ -95,7 +95,7 @@ diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc b/chrome
  }
  
  // Returns whether FLoC is allowable by the current state of |pref_service|.
-@@ -195,6 +180,8 @@ PrivacySandboxSettings::PrivacySandboxSettings(
+@@ -194,6 +179,8 @@ PrivacySandboxSettings::PrivacySandboxSettings(
        base::BindRepeating(&PrivacySandboxSettings::OnPrivacySandboxPrefChanged,
                            base::Unretained(this)));
  
@@ -104,7 +104,7 @@ diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc b/chrome
    // On first entering the privacy sandbox experiment, users may have the
    // privacy sandbox disabled (or "reconciled") based on their current cookie
    // settings (e.g. blocking 3P cookies). Depending on the state of the sync
-@@ -393,7 +380,8 @@ bool PrivacySandboxSettings::IsPrivacySandboxManaged() {
+@@ -392,7 +379,8 @@ bool PrivacySandboxSettings::IsPrivacySandboxManaged() {
  
  void PrivacySandboxSettings::SetPrivacySandboxEnabled(bool enabled) {
    pref_service_->SetBoolean(prefs::kPrivacySandboxManuallyControlled, true);
@@ -114,7 +114,7 @@ diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc b/chrome
  }
  
  void PrivacySandboxSettings::OnCookiesCleared() {
-@@ -447,6 +435,10 @@ bool PrivacySandboxSettings::IsPrivacySandboxAllowedForContext(
+@@ -446,6 +434,10 @@ bool PrivacySandboxSettings::IsPrivacySandboxAllowedForContext(
      const GURL& url,
      const absl::optional<url::Origin>& top_frame_origin,
      const ContentSettingsForOneType& cookie_settings) const {
@@ -125,7 +125,7 @@ diff --git a/chrome/browser/privacy_sandbox/privacy_sandbox_settings.cc b/chrome
    if (!pref_service_->GetBoolean(prefs::kPrivacySandboxApisEnabled))
      return false;
  
-@@ -459,6 +451,12 @@ bool PrivacySandboxSettings::IsPrivacySandboxAllowedForContext(
+@@ -458,6 +450,12 @@ bool PrivacySandboxSettings::IsPrivacySandboxAllowedForContext(
  }
  
  void PrivacySandboxSettings::MaybeReconcilePrivacySandboxPref() {

+ 29 - 0
build/patches/Disable-requests-for-single-word-Omnibar-searches.patch

@@ -0,0 +1,29 @@
+From: csagan5 <32685696+csagan5@users.noreply.github.com>
+Date: Sun, 27 Oct 2019 10:21:19 +0100
+Subject: Disable requests for single-word Omnibar searches
+
+Patch from https://github.com/Eloston/ungoogled-chromium/issues/814#issuecomment-526873727
+---
+ .../ui/omnibox/chrome_omnibox_navigation_observer.cc       | 7 -------
+ 1 file changed, 7 deletions(-)
+
+diff --git a/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer.cc b/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer.cc
+--- a/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer.cc
++++ b/chrome/browser/ui/omnibox/chrome_omnibox_navigation_observer.cc
+@@ -251,13 +251,6 @@ ChromeOmniboxNavigationObserver::ChromeOmniboxNavigationObserver(
+       profile_(profile),
+       show_infobar_(std::move(show_infobar)) {
+   NavigationUserData::CreateForNavigationHandle(navigation, this);
+-  if (alternative_nav_match_.destination_url.is_valid()) {
+-    loader_ = std::make_unique<AlternativeNavigationURLLoader>(
+-        alternative_nav_match.destination_url, this,
+-        base::BindOnce(
+-            &ChromeOmniboxNavigationObserver::OnAlternativeLoaderDone, this),
+-        GetURLLoaderFactory(loader_factory, profile));
+-  }
+ }
+ 
+ ChromeOmniboxNavigationObserver::~ChromeOmniboxNavigationObserver() {
+-- 
+2.20.1
+

File diff suppressed because it is too large
+ 158 - 139
build/patches/Disable-safe-browsing.patch


+ 10 - 10
build/patches/Disable-smart-selection-by-default.patch

@@ -43,7 +43,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearc
 diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
 --- a/chrome/browser/flags/android/chrome_feature_list.cc
 +++ b/chrome/browser/flags/android/chrome_feature_list.cc
-@@ -173,6 +173,7 @@ const base::Feature* const kFeaturesExposedToJava[] = {
+@@ -182,6 +182,7 @@ const base::Feature* const kFeaturesExposedToJava[] = {
      &kCCTClientDataHeader,
      &kCCTExternalLinkHandling,
      &kCCTIncognito,
@@ -51,9 +51,9 @@ diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browse
      &kCCTIncognitoAvailableToThirdParty,
      &kCCTPostMessageAPI,
      &kCCTRedirectPreconnect,
-@@ -487,6 +488,9 @@ const base::Feature kChromeSharingHub{"ChromeSharingHub",
+@@ -500,6 +501,9 @@ const base::Feature kChromeSharingHubLaunchAdjacent{
  const base::Feature kChromeSurveyNextAndroid{"ChromeSurveyNextAndroid",
-                                              base::FEATURE_DISABLED_BY_DEFAULT};
+                                              base::FEATURE_ENABLED_BY_DEFAULT};
  
 +const base::Feature kChromeSmartSelection{"ChromeSmartSelection",
 +                                          base::FEATURE_DISABLED_BY_DEFAULT};
@@ -64,14 +64,14 @@ diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browse
 diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h
 --- a/chrome/browser/flags/android/chrome_feature_list.h
 +++ b/chrome/browser/flags/android/chrome_feature_list.h
-@@ -49,6 +49,7 @@ extern const base::Feature kDontAutoHideBrowserControls;
+@@ -49,6 +49,7 @@ extern const base::Feature kCCTResourcePrefetch;
+ extern const base::Feature kDontAutoHideBrowserControls;
  extern const base::Feature kChromeShareLongScreenshot;
  extern const base::Feature kChromeShareScreenshot;
- extern const base::Feature kChromeSharingHub;
 +extern const base::Feature kChromeSmartSelection;
+ extern const base::Feature kChromeSharingHub;
+ extern const base::Feature kChromeSharingHubLaunchAdjacent;
  extern const base::Feature kChromeSurveyNextAndroid;
- extern const base::Feature kCommandLineOnNonRooted;
- extern const base::Feature kConditionalTabStripAndroid;
 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
 --- 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
@@ -81,8 +81,8 @@ diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/f
      public static final String CCT_REDIRECT_PRECONNECT = "CCTRedirectPreconnect";
 +    public static final String CHROME_SMART_SELECTION = "ChromeSmartSelection";
      public static final String CCT_REMOVE_REMOTE_VIEW_IDS = "CCTRemoveRemoteViewIds";
-     public static final String CCT_RESIZABLE_FOR_FIRST_PARTIES = "CCTResizableForFirstParties";
-     public static final String CCT_RESIZABLE_FOR_THIRD_PARTIES = "CCTResizableForThirdParties";
+     public static final String CCT_RESIZABLE_90_MAXIMUM_HEIGHT = "CCTResizable90MaximumHeight";
+     public static final String CCT_RESIZABLE_ALLOW_RESIZE_BY_USER_GESTURE =
 diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java b/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java
 --- a/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java
 +++ b/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java
@@ -98,7 +98,7 @@ diff --git a/content/public/android/java/src/org/chromium/content/browser/select
 diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
 --- a/testing/variations/fieldtrial_testing_config.json
 +++ b/testing/variations/fieldtrial_testing_config.json
-@@ -2026,6 +2026,21 @@
+@@ -1975,6 +1975,21 @@
              ]
          }
      ],

+ 2 - 2
build/patches/Disable-some-signed-exchange-features.patch

@@ -9,7 +9,7 @@ Subject: Disable some signed exchange features
 diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
 --- a/content/public/common/content_features.cc
 +++ b/content/public/common/content_features.cc
-@@ -719,7 +719,7 @@ const base::Feature kSignedExchangePrefetchCacheForNavigations{
+@@ -701,7 +701,7 @@ const base::Feature kSharedArrayBufferOnDesktop{
  // Signed Exchange Reporting for distributors
  // https://www.chromestatus.com/features/5687904902840320
  const base::Feature kSignedExchangeReportingForDistributors{
@@ -18,7 +18,7 @@ diff --git a/content/public/common/content_features.cc b/content/public/common/c
  
  // Subresource prefetching+loading via Signed HTTP Exchange
  // https://www.chromestatus.com/features/5126805474246656
-@@ -729,7 +729,7 @@ const base::Feature kSignedExchangeSubresourcePrefetch{
+@@ -711,7 +711,7 @@ const base::Feature kSignedExchangeSubresourcePrefetch{
  // Origin-Signed HTTP Exchanges (for WebPackage Loading)
  // https://www.chromestatus.com/features/5745285984681984
  const base::Feature kSignedHTTPExchange{"SignedHTTPExchange",

+ 6 - 6
build/patches/Disable-text-fragments-by-default.patch

@@ -17,7 +17,7 @@ Revert "[Text Fragment] Unflag fragment directive removal."
 diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 --- a/chrome/browser/about_flags.cc
 +++ b/chrome/browser/about_flags.cc
-@@ -5612,6 +5612,7 @@ const FeatureEntry kFeatureEntries[] = {
+@@ -5541,6 +5541,7 @@ const FeatureEntry kFeatureEntries[] = {
       flag_descriptions::kSharingHubDesktopOmniboxDescription, kOsDesktop,
       FEATURE_VALUE_TYPE(sharing_hub::kSharingHubDesktopOmnibox)},
  #endif  // defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX)
@@ -28,7 +28,7 @@ diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
 --- a/chrome/browser/flag-metadata.json
 +++ b/chrome/browser/flag-metadata.json
-@@ -3058,7 +3058,7 @@
+@@ -2961,7 +2961,7 @@
    {
      "name": "ev-details-in-page-info",
      "owners": [ "cthomp" ],
@@ -63,7 +63,7 @@ diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.
 diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
 --- a/third_party/blink/common/features.cc
 +++ b/third_party/blink/common/features.cc
-@@ -379,7 +379,7 @@ const base::Feature kStorageAccessAPI{"StorageAccessAPI",
+@@ -387,7 +387,7 @@ const base::Feature kStorageAccessAPI{"StorageAccessAPI",
  
  // Enable text snippets in URL fragments. https://crbug.com/919204.
  const base::Feature kTextFragmentAnchor{"TextFragmentAnchor",
@@ -75,7 +75,7 @@ diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/fea
 diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
 --- a/third_party/blink/renderer/core/dom/document.cc
 +++ b/third_party/blink/renderer/core/dom/document.cc
-@@ -4063,6 +4063,10 @@ void Document::SetURL(const KURL& url) {
+@@ -4062,6 +4062,10 @@ void Document::SetURL(const KURL& url) {
      }
    }
  
@@ -86,7 +86,7 @@ diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink
    // Strip the fragment directive from the URL fragment. E.g. "#id:~:text=a"
    // --> "#id". See https://github.com/WICG/scroll-to-text-fragment.
    String fragment = new_url.FragmentIdentifier();
-@@ -4076,6 +4080,7 @@ void Document::SetURL(const KURL& url) {
+@@ -4075,6 +4079,7 @@ void Document::SetURL(const KURL& url) {
      else
        new_url.SetFragmentIdentifier(fragment.Substring(0, start_pos));
    }
@@ -145,7 +145,7 @@ diff --git a/third_party/blink/renderer/core/page/scrolling/text_fragment_anchor
 diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
-@@ -2173,8 +2173,7 @@
+@@ -2178,8 +2178,7 @@
      },
      {
        name: "TextFragmentIdentifiers",

+ 2 - 2
build/patches/Disable-the-DIAL-repeating-discovery.patch

@@ -10,7 +10,7 @@ This causes unnecessary SSDP network spam
 diff --git a/chrome/browser/media/router/discovery/dial/dial_registry.cc b/chrome/browser/media/router/discovery/dial/dial_registry.cc
 --- a/chrome/browser/media/router/discovery/dial/dial_registry.cc
 +++ b/chrome/browser/media/router/discovery/dial/dial_registry.cc
-@@ -191,10 +191,6 @@ void DialRegistry::StartPeriodicDiscovery() {
+@@ -190,10 +190,6 @@ void DialRegistry::StartPeriodicDiscovery() {
  
    dial_ = CreateDialService();
    dial_->AddObserver(this);
@@ -21,7 +21,7 @@ diff --git a/chrome/browser/media/router/discovery/dial/dial_registry.cc b/chrom
  }
  
  void DialRegistry::DoDiscovery() {
-@@ -208,8 +204,6 @@ void DialRegistry::StopPeriodicDiscovery() {
+@@ -207,8 +203,6 @@ void DialRegistry::StopPeriodicDiscovery() {
    if (!dial_)
      return;
  

+ 0 - 24
build/patches/Disable-third-party-cookies-by-default.patch

@@ -1,24 +0,0 @@
-From: csagan5 <32685696+csagan5@users.noreply.github.com>
-Date: Wed, 11 Oct 2017 22:50:10 +0200
-Subject: Disable third-party cookies by default
-
-author: Chad Miller <chad.miller@canonical.com>
----
- chrome/browser/prefs/browser_prefs.cc | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
---- a/chrome/browser/prefs/browser_prefs.cc
-+++ b/chrome/browser/prefs/browser_prefs.cc
-@@ -717,7 +717,7 @@ void RegisterProfilePrefsForMigration(
- 
-   chrome_browser_net::secure_dns::RegisterProbesSettingBackupPref(registry);
- 
--  registry->RegisterBooleanPref(kBlockThirdPartyCookies, false);
-+  registry->RegisterBooleanPref(kBlockThirdPartyCookies, true);
- 
-   registry->RegisterTimePref(kPluginsDeprecationInfobarLastShown, base::Time());
- 
--- 
-2.20.1
-

+ 12 - 12
build/patches/Disable-third-party-origin-trials.patch

@@ -43,7 +43,7 @@ diff --git a/components/embedder_support/origin_trials/origin_trial_policy_impl.
 diff --git a/components/embedder_support/origin_trials/origin_trial_policy_impl.h b/components/embedder_support/origin_trials/origin_trial_policy_impl.h
 --- a/components/embedder_support/origin_trials/origin_trial_policy_impl.h
 +++ b/components/embedder_support/origin_trials/origin_trial_policy_impl.h
-@@ -31,11 +31,11 @@ class OriginTrialPolicyImpl : public blink::OriginTrialPolicy {
+@@ -35,11 +35,11 @@ class OriginTrialPolicyImpl : public blink::OriginTrialPolicy {
    bool IsTokenDisabled(base::StringPiece token_signature) const override;
    bool IsOriginSecure(const GURL& url) const override;
  
@@ -59,7 +59,7 @@ diff --git a/components/embedder_support/origin_trials/origin_trial_policy_impl.
 diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc
 --- a/content/browser/renderer_host/navigation_request.cc
 +++ b/content/browser/renderer_host/navigation_request.cc
-@@ -6584,7 +6584,6 @@ void NavigationRequest::RestartBackForwardCachedNavigationImpl() {
+@@ -6522,7 +6522,6 @@ void NavigationRequest::RestartBackForwardCachedNavigationImpl() {
  void NavigationRequest::ForceEnableOriginTrials(
      const std::vector<std::string>& trials) {
    DCHECK(!HasCommitted());
@@ -70,7 +70,7 @@ diff --git a/content/browser/renderer_host/navigation_request.cc b/content/brows
 diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
 --- a/content/renderer/render_frame_impl.cc
 +++ b/content/renderer/render_frame_impl.cc
-@@ -468,10 +468,6 @@ void FillNavigationParamsRequest(
+@@ -469,10 +469,6 @@ void FillNavigationParamsRequest(
          common_params.initiator_origin.value();
    }
  
@@ -81,7 +81,7 @@ diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_fra
    navigation_params->was_discarded = commit_params.was_discarded;
    navigation_params->document_ukm_source_id =
        commit_params.document_ukm_source_id;
-@@ -504,12 +500,6 @@ void FillNavigationParamsRequest(
+@@ -505,12 +501,6 @@ void FillNavigationParamsRequest(
    navigation_params->web_bundle_claimed_url =
        commit_params.web_bundle_claimed_url;
  
@@ -94,7 +94,7 @@ diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_fra
    if (!commit_params.early_hints_preloaded_resources.empty()) {
      navigation_params->early_hints_preloaded_resources = WebVector<WebURL>();
      for (const auto& resource : commit_params.early_hints_preloaded_resources) {
-@@ -555,11 +545,6 @@ blink::mojom::CommonNavigationParamsPtr MakeCommonNavigationParams(
+@@ -556,11 +546,6 @@ blink::mojom::CommonNavigationParamsPtr MakeCommonNavigationParams(
            info->url_request.GetURLRequestExtraData().get());
    DCHECK(url_request_extra_data);
  
@@ -179,7 +179,7 @@ diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_p
    return result;
  }
  
-@@ -2444,10 +2431,6 @@ void DocumentLoader::CreateParserPostCommit() {
+@@ -2432,10 +2419,6 @@ void DocumentLoader::CreateParserPostCommit() {
            OriginTrialFeature::kTouchEventFeatureDetection);
      }
  
@@ -187,9 +187,9 @@ diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_p
 -    window->GetOriginTrialContext()->AddForceEnabledTrials(
 -        force_enabled_origin_trials_);
 -
- #if BUILDFLAG(IS_CHROMEOS_ASH)
-     // Enable Auto Picture-in-Picture feature for the built-in Chrome OS Video
-     // Player app.
+     OriginTrialContext::ActivateNavigationFeaturesFromInitiator(
+         window, &initiator_origin_trial_features_);
+   }
 diff --git a/third_party/blink/renderer/core/loader/http_equiv.cc b/third_party/blink/renderer/core/loader/http_equiv.cc
 --- a/third_party/blink/renderer/core/loader/http_equiv.cc
 +++ b/third_party/blink/renderer/core/loader/http_equiv.cc
@@ -219,7 +219,7 @@ diff --git a/third_party/blink/renderer/core/loader/http_equiv.cc b/third_party/
 diff --git a/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc b/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc
 --- a/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc
 +++ b/third_party/blink/renderer/core/origin_trials/origin_trial_context.cc
-@@ -275,17 +275,8 @@ void OriginTrialContext::AddToken(const String& token) {
+@@ -278,17 +278,8 @@ void OriginTrialContext::AddToken(const String& token) {
  void OriginTrialContext::AddTokenFromExternalScript(
      const String& token,
      const SecurityOrigin* origin) {
@@ -239,7 +239,7 @@ diff --git a/third_party/blink/renderer/core/origin_trials/origin_trial_context.
  }
  
  void OriginTrialContext::AddTokenInternal(const String& token,
-@@ -372,8 +363,6 @@ bool OriginTrialContext::InstallFeature(OriginTrialFeature enabled_feature,
+@@ -400,8 +391,6 @@ bool OriginTrialContext::InstallSettingFeature(
  }
  
  void OriginTrialContext::AddFeature(OriginTrialFeature feature) {
@@ -251,7 +251,7 @@ diff --git a/third_party/blink/renderer/core/origin_trials/origin_trial_context.
 diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
-@@ -2183,10 +2183,6 @@
+@@ -2188,10 +2188,6 @@
        name: "TextFragmentTapOpensContextMenu",
        status: {"Android": "stable"},
      },

+ 1 - 1
build/patches/Disable-unified-autoplay-feature.patch

@@ -9,7 +9,7 @@ Subject: Disable unified autoplay feature
 diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc
 --- a/media/base/media_switches.cc
 +++ b/media/base/media_switches.cc
-@@ -480,7 +480,7 @@ const base::Feature kUseR16Texture{"use-r16-texture",
+@@ -490,7 +490,7 @@ const base::Feature kUseR16Texture{"use-r16-texture",
  // Enables the Unified Autoplay policy by overriding the platform's default
  // autoplay policy.
  const base::Feature kUnifiedAutoplay{"UnifiedAutoplay",

+ 1 - 1
build/patches/Do-not-build-API-keys-infobar.patch

@@ -9,7 +9,7 @@ Subject: Do not build API keys infobar
 diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
 --- a/chrome/browser/ui/BUILD.gn
 +++ b/chrome/browser/ui/BUILD.gn
-@@ -1194,8 +1194,6 @@ static_library("ui") {
+@@ -1227,8 +1227,6 @@ static_library("ui") {
        "singleton_tabs.h",
        "startup/automation_infobar_delegate.cc",
        "startup/automation_infobar_delegate.h",

+ 6 - 6
build/patches/Do-not-compile-QR-code-sharing.patch

@@ -11,7 +11,7 @@ Subject: Do not compile QR code sharing
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
-@@ -79,7 +79,6 @@ import org.chromium.chrome.browser.share.ShareButtonController;
+@@ -82,7 +82,6 @@ import org.chromium.chrome.browser.share.ShareButtonController;
  import org.chromium.chrome.browser.share.ShareDelegate;
  import org.chromium.chrome.browser.share.ShareDelegate.ShareOrigin;
  import org.chromium.chrome.browser.share.ShareUtils;
@@ -19,7 +19,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordi
  import org.chromium.chrome.browser.tab.AccessibilityVisibilityHandler;
  import org.chromium.chrome.browser.tab.AutofillSessionLifetimeController;
  import org.chromium.chrome.browser.tab.Tab;
-@@ -402,10 +401,6 @@ public class RootUiCoordinator
+@@ -421,10 +420,6 @@ public class RootUiCoordinator
      }
  
      public void onAttachFragment(Fragment fragment) {
@@ -33,7 +33,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordi
 diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java
 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java
 +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java
-@@ -25,7 +25,6 @@ import org.chromium.chrome.browser.profiles.Profile;
+@@ -26,7 +26,6 @@ import org.chromium.chrome.browser.profiles.Profile;
  import org.chromium.chrome.browser.share.SaveBitmapDelegate;
  import org.chromium.chrome.browser.share.link_to_text.LinkToTextCoordinator.LinkGeneration;
  import org.chromium.chrome.browser.share.long_screenshots.LongScreenshotsCoordinator;
@@ -41,7 +41,7 @@ diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/s
  import org.chromium.chrome.browser.share.screenshot.ScreenshotCoordinator;
  import org.chromium.chrome.browser.share.send_tab_to_self.SendTabToSelfCoordinator;
  import org.chromium.chrome.browser.share.share_sheet.ShareSheetLinkToggleMetricsHelper.LinkToggleMetricsDetails;
-@@ -255,9 +254,6 @@ public class ChromeProvidedSharingOptionsProvider {
+@@ -274,9 +273,6 @@ public class ChromeProvidedSharingOptionsProvider {
          mOrderedFirstPartyOptions.add(createCopyFirstPartyOption());
          mOrderedFirstPartyOptions.add(createCopyTextFirstPartyOption());
          mOrderedFirstPartyOptions.add(createSendTabToSelfFirstPartyOption());
@@ -51,7 +51,7 @@ diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/s
          if (UserPrefs.get(Profile.getLastUsedRegularProfile()).getBoolean(Pref.PRINTING_ENABLED)) {
              mOrderedFirstPartyOptions.add(createPrintingFirstPartyOption());
          }
-@@ -410,19 +406,6 @@ public class ChromeProvidedSharingOptionsProvider {
+@@ -400,19 +396,6 @@ public class ChromeProvidedSharingOptionsProvider {
                  .build();
      }
  
@@ -74,7 +74,7 @@ diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/s
 diff --git a/chrome/browser/share/android/java_sources.gni b/chrome/browser/share/android/java_sources.gni
 --- a/chrome/browser/share/android/java_sources.gni
 +++ b/chrome/browser/share/android/java_sources.gni
-@@ -23,24 +23,6 @@ share_java_sources = [
+@@ -24,24 +24,6 @@ share_java_sources = [
    "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsTabService.java",
    "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/LongScreenshotsTabServiceFactory.java",
    "//chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/long_screenshots/bitmap_generation/ScreenshotBoundsManager.java",

+ 6 - 5
build/patches/Do-not-ignore-download-location-prompt-setting.patch

@@ -8,21 +8,22 @@ do not skip the prompt in such cases.
 
 Do not tick "Don't show again" by default
 ---
- .../dialogs/DownloadLocationDialogCoordinator.java | 14 --------------
- 1 file changed, 14 deletions(-)
+ .../DownloadLocationDialogCoordinator.java        | 15 ---------------
+ 1 file changed, 15 deletions(-)
 
 diff --git a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationDialogCoordinator.java b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationDialogCoordinator.java
 --- a/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationDialogCoordinator.java
 +++ b/chrome/browser/download/android/java/src/org/chromium/chrome/browser/download/dialogs/DownloadLocationDialogCoordinator.java
-@@ -128,20 +128,6 @@ public class DownloadLocationDialogCoordinator implements ModalDialogProperties.
+@@ -132,21 +132,6 @@ public class DownloadLocationDialogCoordinator implements ModalDialogProperties.
       * @param dirs An list of available download directories.
       */
      private void onDirectoryOptionsRetrieved(ArrayList<DirectoryOption> dirs) {
 -        // If there is only one directory available, don't show the default dialog, and set the
 -        // download directory to default. Dialog will still show for other types of dialogs, like
--        // name conflict or disk error.
+-        // name conflict or disk error or if Incognito download warning is needed.
 -        if (dirs.size() == 1 && !mLocationDialogManaged
--                && mDialogType == DownloadLocationDialogType.DEFAULT) {
+-                && mDialogType == DownloadLocationDialogType.DEFAULT
+-                && !shouldShowIncognitoWarning()) {
 -            final DirectoryOption dir = dirs.get(0);
 -            if (dir.type == DirectoryOption.DownloadLocationDirectoryType.DEFAULT) {
 -                assert (!TextUtils.isEmpty(dir.location));

+ 11 - 11
build/patches/Enable-SPPI-for-devices-with-enough-memory.patch

@@ -10,10 +10,10 @@ Subject: Enable SPPI for devices with enough memory
 diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
 --- a/chrome/common/chrome_features.cc
 +++ b/chrome/common/chrome_features.cc
-@@ -889,11 +889,7 @@ const base::Feature kShow10_10ObsoleteInfobar{
+@@ -922,11 +922,7 @@ const base::Feature kShow10_10ObsoleteInfobar{
  // browser_features, as they are only used on the browser side.
  const base::Feature kSitePerProcess {
-   "site-per-process",
+   "SitePerProcess",
 -#if defined(OS_ANDROID)
 -      base::FEATURE_DISABLED_BY_DEFAULT
 -#else
@@ -25,15 +25,15 @@ diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
 diff --git a/components/site_isolation/features.cc b/components/site_isolation/features.cc
 --- a/components/site_isolation/features.cc
 +++ b/components/site_isolation/features.cc
-@@ -57,7 +57,7 @@ const base::Feature kSiteIsolationForOAuthSites{
- // base::SysInfo::AmountOfPhysicalMemoryMB().
- const base::Feature kSitePerProcessOnlyForHighMemoryClients{
-     "site-per-process-only-for-high-memory-clients",
--    base::FEATURE_DISABLED_BY_DEFAULT};
-+    base::FEATURE_ENABLED_BY_DEFAULT};
- const char kSitePerProcessOnlyForHighMemoryClientsParamName[] =
-     "site-per-process-low-memory-cutoff-mb";
- 
+@@ -60,7 +60,7 @@ const base::Feature kSiteIsolationForOAuthSites{
+ // kSitePerProcess won't be checked at all, and field trials won't activate
+ // either the control or the experiment group.
+ const base::Feature kSiteIsolationMemoryThresholds{
+-    "SiteIsolationMemoryThresholds", base::FEATURE_DISABLED_BY_DEFAULT};
++    "SiteIsolationMemoryThresholds", base::FEATURE_ENABLED_BY_DEFAULT};
+ const char kStrictSiteIsolationMemoryThresholdParamName[] =
+     "strict_site_isolation_threshold_mb";
+ const char kPartialSiteIsolationMemoryThresholdParamName[] =
 -- 
 2.20.1
 

+ 2 - 2
build/patches/Enable-darken-websites-checkbox-in-themes.patch

@@ -11,7 +11,7 @@ Unexpire #darken-websites-checkbox-in-themes-setting
 diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
 --- a/chrome/browser/flag-metadata.json
 +++ b/chrome/browser/flag-metadata.json
-@@ -941,7 +941,7 @@
+@@ -965,7 +965,7 @@
    {
      "name": "darken-websites-checkbox-in-themes-setting",
      "owners": [ "lazzzis@google.com", "twellington" ],
@@ -23,7 +23,7 @@ diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.js
 diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
 --- a/chrome/browser/flags/android/chrome_feature_list.cc
 +++ b/chrome/browser/flags/android/chrome_feature_list.cc
-@@ -561,7 +561,7 @@ const base::Feature kContextualSearchTranslations{
+@@ -571,7 +571,7 @@ const base::Feature kContextualSearchTranslations{
      "ContextualSearchTranslations", base::FEATURE_DISABLED_BY_DEFAULT};
  
  const base::Feature kDarkenWebsitesCheckboxInThemesSetting{

+ 1 - 1
build/patches/Enable-fwrapv-in-Clang-for-non-UBSan-builds.patch

@@ -42,7 +42,7 @@ Excerpt from https://github.com/bromite/bromite/issues/226
 diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
 --- a/build/config/compiler/BUILD.gn
 +++ b/build/config/compiler/BUILD.gn
-@@ -350,6 +350,10 @@ config("compiler") {
+@@ -351,6 +351,10 @@ config("compiler") {
        }
      }
  

+ 18 - 18
build/patches/Enable-native-Android-autofill.patch

@@ -28,7 +28,7 @@ See also: https://github.com/bromite/bromite/issues/547
 diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
 --- a/chrome/android/BUILD.gn
 +++ b/chrome/android/BUILD.gn
-@@ -414,6 +414,7 @@ android_library("chrome_java") {
+@@ -415,6 +415,7 @@ android_library("chrome_java") {
      "//chrome/browser/xsurface:java",
      "//components/autofill/android:autofill_java",
      "//components/autofill_assistant/browser:proto_java",
@@ -62,23 +62,23 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manage
 @@ -75,6 +81,10 @@ public class PasswordSettings extends PreferenceFragmentCompat
      public static final String PREF_TRUSTED_VAULT_OPT_IN = "trusted_vault_opt_in";
      public static final String PREF_KEY_MANAGE_ACCOUNT_LINK = "manage_account_link";
-     public static final String PREF_KEY_SECURITY_KEY_LINK = "security_key_link";
+ 
 +    public static final String PREF_ANDROID_AUTOFILL_SWITCH = "android_autofill_switch";
 +
 +    private SnackbarManager mSnackbarManager;
 +    private Snackbar mSnackbar;
- 
      // A PasswordEntryViewer receives a boolean value with this key. If set true, the the entry was
  
-@@ -110,6 +120,7 @@ public class PasswordSettings extends PreferenceFragmentCompat
+     // part of a search result.
+@@ -108,6 +118,7 @@ public class PasswordSettings extends PreferenceFragmentCompat
+     private String mSearchQuery;
      private Preference mLinkPref;
-     private Preference mSecurityKey;
      private ChromeSwitchPreference mSavePasswordsSwitch;
 +    private ChromeSwitchPreference mEnableAndroidAutofillSwitch;
      private ChromeSwitchPreference mAutoSignInSwitch;
      private ChromeBasePreference mCheckPasswords;
      private ChromeBasePreference mTrustedVaultOptIn;
-@@ -274,6 +285,7 @@ public class PasswordSettings extends PreferenceFragmentCompat
+@@ -272,6 +283,7 @@ public class PasswordSettings extends PreferenceFragmentCompat
          getPreferenceScreen().removeAll();
          if (mSearchQuery == null) {
              createSavePasswordsSwitch();
@@ -86,7 +86,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manage
              createAutoSignInCheckbox();
              if (mPasswordCheck != null) {
                  createCheckPasswords();
-@@ -517,6 +529,50 @@ public class PasswordSettings extends PreferenceFragmentCompat
+@@ -511,6 +523,50 @@ public class PasswordSettings extends PreferenceFragmentCompat
                  getPrefService().getBoolean(Pref.CREDENTIALS_ENABLE_SERVICE));
      }
  
@@ -140,7 +140,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manage
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.java
-@@ -74,6 +74,18 @@ import org.chromium.url.GURL;
+@@ -75,6 +75,18 @@ import org.chromium.url.GURL;
  
  import java.nio.ByteBuffer;
  
@@ -159,7 +159,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.jav
  /**
   * Implementation of the interface {@link Tab}. Contains and manages a {@link ContentView}.
   * This class is not intended to be extended.
-@@ -217,6 +229,8 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
+@@ -218,6 +230,8 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
      /** Whether or not the user manually changed the user agent. */
      private boolean mUserForcedUserAgent;
  
@@ -168,7 +168,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.jav
      /**
       * Creates an instance of a {@link TabImpl}.
       *
-@@ -767,6 +781,11 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
+@@ -768,6 +782,11 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
          for (TabObserver observer : mObservers) observer.onDestroyed(this);
          mObservers.clear();
  
@@ -180,7 +180,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.jav
          mUserDataHost.destroy();
          mTabViewManager.destroy();
          hideNativePage(false, null);
-@@ -1358,6 +1377,16 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
+@@ -1359,6 +1378,16 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
          return tabsPtrArray;
      }
  
@@ -197,7 +197,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.jav
      /**
       * Initializes the {@link WebContents}. Completes the browser content components initialization
       * around a native WebContents pointer.
-@@ -1407,6 +1436,19 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
+@@ -1408,6 +1437,19 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
                              mDelegateFactory.createContextMenuPopulatorFactory(this), this));
  
              mWebContents.notifyRendererPreferenceUpdate();
@@ -217,7 +217,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabImpl.jav
              TabHelpers.initWebContentsHelpers(this);
              notifyContentChanged();
          } finally {
-@@ -1769,5 +1811,6 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
+@@ -1771,5 +1813,6 @@ public class TabImpl implements Tab, TabObscuringHandler.Observer {
          void setActiveNavigationEntryTitleForUrl(long nativeTabAndroid, String url, String title);
          void loadOriginalImage(long nativeTabAndroid);
          boolean handleNonNavigationAboutURL(GURL url);
@@ -256,7 +256,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabViewAndr
 diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
 --- a/chrome/browser/BUILD.gn
 +++ b/chrome/browser/BUILD.gn
-@@ -2376,6 +2376,14 @@ static_library("browser") {
+@@ -2393,6 +2393,14 @@ static_library("browser") {
      "//ui/webui/resources/cr_components/most_visited:mojom",
      "//ui/webui/resources/js/browser_command:mojo_bindings",
    ]
@@ -314,7 +314,7 @@ diff --git a/chrome/browser/android/tab_android.cc b/chrome/browser/android/tab_
 diff --git a/chrome/browser/android/tab_android.h b/chrome/browser/android/tab_android.h
 --- a/chrome/browser/android/tab_android.h
 +++ b/chrome/browser/android/tab_android.h
-@@ -150,6 +150,8 @@ class TabAndroid : public base::SupportsUserData {
+@@ -154,6 +154,8 @@ class TabAndroid : public base::SupportsUserData {
  
    void SetDevToolsAgentHost(scoped_refptr<content::DevToolsAgentHost> host);
  
@@ -326,7 +326,7 @@ diff --git a/chrome/browser/android/tab_android.h b/chrome/browser/android/tab_a
 diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
 +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
-@@ -555,6 +555,9 @@ CHAR_LIMIT guidelines:
+@@ -582,6 +582,9 @@ CHAR_LIMIT guidelines:
        <message name="IDS_PASSWORD_SETTINGS_SAVE_PASSWORDS" desc="Title for the checkbox toggling whether passwords are saved or not. [CHAR_LIMIT=32]">
          Save passwords
        </message>
@@ -339,7 +339,7 @@ diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chro
 diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc
 --- a/chrome/browser/ui/tab_helpers.cc
 +++ b/chrome/browser/ui/tab_helpers.cc
-@@ -126,6 +126,9 @@
+@@ -141,6 +141,9 @@
  #include "chrome/browser/ui/android/context_menu_helper.h"
  #include "chrome/browser/ui/javascript_dialogs/javascript_tab_modal_dialog_manager_delegate_android.h"
  #include "chrome/browser/video_tutorials/video_tutorial_tab_helper.h"
@@ -349,7 +349,7 @@ diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc
  #else
  #include "chrome/browser/accuracy_tips/accuracy_service_factory.h"
  #include "chrome/browser/banners/app_banner_manager_desktop.h"
-@@ -245,7 +248,8 @@ void TabHelpers::AttachTabHelpers(WebContents* web_contents) {
+@@ -265,7 +268,8 @@ void TabHelpers::AttachTabHelpers(WebContents* web_contents) {
        web_contents,
        autofill::ChromeAutofillClient::FromWebContents(web_contents),
        g_browser_process->GetApplicationLocale(),

+ 1 - 1
build/patches/Enable-prefetch-privacy-changes-by-default.patch

@@ -9,7 +9,7 @@ Subject: Enable prefetch-privacy-changes by default
 diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
 --- a/third_party/blink/common/features.cc
 +++ b/third_party/blink/common/features.cc
-@@ -408,7 +408,7 @@ const base::Feature kComputePressure{"ComputePressure",
+@@ -416,7 +416,7 @@ const base::Feature kComputePressure{"ComputePressure",
  // Prefetch request properties are updated to be privacy-preserving. See
  // crbug.com/988956.
  const base::Feature kPrefetchPrivacyChanges{"PrefetchPrivacyChanges",

+ 11 - 11
build/patches/Enable-share-intent.patch

@@ -27,7 +27,7 @@ See also: https://github.com/bromite/bromite/issues/1062
 diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni
 --- a/chrome/android/chrome_java_resources.gni
 +++ b/chrome/android/chrome_java_resources.gni
-@@ -719,6 +719,7 @@ chrome_java_resources = [
+@@ -717,6 +717,7 @@ chrome_java_resources = [
    "java/res/layout/share_sheet_content.xml",
    "java/res/layout/share_sheet_item.xml",
    "java/res/layout/sharing_device_picker.xml",
@@ -38,7 +38,7 @@ diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_ja
 diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
 --- a/chrome/android/chrome_java_sources.gni
 +++ b/chrome/android/chrome_java_sources.gni
-@@ -1052,6 +1052,7 @@ chrome_java_sources = [
+@@ -1048,6 +1048,7 @@ chrome_java_sources = [
    "java/src/org/chromium/chrome/browser/sharing/shared_clipboard/SharedClipboardMessageHandler.java",
    "java/src/org/chromium/chrome/browser/sharing/shared_clipboard/SharedClipboardMetrics.java",
    "java/src/org/chromium/chrome/browser/sharing/shared_clipboard/SharedClipboardShareActivity.java",
@@ -173,7 +173,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessIni
  import org.chromium.chrome.browser.tab.state.ShoppingPersistedTabData;
  import org.chromium.chrome.browser.ui.searchactivityutils.SearchActivityPreferencesManager;
  import org.chromium.chrome.browser.util.AfterStartupTaskUtils;
-@@ -397,6 +398,8 @@ public class ProcessInitializationHandler {
+@@ -409,6 +410,8 @@ public class ProcessInitializationHandler {
          deferredStartupHandler.addDeferredTask(
                  () -> IncognitoTabLauncher.updateComponentEnabledState());
  
@@ -304,7 +304,7 @@ new file mode 100644
 diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 --- a/chrome/browser/about_flags.cc
 +++ b/chrome/browser/about_flags.cc
-@@ -5637,6 +5637,10 @@ const FeatureEntry kFeatureEntries[] = {
+@@ -5566,6 +5566,10 @@ const FeatureEntry kFeatureEntries[] = {
       FEATURE_VALUE_TYPE(sharing_hub::kDesktopScreenshots)},
  #endif
  
@@ -318,7 +318,7 @@ diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
 --- a/chrome/browser/flag_descriptions.cc
 +++ b/chrome/browser/flag_descriptions.cc
-@@ -2319,6 +2319,11 @@ const char kSharingDesktopScreenshotsDescription[] =
+@@ -2335,6 +2335,11 @@ const char kSharingDesktopScreenshotsDescription[] =
      "Enables taking"
      " screenshots from the desktop sharing hub.";
  
@@ -333,7 +333,7 @@ diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descripti
 diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
 --- a/chrome/browser/flag_descriptions.h
 +++ b/chrome/browser/flag_descriptions.h
-@@ -1336,6 +1336,9 @@ extern const char kSharedClipboardUIDescription[];
+@@ -1340,6 +1340,9 @@ extern const char kSharedClipboardUIDescription[];
  extern const char kSharingDesktopScreenshotsName[];
  extern const char kSharingDesktopScreenshotsDescription[];
  
@@ -346,7 +346,7 @@ diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptio
 diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
 --- a/chrome/browser/flags/android/chrome_feature_list.cc
 +++ b/chrome/browser/flags/android/chrome_feature_list.cc
-@@ -258,6 +258,7 @@ const base::Feature* const kFeaturesExposedToJava[] = {
+@@ -270,6 +270,7 @@ const base::Feature* const kFeaturesExposedToJava[] = {
      &kServiceManagerForDownload,
      &kShareButtonInTopToolbar,
      &kSharedClipboardUI,
@@ -354,7 +354,7 @@ diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browse
      &kSharingHubLinkToggle,
      &kSingleTouchSelect,
      &kSpannableInlineAutocomplete,
-@@ -644,6 +645,9 @@ const base::Feature kSearchEnginePromoExistingDevice{
+@@ -657,6 +658,9 @@ const base::Feature kSearchEnginePromoExistingDevice{
  const base::Feature kSearchEnginePromoNewDevice{
      "SearchEnginePromo.NewDevice", base::FEATURE_ENABLED_BY_DEFAULT};
  
@@ -367,7 +367,7 @@ diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browse
 diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h
 --- a/chrome/browser/flags/android/chrome_feature_list.h
 +++ b/chrome/browser/flags/android/chrome_feature_list.h
-@@ -123,6 +123,7 @@ extern const base::Feature kRelatedSearchesSimplifiedUx;
+@@ -126,6 +126,7 @@ extern const base::Feature kRelatedSearchesSimplifiedUx;
  extern const base::Feature kRelatedSearchesUi;
  extern const base::Feature kSearchEnginePromoExistingDevice;
  extern const base::Feature kSearchEnginePromoNewDevice;
@@ -378,7 +378,7 @@ diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser
 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
 --- 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
-@@ -481,6 +481,7 @@ public abstract class ChromeFeatureList {
+@@ -488,6 +488,7 @@ public abstract class ChromeFeatureList {
      public static final String SHARE_USAGE_RANKING = "ShareUsageRanking";
      public static final String SHARE_USAGE_RANKING_FIXED_MORE = "ShareUsageRankingFixedMore";
      public static final String SHARED_CLIPBOARD_UI = "SharedClipboardUI";
@@ -389,7 +389,7 @@ diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/f
 diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
 +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
-@@ -4518,6 +4518,19 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
+@@ -4578,6 +4578,19 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
          Send text to Your Devices
        </message>
  

+ 1 - 1
build/patches/Enable-user-agent-freeze-by-default.patch

@@ -9,7 +9,7 @@ Subject: Enable user-agent freeze by default
 diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
 --- a/third_party/blink/common/features.cc
 +++ b/third_party/blink/common/features.cc
-@@ -81,7 +81,7 @@ const base::Feature kFreezePurgeMemoryAllPagesFrozen{
+@@ -86,7 +86,7 @@ const base::Feature kFreezePurgeMemoryAllPagesFrozen{
  
  // Freezes the user-agent as part of https://github.com/WICG/ua-client-hints.
  const base::Feature kReduceUserAgent{"ReduceUserAgent",

+ 0 - 10640
build/patches/Experimental-user-scripts-support.patch

@@ -1,10640 +0,0 @@
-From: uazo <uazo@users.noreply.github.com>
-Date: Fri, 13 Aug 2021 17:10:47 +0000
-Subject: Experimental user scripts support
-
-Activate the user scripts functionality for Android,
-as it is available in the Desktop version.
-
-It is possible to add user scripts in two ways: by
-selecting files from the picker in the settings or
-downloading the scripts and opening them from downloads
-(only if such files end with '.user.js').
-
-New imported scripts are disabled by default: they
-can be activated via the UI.
-
-Parsed user script headers are: name, version, description,
-include, exclude, match, exclude_match (only http and
-https), run-at (document-start, document-end,
-document-idle), homepage, url_source
-
-The UI also allows you to see the source of the script.
-
-See also: components/user_scripts/README.md
----
- chrome/android/BUILD.gn                       |   5 +
- .../android/java/res/xml/main_preferences.xml |   5 +
- .../browser/download/DownloadUtils.java       |   6 +
- .../init/ProcessInitializationHandler.java    |   3 +
- chrome/android/java_sources.gni               |   3 +
- chrome/browser/BUILD.gn                       |   5 +
- chrome/browser/about_flags.cc                 |   5 +
- .../browser/chrome_content_browser_client.cc  |   3 +-
- chrome/browser/flag_descriptions.cc           |   5 +
- chrome/browser/flag_descriptions.h            |   3 +
- chrome/browser/prefs/browser_prefs.cc         |   2 +
- chrome/browser/profiles/BUILD.gn              |   1 +
- ...hrome_browser_main_extra_parts_profiles.cc |   3 +
- chrome/browser/profiles/profile_manager.cc    |   9 +
- chrome/browser/profiles/renderer_updater.cc   |  10 +-
- chrome/browser/profiles/renderer_updater.h    |   1 +
- .../webui/chrome_web_ui_controller_factory.cc |   3 +
- chrome/chrome_paks.gni                        |   2 +
- chrome/common/renderer_configuration.mojom    |   1 +
- chrome/renderer/BUILD.gn                      |   1 +
- .../chrome_content_renderer_client.cc         |  37 +
- .../renderer/chrome_render_thread_observer.cc |   3 +
- components/components_strings.grd             |   1 +
- components/user_scripts/README.md             | 150 ++++
- components/user_scripts/android/BUILD.gn      |  80 ++
- .../java/res/layout/accept_script_item.xml    | 160 ++++
- .../java/res/layout/accept_script_list.xml    |  10 +
- .../java/res/layout/scripts_preference.xml    |  40 +
- .../android/java/res/values/dimens.xml        |  11 +
- .../java/res/xml/userscripts_preferences.xml  |  34 +
- .../user_scripts/UserScriptsUtils.java        |  84 ++
- .../user_scripts/FragmentWindowAndroid.java   |  89 ++
- .../user_scripts/IUserScriptsUtils.java       |  22 +
- .../components/user_scripts/ScriptInfo.java   |  37 +
- .../user_scripts/ScriptListBaseAdapter.java   | 163 ++++
- .../user_scripts/ScriptListPreference.java    | 171 ++++
- .../user_scripts/UserScriptsBridge.java       | 200 +++++
- .../user_scripts/UserScriptsPreferences.java  | 116 +++
- .../user_scripts/android/java_sources.gni     |  18 +
- .../android/user_scripts_bridge.cc            | 173 ++++
- .../android/user_scripts_bridge.h             |  31 +
- components/user_scripts/browser/BUILD.gn      |  83 ++
- .../user_scripts/browser/file_task_runner.cc  |  40 +
- .../user_scripts/browser/file_task_runner.h   |  34 +
- .../browser/resources/browser_resources.grd   |  14 +
- .../browser/resources/user-script-ui/BUILD.gn |  12 +
- .../user-script-ui/user-scripts-ui.html       |  14 +
- .../user-script-ui/user-scripts-ui.js         |   9 +
- .../browser/ui/user_scripts_ui.cc             | 148 ++++
- .../user_scripts/browser/ui/user_scripts_ui.h |  39 +
- .../browser/user_script_loader.cc             | 721 ++++++++++++++++
- .../user_scripts/browser/user_script_loader.h | 170 ++++
- .../browser/user_script_pref_info.cc          |  34 +
- .../browser/user_script_pref_info.h           |  72 ++
- .../user_scripts/browser/user_script_prefs.cc | 276 ++++++
- .../user_scripts/browser/user_script_prefs.h  |  62 ++
- .../browser/userscripts_browser_client.cc     |  78 ++
- .../browser/userscripts_browser_client.h      |  62 ++
- components/user_scripts/common/BUILD.gn       |  49 ++
- components/user_scripts/common/constants.h    |  21 +
- components/user_scripts/common/error_utils.cc |  54 ++
- components/user_scripts/common/error_utils.h  |  24 +
- .../common/extension_message_generator.cc     |  29 +
- .../common/extension_message_generator.h      |  11 +
- .../user_scripts/common/extension_messages.cc |  40 +
- .../user_scripts/common/extension_messages.h  |  71 ++
- components/user_scripts/common/host_id.cc     |  31 +
- components/user_scripts/common/host_id.h      |  35 +
- .../user_scripts/common/script_constants.h    |  33 +
- components/user_scripts/common/url_pattern.cc | 803 ++++++++++++++++++
- components/user_scripts/common/url_pattern.h  | 302 +++++++
- .../user_scripts/common/url_pattern_set.cc    | 334 ++++++++
- .../user_scripts/common/url_pattern_set.h     | 161 ++++
- components/user_scripts/common/user_script.cc | 317 +++++++
- components/user_scripts/common/user_script.h  | 403 +++++++++
- .../common/user_scripts_features.cc           |  32 +
- .../common/user_scripts_features.h            |  34 +
- components/user_scripts/common/view_type.cc   |  39 +
- components/user_scripts/common/view_type.h    |  48 ++
- components/user_scripts/renderer/BUILD.gn     |  67 ++
- .../renderer/extension_frame_helper.cc        |  96 +++
- .../renderer/extension_frame_helper.h         |  92 ++
- .../user_scripts/renderer/injection_host.cc   |  12 +
- .../user_scripts/renderer/injection_host.h    |  42 +
- .../renderer/resources/greasemonkey_api.js    |  82 ++
- .../user_scripts_renderer_resources.grd       |  14 +
- .../user_scripts/renderer/script_context.cc   | 215 +++++
- .../user_scripts/renderer/script_context.h    |  70 ++
- .../user_scripts/renderer/script_injection.cc | 343 ++++++++
- .../user_scripts/renderer/script_injection.h  | 155 ++++
- .../renderer/script_injection_callback.cc     |  25 +
- .../renderer/script_injection_callback.h      |  39 +
- .../renderer/script_injection_manager.cc      | 417 +++++++++
- .../renderer/script_injection_manager.h       | 102 +++
- .../user_scripts/renderer/script_injector.h   |  96 +++
- .../user_scripts/renderer/scripts_run_info.cc |  31 +
- .../user_scripts/renderer/scripts_run_info.h  |  70 ++
- .../renderer/user_script_injector.cc          | 228 +++++
- .../renderer/user_script_injector.h           |  87 ++
- .../user_scripts/renderer/user_script_set.cc  | 259 ++++++
- .../user_scripts/renderer/user_script_set.h   | 102 +++
- .../renderer/user_script_set_manager.cc       |  77 ++
- .../renderer/user_script_set_manager.h        |  62 ++
- .../renderer/user_scripts_dispatcher.cc       |  36 +
- .../renderer/user_scripts_dispatcher.h        |  48 ++
- .../renderer/user_scripts_renderer_client.cc  | 105 +++
- .../renderer/user_scripts_renderer_client.h   |  36 +
- .../renderer/web_ui_injection_host.cc         |  40 +
- .../renderer/web_ui_injection_host.h          |  28 +
- .../strings/userscripts_strings.grdp          |  55 ++
- tools/gritsettings/resource_ids.spec          |   6 +
- 111 files changed, 9580 insertions(+), 2 deletions(-)
- create mode 100644 components/user_scripts/README.md
- create mode 100755 components/user_scripts/android/BUILD.gn
- create mode 100644 components/user_scripts/android/java/res/layout/accept_script_item.xml
- create mode 100644 components/user_scripts/android/java/res/layout/accept_script_list.xml
- create mode 100644 components/user_scripts/android/java/res/layout/scripts_preference.xml
- create mode 100755 components/user_scripts/android/java/res/values/dimens.xml
- create mode 100644 components/user_scripts/android/java/res/xml/userscripts_preferences.xml
- create mode 100755 components/user_scripts/android/java/src/org/chromium/chrome/browser/user_scripts/UserScriptsUtils.java
- create mode 100644 components/user_scripts/android/java/src/org/chromium/components/user_scripts/FragmentWindowAndroid.java
- create mode 100644 components/user_scripts/android/java/src/org/chromium/components/user_scripts/IUserScriptsUtils.java
- create mode 100644 components/user_scripts/android/java/src/org/chromium/components/user_scripts/ScriptInfo.java
- create mode 100644 components/user_scripts/android/java/src/org/chromium/components/user_scripts/ScriptListBaseAdapter.java
- create mode 100644 components/user_scripts/android/java/src/org/chromium/components/user_scripts/ScriptListPreference.java
- create mode 100644 components/user_scripts/android/java/src/org/chromium/components/user_scripts/UserScriptsBridge.java
- create mode 100755 components/user_scripts/android/java/src/org/chromium/components/user_scripts/UserScriptsPreferences.java
- create mode 100644 components/user_scripts/android/java_sources.gni
- create mode 100644 components/user_scripts/android/user_scripts_bridge.cc
- create mode 100644 components/user_scripts/android/user_scripts_bridge.h
- create mode 100755 components/user_scripts/browser/BUILD.gn
- create mode 100755 components/user_scripts/browser/file_task_runner.cc
- create mode 100755 components/user_scripts/browser/file_task_runner.h
- create mode 100644 components/user_scripts/browser/resources/browser_resources.grd
- create mode 100644 components/user_scripts/browser/resources/user-script-ui/BUILD.gn
- create mode 100644 components/user_scripts/browser/resources/user-script-ui/user-scripts-ui.html
- create mode 100644 components/user_scripts/browser/resources/user-script-ui/user-scripts-ui.js
- create mode 100644 components/user_scripts/browser/ui/user_scripts_ui.cc
- create mode 100644 components/user_scripts/browser/ui/user_scripts_ui.h
- create mode 100755 components/user_scripts/browser/user_script_loader.cc
- create mode 100755 components/user_scripts/browser/user_script_loader.h
- create mode 100644 components/user_scripts/browser/user_script_pref_info.cc
- create mode 100644 components/user_scripts/browser/user_script_pref_info.h
- create mode 100644 components/user_scripts/browser/user_script_prefs.cc
- create mode 100644 components/user_scripts/browser/user_script_prefs.h
- create mode 100755 components/user_scripts/browser/userscripts_browser_client.cc
- create mode 100755 components/user_scripts/browser/userscripts_browser_client.h
- create mode 100755 components/user_scripts/common/BUILD.gn
- create mode 100755 components/user_scripts/common/constants.h
- create mode 100755 components/user_scripts/common/error_utils.cc
- create mode 100755 components/user_scripts/common/error_utils.h
- create mode 100755 components/user_scripts/common/extension_message_generator.cc
- create mode 100755 components/user_scripts/common/extension_message_generator.h
- create mode 100755 components/user_scripts/common/extension_messages.cc
- create mode 100755 components/user_scripts/common/extension_messages.h
- create mode 100755 components/user_scripts/common/host_id.cc
- create mode 100755 components/user_scripts/common/host_id.h
- create mode 100755 components/user_scripts/common/script_constants.h
- create mode 100755 components/user_scripts/common/url_pattern.cc
- create mode 100755 components/user_scripts/common/url_pattern.h
- create mode 100755 components/user_scripts/common/url_pattern_set.cc
- create mode 100755 components/user_scripts/common/url_pattern_set.h
- create mode 100755 components/user_scripts/common/user_script.cc
- create mode 100755 components/user_scripts/common/user_script.h
- create mode 100644 components/user_scripts/common/user_scripts_features.cc
- create mode 100644 components/user_scripts/common/user_scripts_features.h
- create mode 100755 components/user_scripts/common/view_type.cc
- create mode 100755 components/user_scripts/common/view_type.h
- create mode 100755 components/user_scripts/renderer/BUILD.gn
- create mode 100755 components/user_scripts/renderer/extension_frame_helper.cc
- create mode 100755 components/user_scripts/renderer/extension_frame_helper.h
- create mode 100755 components/user_scripts/renderer/injection_host.cc
- create mode 100755 components/user_scripts/renderer/injection_host.h
- create mode 100755 components/user_scripts/renderer/resources/greasemonkey_api.js
- create mode 100755 components/user_scripts/renderer/resources/user_scripts_renderer_resources.grd
- create mode 100755 components/user_scripts/renderer/script_context.cc
- create mode 100755 components/user_scripts/renderer/script_context.h
- create mode 100755 components/user_scripts/renderer/script_injection.cc
- create mode 100755 components/user_scripts/renderer/script_injection.h
- create mode 100755 components/user_scripts/renderer/script_injection_callback.cc
- create mode 100755 components/user_scripts/renderer/script_injection_callback.h
- create mode 100755 components/user_scripts/renderer/script_injection_manager.cc
- create mode 100755 components/user_scripts/renderer/script_injection_manager.h
- create mode 100755 components/user_scripts/renderer/script_injector.h
- create mode 100755 components/user_scripts/renderer/scripts_run_info.cc
- create mode 100755 components/user_scripts/renderer/scripts_run_info.h
- create mode 100755 components/user_scripts/renderer/user_script_injector.cc
- create mode 100755 components/user_scripts/renderer/user_script_injector.h
- create mode 100755 components/user_scripts/renderer/user_script_set.cc
- create mode 100755 components/user_scripts/renderer/user_script_set.h
- create mode 100755 components/user_scripts/renderer/user_script_set_manager.cc
- create mode 100755 components/user_scripts/renderer/user_script_set_manager.h
- create mode 100755 components/user_scripts/renderer/user_scripts_dispatcher.cc
- create mode 100755 components/user_scripts/renderer/user_scripts_dispatcher.h
- create mode 100755 components/user_scripts/renderer/user_scripts_renderer_client.cc
- create mode 100755 components/user_scripts/renderer/user_scripts_renderer_client.h
- create mode 100755 components/user_scripts/renderer/web_ui_injection_host.cc
- create mode 100755 components/user_scripts/renderer/web_ui_injection_host.h
- create mode 100755 components/user_scripts/strings/userscripts_strings.grdp
-
-diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
---- a/chrome/android/BUILD.gn
-+++ b/chrome/android/BUILD.gn
-@@ -252,6 +252,10 @@ android_resources("chrome_app_java_resources") {
-     "//third_party/androidx:androidx_preference_preference_java",
-     "//third_party/androidx:androidx_recyclerview_recyclerview_java",
-   ]
-+
-+  # this need to be into android_resources("chrome_app_java_resources") section because
-+  # android:java_resources are packed *_percent.pak and placed in the executable folder
-+  deps += [ "//components/user_scripts/android:java_resources" ]
- }
- 
- if (enable_vr) {
-@@ -517,6 +521,7 @@ android_library("chrome_java") {
-     "//components/ukm/android:java",
-     "//components/url_formatter/android:url_formatter_java",
-     "//components/user_prefs/android:java",
-+    "//components/user_scripts/android:java",
-     "//components/variations/android:variations_java",
-     "//components/version_info/android:version_constants_java",
-     "//components/viz/common:common_java",
-diff --git a/chrome/android/java/res/xml/main_preferences.xml b/chrome/android/java/res/xml/main_preferences.xml
---- a/chrome/android/java/res/xml/main_preferences.xml
-+++ b/chrome/android/java/res/xml/main_preferences.xml
-@@ -86,6 +86,11 @@
-         android:key="useragent_settings"
-         android:order="20"
-         android:title="@string/prefs_useragent_settings"/>
-+    <Preference
-+        android:fragment="org.chromium.components.user_scripts.UserScriptsPreferences"
-+        android:key="userscripts_settings"
-+        android:order="20"
-+        android:title="@string/prefs_userscripts_settings"/>
-     <Preference
-         android:fragment="org.chromium.chrome.browser.language.settings.LanguageSettings"
-         android:key="languages"
-diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java
---- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java
-+++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadUtils.java
-@@ -68,6 +68,7 @@ import org.chromium.content_public.browser.BrowserStartupController;
- import org.chromium.content_public.browser.LoadUrlParams;
- import org.chromium.ui.base.DeviceFormFactor;
- import org.chromium.ui.widget.Toast;
-+import org.chromium.chrome.browser.user_scripts.UserScriptsUtils;
- 
- import java.io.File;
- 
-@@ -419,6 +420,11 @@ public class DownloadUtils {
-     public static boolean openFile(String filePath, String mimeType, String downloadGuid,
-             OTRProfileID otrProfileID, String originalUrl, String referrer,
-             @DownloadOpenSource int source, Context context) {
-+        if (UserScriptsUtils.getInstance().openFile(filePath, mimeType, downloadGuid,
-+                                                    originalUrl, referrer,
-+                                                    getUriForItem(filePath))) {
-+            return true;
-+        }
-         DownloadMetrics.recordDownloadOpen(source, mimeType);
-         DownloadManagerService service = DownloadManagerService.getDownloadManagerService();
- 
-diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java
---- a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java
-+++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessInitializationHandler.java
-@@ -111,6 +111,8 @@ import java.util.Date;
- import java.util.List;
- import java.util.Locale;
- 
-+import org.chromium.chrome.browser.user_scripts.UserScriptsUtils;
-+
- /**
-  * Handles the initialization dependences of the browser process.  This is meant to handle the
-  * initialization that is not tied to any particular Activity, and the logic that should only be
-@@ -285,6 +287,7 @@ public class ProcessInitializationHandler {
- 
-                 DefaultBrowserInfo.initBrowserFetcher();
- 
-+                UserScriptsUtils.Initialize();
-                 AfterStartupTaskUtils.setStartupComplete();
- 
-                 PartnerBrowserCustomizations.getInstance().setOnInitializeAsyncFinished(
-diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
---- a/chrome/android/java_sources.gni
-+++ b/chrome/android/java_sources.gni
-@@ -23,6 +23,7 @@ import("//components/feed/features.gni")
- import("//components/offline_pages/buildflags/features.gni")
- import("//components/omnibox/browser/test_java_sources.gni")
- import("//device/vr/buildflags/buildflags.gni")
-+import("//components/user_scripts/android/java_sources.gni")
- 
- chrome_java_sources += public_autofill_assistant_java_sources
- 
-@@ -60,3 +61,5 @@ if (enable_arcore) {
-     "java/src/org/chromium/chrome/browser/vr/ArDelegateImpl.java",
-   ]
- }
-+
-+chrome_java_sources += userscripts_java_sources
-diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
---- a/chrome/browser/BUILD.gn
-+++ b/chrome/browser/BUILD.gn
-@@ -3454,6 +3454,11 @@ static_library("browser") {
-       ]
-       deps += [ "//chrome/android/modules/dev_ui/provider:native" ]
-     }
-+    deps += [
-+      "//components/user_scripts/common",
-+      "//components/user_scripts/browser",
-+      "//components/user_scripts/android",
-+    ]
-   } else {
-     #!is_android
-     sources += [
-diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
---- a/chrome/browser/about_flags.cc
-+++ b/chrome/browser/about_flags.cc
-@@ -147,6 +147,7 @@
- #include "components/translate/core/browser/translate_ranker_impl.h"
- #include "components/translate/core/common/translate_util.h"
- #include "components/ui_devtools/switches.h"
-+#include "components/user_scripts/common/user_scripts_features.h"
- #include "components/version_info/version_info.h"
- #include "components/viz/common/features.h"
- #include "components/viz/common/switches.h"
-@@ -6591,6 +6592,10 @@ const FeatureEntry kFeatureEntries[] = {
-      FEATURE_VALUE_TYPE(features::kUserDataSnapshot)},
- #endif
- 
-+    {"enable-userscripts-log", flag_descriptions::kEnableLoggingUserScriptsName,
-+     flag_descriptions::kEnableLoggingUserScriptsDescription, kOsDesktop | kOsAndroid,
-+     FEATURE_VALUE_TYPE(user_scripts::features::kEnableLoggingUserScripts)},
-+
- #if defined(OS_WIN)
-     {"run-video-capture-service-in-browser",
-      flag_descriptions::kRunVideoCaptureServiceInBrowserProcessName,
-diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
---- a/chrome/browser/chrome_content_browser_client.cc
-+++ b/chrome/browser/chrome_content_browser_client.cc
-@@ -4480,7 +4480,8 @@ ChromeContentBrowserClient::CreateURLLoaderThrottles(
-   chrome::mojom::DynamicParams dynamic_params = {
-       profile->GetPrefs()->GetBoolean(prefs::kForceGoogleSafeSearch),
-       profile->GetPrefs()->GetInteger(prefs::kForceYouTubeRestrict),
--      profile->GetPrefs()->GetString(prefs::kAllowedDomainsForApps)};
-+      profile->GetPrefs()->GetString(prefs::kAllowedDomainsForApps),
-+      false /*-> allow_userscript, don't care */};
-   result.push_back(std::make_unique<GoogleURLLoaderThrottle>(
- #if defined(OS_ANDROID)
-       client_data_header, is_tab_large_enough,
-diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
---- a/chrome/browser/flag_descriptions.cc
-+++ b/chrome/browser/flag_descriptions.cc
-@@ -5358,6 +5358,11 @@ const char kUserDataSnapshotDescription[] =
-     "update and restoring them after a version rollback.";
- #endif  // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
- 
-+const char kEnableLoggingUserScriptsName[] = "Enable logging user scripts component";
-+const char kEnableLoggingUserScriptsDescription[] =
-+    "Enables logging for troubleshooting feature. "
-+    "Enabling logs may make browsing slower.";
-+
- #if defined(OS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_MAC)
- const char kWebShareName[] = "Web Share";
- const char kWebShareDescription[] =
-diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
---- a/chrome/browser/flag_descriptions.h
-+++ b/chrome/browser/flag_descriptions.h
-@@ -3125,6 +3125,9 @@ extern const char kUserDataSnapshotName[];
- extern const char kUserDataSnapshotDescription[];
- #endif  // !defined(OS_ANDROID) && !BUILDFLAG(IS_CHROMEOS_ASH)
- 
-+extern const char kEnableLoggingUserScriptsName[];
-+extern const char kEnableLoggingUserScriptsDescription[];
-+
- #if defined(OS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH) || defined(OS_MAC)
- extern const char kWebShareName[];
- extern const char kWebShareDescription[];
-diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
---- a/chrome/browser/prefs/browser_prefs.cc
-+++ b/chrome/browser/prefs/browser_prefs.cc
-@@ -233,6 +233,7 @@
- #include "components/ntp_tiles/popular_sites_impl.h"
- #include "components/permissions/contexts/geolocation_permission_context_android.h"
- #include "components/query_tiles/tile_service_prefs.h"
-+#include "components/user_scripts/browser/user_script_prefs.h"
- #else  // defined(OS_ANDROID)
- #include "chrome/browser/cart/cart_service.h"
- #include "chrome/browser/device_api/device_service_impl.h"
-@@ -1177,6 +1178,7 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry,
-   translate::TranslatePrefs::RegisterProfilePrefs(registry);
-   omnibox::RegisterProfilePrefs(registry);
-   ZeroSuggestProvider::RegisterProfilePrefs(registry);
-+  user_scripts::UserScriptsPrefs::RegisterProfilePrefs(registry);
- 
- #if BUILDFLAG(ENABLE_SESSION_SERVICE)
-   RegisterSessionServiceLogProfilePrefs(registry);
-diff --git a/chrome/browser/profiles/BUILD.gn b/chrome/browser/profiles/BUILD.gn
---- a/chrome/browser/profiles/BUILD.gn
-+++ b/chrome/browser/profiles/BUILD.gn
-@@ -45,6 +45,7 @@ source_set("profile") {
-     "//components/profile_metrics",
-     "//components/sync/driver",
-     "//components/variations",
-+    "//components/user_scripts/browser",
-     "//content/public/browser",
-     "//extensions/buildflags",
-   ]
-diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
---- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
-+++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
-@@ -214,6 +214,8 @@
- #include "chrome/browser/ui/cocoa/screentime/screentime_features.h"
- #endif
- 
-+#include "components/user_scripts/browser/userscripts_browser_client.h"
-+
- namespace chrome {
- 
- void AddProfilesExtraParts(ChromeBrowserMainParts* main_parts) {
-@@ -506,6 +508,7 @@ void ChromeBrowserMainExtraPartsProfiles::
- #endif
-   WebDataServiceFactory::GetInstance();
-   webrtc_event_logging::WebRtcEventLogManagerKeyedServiceFactory::GetInstance();
-+  user_scripts::UserScriptsBrowserClient::GetInstance();
- }
- 
- void ChromeBrowserMainExtraPartsProfiles::PreProfileInit() {
-diff --git a/chrome/browser/profiles/profile_manager.cc b/chrome/browser/profiles/profile_manager.cc
---- a/chrome/browser/profiles/profile_manager.cc
-+++ b/chrome/browser/profiles/profile_manager.cc
-@@ -114,6 +114,8 @@
- #include "extensions/common/manifest.h"
- #endif
- 
-+#include "components/user_scripts/browser/userscripts_browser_client.h"
-+
- #if BUILDFLAG(ENABLE_SESSION_SERVICE)
- #include "chrome/browser/sessions/session_service_factory.h"
- #endif
-@@ -1522,6 +1524,13 @@ void ProfileManager::DoFinalInitForServices(Profile* profile,
-   }
- 
- #endif
-+
-+  user_scripts::UserScriptsBrowserClient* userscript_client =
-+    user_scripts::UserScriptsBrowserClient::GetInstance();
-+  if (userscript_client) {
-+    userscript_client->SetProfile(profile);
-+  }
-+
- #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
-   // Initialization needs to happen after extension system initialization (for
-   // extension::ManagementPolicy) and InitProfileUserPrefs (for setting the
-diff --git a/chrome/browser/profiles/renderer_updater.cc b/chrome/browser/profiles/renderer_updater.cc
---- a/chrome/browser/profiles/renderer_updater.cc
-+++ b/chrome/browser/profiles/renderer_updater.cc
-@@ -29,6 +29,8 @@
- #include "chrome/browser/ash/login/signin/oauth2_login_manager_factory.h"
- #endif
- 
-+#include "components/user_scripts/browser/user_script_prefs.h"
-+
- namespace {
- 
- #if BUILDFLAG(ENABLE_EXTENSIONS)
-@@ -75,6 +77,7 @@ RendererUpdater::RendererUpdater(Profile* profile) : profile_(profile) {
-   force_google_safesearch_.Init(prefs::kForceGoogleSafeSearch, pref_service);
-   force_youtube_restrict_.Init(prefs::kForceYouTubeRestrict, pref_service);
-   allowed_domains_for_apps_.Init(prefs::kAllowedDomainsForApps, pref_service);
-+  activate_userscripts_.Init(user_scripts::prefs::kUserScriptsEnabled, pref_service);
- 
-   pref_change_registrar_.Init(pref_service);
-   pref_change_registrar_.Add(
-@@ -89,6 +92,10 @@ RendererUpdater::RendererUpdater(Profile* profile) : profile_(profile) {
-       prefs::kAllowedDomainsForApps,
-       base::BindRepeating(&RendererUpdater::UpdateAllRenderers,
-                           base::Unretained(this)));
-+  pref_change_registrar_.Add(
-+      user_scripts::prefs::kUserScriptsEnabled,
-+      base::BindRepeating(&RendererUpdater::UpdateAllRenderers,
-+                          base::Unretained(this)));
- }
- 
- RendererUpdater::~RendererUpdater() {
-@@ -237,5 +244,6 @@ void RendererUpdater::UpdateRenderer(
-       ->SetConfiguration(chrome::mojom::DynamicParams::New(
-           force_google_safesearch_.GetValue(),
-           force_youtube_restrict_.GetValue(),
--          allowed_domains_for_apps_.GetValue()));
-+          allowed_domains_for_apps_.GetValue(),
-+          activate_userscripts_.GetValue()));
- }
-diff --git a/chrome/browser/profiles/renderer_updater.h b/chrome/browser/profiles/renderer_updater.h
---- a/chrome/browser/profiles/renderer_updater.h
-+++ b/chrome/browser/profiles/renderer_updater.h
-@@ -82,6 +82,7 @@ class RendererUpdater : public KeyedService,
- 
-   // Prefs that we sync to the renderers.
-   BooleanPrefMember force_google_safesearch_;
-+  BooleanPrefMember activate_userscripts_;
-   IntegerPrefMember force_youtube_restrict_;
-   StringPrefMember allowed_domains_for_apps_;
- 
-diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
---- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
-+++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
-@@ -84,6 +84,7 @@
- #include "components/security_interstitials/content/urls.h"
- #include "components/signin/public/base/signin_buildflags.h"
- #include "components/site_engagement/content/site_engagement_service.h"
-+#include "components/user_scripts/browser/ui/user_scripts_ui.h"
- #include "content/public/browser/web_contents.h"
- #include "content/public/browser/web_ui.h"
- #include "content/public/common/content_client.h"
-@@ -669,6 +670,8 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui,
-     return &NewWebUI<UserActionsUI>;
-   if (url.host_piece() == chrome::kChromeUIVersionHost)
-     return &NewWebUI<VersionUI>;
-+  if (url.host_piece() == user_scripts::kChromeUIUserScriptsHost)
-+    return &NewWebUI<user_scripts::UserScriptsUI>;
- 
- #if !defined(OS_ANDROID)
- #if !defined(OS_CHROMEOS)
-diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni
---- a/chrome/chrome_paks.gni
-+++ b/chrome/chrome_paks.gni
-@@ -105,6 +105,7 @@ template("chrome_extra_paks") {
-       "$root_gen_dir/third_party/blink/public/resources/inspector_overlay_resources.pak",
-       "$root_gen_dir/ui/resources/webui_generated_resources.pak",
-       "$root_gen_dir/ui/resources/webui_resources.pak",
-+      "$root_gen_dir/chrome/userscripts_browser_resources.pak",
-     ]
-     deps = [
-       "//base/tracing/protos:chrome_track_event_resources",
-@@ -120,6 +121,7 @@ template("chrome_extra_paks") {
-       "//third_party/blink/public:devtools_inspector_resources",
-       "//third_party/blink/public:resources",
-       "//ui/resources",
-+      "//components/user_scripts/browser:userscripts_browser_resources_grit",
-     ]
-     if (defined(invoker.deps)) {
-       deps += invoker.deps
-diff --git a/chrome/common/renderer_configuration.mojom b/chrome/common/renderer_configuration.mojom
---- a/chrome/common/renderer_configuration.mojom
-+++ b/chrome/common/renderer_configuration.mojom
-@@ -12,6 +12,7 @@ struct DynamicParams {
-   bool force_safe_search = true;
-   int32 youtube_restrict = 0;
-   string allowed_domains_for_apps;
-+  bool allow_userscript = false;
- };
- 
- interface ChromeOSListener {
-diff --git a/chrome/renderer/BUILD.gn b/chrome/renderer/BUILD.gn
---- a/chrome/renderer/BUILD.gn
-+++ b/chrome/renderer/BUILD.gn
-@@ -171,6 +171,7 @@ static_library("renderer") {
-     "//components/feed:feature_list",
-     "//components/feed/content/renderer:feed_renderer",
-     "//components/history_clusters/core",
-+    "//components/user_scripts/renderer",
-     "//components/network_hints/renderer",
-     "//components/no_state_prefetch/common",
-     "//components/no_state_prefetch/renderer",
-diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
---- a/chrome/renderer/chrome_content_renderer_client.cc
-+++ b/chrome/renderer/chrome_content_renderer_client.cc
-@@ -251,6 +251,9 @@
- #include "chrome/renderer/supervised_user/supervised_user_error_page_controller_delegate_impl.h"
- #endif
- 
-+#include "components/user_scripts/common/user_scripts_features.h"
-+#include "components/user_scripts/renderer/user_scripts_renderer_client.h"
-+
- using autofill::AutofillAgent;
- using autofill::AutofillAssistantAgent;
- using autofill::PasswordAutofillAgent;
-@@ -416,6 +419,12 @@ void ChromeContentRendererClient::RenderThreadStarted() {
-       WebString::FromASCII(extensions::kExtensionScheme));
- #endif
- 
-+  user_scripts::UserScriptsRendererClient* userscript_client =
-+    user_scripts::UserScriptsRendererClient::GetInstance();
-+  if (userscript_client) {
-+    userscript_client->RenderThreadStarted();
-+  }
-+
- #if BUILDFLAG(ENABLE_SPELLCHECK)
-   if (!spellcheck_)
-     InitSpellCheck();
-@@ -552,6 +561,13 @@ void ChromeContentRendererClient::RenderFrameCreated(
-       render_frame, registry);
- #endif
- 
-+  user_scripts::UserScriptsRendererClient* userscript_client =
-+    user_scripts::UserScriptsRendererClient::GetInstance();
-+  if (userscript_client) {
-+    userscript_client->RenderFrameCreated(
-+      render_frame, registry);
-+  }
-+
- #if BUILDFLAG(ENABLE_PLUGINS)
-   new PepperHelper(render_frame);
- #endif
-@@ -1549,7 +1565,14 @@ void ChromeContentRendererClient::RunScriptsAtDocumentStart(
-   ChromeExtensionsRendererClient::GetInstance()->RunScriptsAtDocumentStart(
-       render_frame);
-   // |render_frame| might be dead by now.
-+  static_assert(false, "Compiler error: extensions cannot be enabled with user scripts");
- #endif
-+  user_scripts::UserScriptsRendererClient* userscript_client =
-+    user_scripts::UserScriptsRendererClient::GetInstance();
-+  if (userscript_client) {
-+    userscript_client->RunScriptsAtDocumentStart(
-+      render_frame);
-+  }
- }
- 
- void ChromeContentRendererClient::RunScriptsAtDocumentEnd(
-@@ -1558,7 +1581,14 @@ void ChromeContentRendererClient::RunScriptsAtDocumentEnd(
-   ChromeExtensionsRendererClient::GetInstance()->RunScriptsAtDocumentEnd(
-       render_frame);
-   // |render_frame| might be dead by now.
-+  static_assert(false, "Compiler error: extensions cannot be enabled with user scripts");
- #endif
-+  user_scripts::UserScriptsRendererClient* userscript_client =
-+    user_scripts::UserScriptsRendererClient::GetInstance();
-+  if (userscript_client) {
-+    userscript_client->RunScriptsAtDocumentEnd(
-+      render_frame);
-+  }
- }
- 
- void ChromeContentRendererClient::RunScriptsAtDocumentIdle(
-@@ -1567,7 +1597,14 @@ void ChromeContentRendererClient::RunScriptsAtDocumentIdle(
-   ChromeExtensionsRendererClient::GetInstance()->RunScriptsAtDocumentIdle(
-       render_frame);
-   // |render_frame| might be dead by now.
-+  static_assert(false, "Compiler error: extensions cannot be enabled with user scripts");
- #endif
-+  user_scripts::UserScriptsRendererClient* userscript_client =
-+    user_scripts::UserScriptsRendererClient::GetInstance();
-+  if (userscript_client) {
-+    userscript_client->RunScriptsAtDocumentIdle(
-+      render_frame);
-+  }
- }
- 
- void ChromeContentRendererClient::
-diff --git a/chrome/renderer/chrome_render_thread_observer.cc b/chrome/renderer/chrome_render_thread_observer.cc
---- a/chrome/renderer/chrome_render_thread_observer.cc
-+++ b/chrome/renderer/chrome_render_thread_observer.cc
-@@ -59,6 +59,8 @@
- #include "third_party/blink/public/web/web_security_policy.h"
- #include "third_party/blink/public/web/web_view.h"
- 
-+#include "components/user_scripts/renderer/user_scripts_renderer_client.h"
-+
- #if BUILDFLAG(ENABLE_EXTENSIONS)
- #include "chrome/renderer/extensions/extension_localization_peer.h"
- #endif
-@@ -255,6 +257,7 @@ void ChromeRenderThreadObserver::SetInitialConfiguration(
- void ChromeRenderThreadObserver::SetConfiguration(
-     chrome::mojom::DynamicParamsPtr params) {
-   *GetDynamicConfigParams() = std::move(*params);
-+  user_scripts::UserScriptsRendererClient::GetInstance()->ConfigurationUpdated();
- }
- 
- void ChromeRenderThreadObserver::SetContentSettingRules(
-diff --git a/components/components_strings.grd b/components/components_strings.grd
---- a/components/components_strings.grd
-+++ b/components/components_strings.grd
-@@ -335,6 +335,7 @@
-       <part file="undo_strings.grdp" />
-       <part file="version_ui_strings.grdp" />
-       <part file="webapps_strings.grdp" />
-+      <part file="user_scripts/strings/userscripts_strings.grdp" />
- 
-       <if expr="not is_android and not is_ios">
-         <part file="management_strings.grdp" />
-diff --git a/components/user_scripts/README.md b/components/user_scripts/README.md
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/README.md
-@@ -0,0 +1,150 @@
-+# Userscripts support for Bromite
-+
-+UserScript support is under user setting currently disabled by default: when disabled, no code that can impact navigation safety is active.
-+
-+Activation allows the use of userscripts in Bromite. It is possible to add them in two ways:
-+- by selecting files from the file picker in the settings
-+- downloading the scripts and opening it from downloads (only if ends with .user.js)
-+The new imported scripts are disabled by default: they can be activated via the menu visible on the ui.
-+
-+Userscript support is currently the one provided by the desktop version. The enabled headers are:
-+
-+- `@name`
-+- `@version`
-+- `@description`
-+- `@url` or `@homepage`
-+- `@include`, `@exclude`, `@match`, `@exclude_match` for the url pattern (only http e https)
-+- `@run-at`
-+    - `document-start`
-+        Start the script after the documentElement is created, but before anything else happens
-+	- `document-end`
-+        Start the script after the entire document is parsed. Same as DOMContentLoaded
-+	- `document-idle`
-+        Start the script sometime after DOMContentLoaded, as soon as the document is "idle". Currently this uses the simple heuristic of: min(DOM_CONTENT_LOADED + TIMEOUT, ONLOAD), but no particular injection point is guaranteed
-+
-+The url-patterns are so defined:
-+```
-+// <url-pattern> := <scheme>://<host><port><path> | '<all_urls>'
-+// <scheme> := '*' | 'http' | 'https'
-+// <host> := '*' | <IPv4 address> | [<IPv6 address>] |
-+//           '*.' <anychar except '/' and '*'>+
-+// <port> := [':' ('*' | <port number between 0 and 65535>)]
-+// <path> := '/' <any chars>
-+//
-+// * Host is not used when the scheme is 'file'.
-+// * The path can have embedded '*' characters which act as glob wildcards.
-+// * '<all_urls>' is a special pattern that matches any valid URL that contains
-+//   a valid scheme (as specified by valid_schemes_).
-+// * The '*' scheme pattern excludes file URLs.
-+//
-+// Examples of valid patterns:
-+// - http://*/*
-+// - http://*/foo*
-+// - https://*.google.com/foo*bar
-+// - file://monkey*
-+// - http://127.0.0.1/*
-+// - http://[2607:f8b0:4005:805::200e]/*
-+//
-+// Examples of invalid patterns:
-+// - http://* -- path not specified
-+// - http://*foo/bar -- * not allowed as substring of host component
-+// - http://foo.*.bar/baz -- * must be first component
-+// - http:/bar -- scheme separator not found
-+// - foo://* -- invalid scheme
-+// - chrome:// -- we don't support chrome internal URLs
-+```
-+
-+---
-+## **Beware of the scripts you enter: they can be a source of security problems, you are injecting code into your navigation**.
-+---
-+## Technical aspects
-+
-+`user_scripts/common` and `user_scripts/renderer` is the closest to the current chromium code: few changes there, mostly eliminated the superfluous extension related code.
-+
-+In `user_scripts/browser` you find the actual management (in the browser process) and in `android` basically the settings ui.
-+
-+At startup it tries to read all files in the `userscripts folder` in `/data/user/0/org.bromite.bromite/app_chrome/userscripts`: this could be a critical process because a crash would prevent the browser from opening, and that's why there is a crash counter that automatically disables the feature after three attempts if it encounters a problem during startup.
-+
-+The java ui allows userscript management: addition, deletion and activation/deactivation. Any errors while reading the scripts are presented to the user: scripts with errors cannot be activated. There is also the visualization of the script source and the open of its homepage (if foreseen) in incognito browsing.
-+
-+There is also support for an on-line help at https://github.com/bromite/bromite/wiki/UserScripts.
-+
-+
-+Entry points are `components/user_scripts/browser/userscripts_browser_client.cc` and `components/user_scripts/renderer/user_scripts_renderer_client.cc`: the two attach to the browser and the renderer process.
-+
-+for userscripts_browser_client.cc
-+- `chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc`
-+builds the browser side. also gpu process passes here, but the call is avoided.
-+
-+- `chrome/browser/profiles/profile_manager.cc`
-+set the profile
-+
-+for renderer/user_scripts_renderer_client.cc
-+- `chrome/renderer/chrome_content_renderer_client.cc`
-+at the renderer side
-+
-+the two sides have a life of their own and can communicate only via ipc, the renderer does not have access to the disk while the browser does only via its own task runner file (`components/user_scripts/browser/file_task_runner.cc`).
-+
-+## BROWSER PROCESS
-+Once the profile is set, it istance the `components/user_scripts/browser/user_script_loader.cc` and starts it.
-+This loads all the files in the folder into the runner file and interprets them. Control then passes to
-+`components/user_scripts/browser/user_script_prefs.cc` which verifies through the default profile what the user wants active.
-+At that point it passes through IPC to the renderer only the list of active scripts.
-+
-+## RENDERER PROCESS
-+Each time a frame is created, the script pattern is checked and it is injected into the three stages (START, IDLE, END).
-+The logic is all in `components/user_scripts/renderer/user_script_set.cc`.
-+
-+## Simple example
-+Here you find a working example that eliminates the google popup, useful in always incognito:
-+```
-+// ==UserScript==
-+// @name         Remove Google Consent
-+// @namespace    google
-+// @version      0.0.1
-+// @description  Autohide Accepts Cookies
-+// @author       uazo
-+// @match        https://*.google.com/search?*
-+// @grant        none
-+// @run-at       document-start
-+// ==/UserScript==
-+
-+(function() {
-+    'use strict';
-+
-+    var prepareStyleSheet = function() {
-+        var style = document.createElement('style');
-+        //style.setAttribute('media', 'screen');
-+        style.appendChild(document.createTextNode(''));
-+        document.head.appendChild(style);
-+        style.sheet.insertRule('body { overflow:scroll !important;position:unset !important }');
-+    };
-+
-+	var hideConsent = function() {
-+		document.getElementById("lb").style.display = "none";
-+	};
-+
-+    var checkElementThenRun = function(selector, func) {
-+        var el = document.querySelector(selector);
-+        if ( el == null ) {
-+            if (window.requestAnimationFrame != undefined) {
-+                window.requestAnimationFrame(function(){ checkElementThenRun(selector, func)});
-+            } else {
-+                document.addEventListener('readystatechange', function(e) {
-+                    if (document.readyState == 'complete') {
-+                        func();
-+                    }
-+                });
-+            }
-+        } else {
-+            func();
-+        }
-+    }
-+
-+    document.cookie = 'CONSENT=YES+IT.it+V13+BX;domain=.google.com';
-+    checkElementThenRun('head', prepareStyleSheet);
-+    checkElementThenRun('#lb', hideConsent);
-+})();
-+```
-+
-+See also: https://github.com/bromite/bromite/pull/857
-diff --git a/components/user_scripts/android/BUILD.gn b/components/user_scripts/android/BUILD.gn
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/android/BUILD.gn
-@@ -0,0 +1,80 @@
-+# This file is part of Bromite.
-+
-+# Bromite 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.
-+
-+# Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+
-+import("//build/config/android/rules.gni")
-+
-+generate_jni("user_scripts_jni_headers") {
-+  sources = [ "java/src/org/chromium/components/user_scripts/UserScriptsBridge.java" ]
-+}
-+
-+android_resources("java_resources") {
-+  sources = [
-+    "java/res/xml/userscripts_preferences.xml",
-+    "java/res/layout/accept_script_item.xml",
-+    "java/res/layout/accept_script_list.xml",
-+    "java/res/layout/scripts_preference.xml",
-+    "java/res/values/dimens.xml"
-+   ]
-+
-+  deps = [
-+    "//components/browser_ui/strings/android:browser_ui_strings_grd",
-+    "//components/browser_ui/styles/android:java_resources",
-+    "//components/strings:components_strings_grd",
-+    "//ui/android:ui_java_resources",
-+  ]
-+}
-+
-+android_library("java") {
-+  sources = [
-+    "java/src/org/chromium/components/user_scripts/FragmentWindowAndroid.java",
-+    "java/src/org/chromium/components/user_scripts/UserScriptsPreferences.java",
-+    "java/src/org/chromium/components/user_scripts/UserScriptsBridge.java",
-+    "java/src/org/chromium/components/user_scripts/IUserScriptsUtils.java",
-+    "java/src/org/chromium/components/user_scripts/ScriptListBaseAdapter.java",
-+    "java/src/org/chromium/components/user_scripts/ScriptListPreference.java",
-+    "java/src/org/chromium/components/user_scripts/ScriptInfo.java",
-+  ]
-+  deps = [
-+    ":java_resources",
-+    "//base:base_java",
-+    "//base:jni_java",
-+    "//components/embedder_support/android:browser_context_java",
-+    "//components/browser_ui/settings/android:java",
-+    "//components/browser_ui/widget/android:java",
-+    "//content/public/android:content_java",
-+    "//components/prefs/android:java",
-+    "//third_party/android_deps:android_support_v7_appcompat_java",
-+    "//third_party/androidx:androidx_annotation_annotation_java",
-+    "//third_party/androidx:androidx_appcompat_appcompat_resources_java",
-+    "//third_party/androidx:androidx_preference_preference_java",
-+    "//ui/android:ui_java",
-+  ]
-+  resources_package = "org.chromium.components.user_scripts"
-+  annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
-+}
-+
-+source_set("android") {
-+  sources = [
-+    "user_scripts_bridge.cc",
-+    "user_scripts_bridge.h",
-+  ]
-+  deps = [
-+    ":user_scripts_jni_headers",
-+    "//base",
-+    "//components/user_scripts/browser",
-+    "//components/permissions",
-+    "//content/public/browser",
-+  ]
-+}
-diff --git a/components/user_scripts/android/java/res/layout/accept_script_item.xml b/components/user_scripts/android/java/res/layout/accept_script_item.xml
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/android/java/res/layout/accept_script_item.xml
-@@ -0,0 +1,160 @@
-+<?xml version="1.0" encoding="utf-8"?>
-+<!-- Copyright 2017 The Chromium Authors. All rights reserved.
-+     Use of this source code is governed by a BSD-style license that can be
-+     found in the LICENSE file. -->
-+
-+<LinearLayout
-+    xmlns:android="http://schemas.android.com/apk/res/android"
-+    xmlns:app="http://schemas.android.com/apk/res-auto"
-+    xmlns:tools="http://schemas.android.com/tools"
-+    android:layout_width="match_parent"
-+    android:layout_height="wrap_content"
-+    android:orientation="vertical"
-+    android:layout_gravity="center_vertical" >
-+
-+    <LinearLayout
-+        android:layout_marginStart="0dp"
-+        android:paddingStart="@dimen/draggable_list_item_padding"
-+        android:paddingEnd="@dimen/draggable_list_item_padding"
-+        style="@style/ListItemContainer">
-+
-+        <Switch
-+            android:id="@+id/switch_widget"
-+            android:layout_width="wrap_content"
-+            android:layout_height="wrap_content"
-+            android:paddingEnd="15dp"
-+            android:focusable="false"
-+            android:background="@null" />
-+
-+        <LinearLayout
-+            android:layout_width="0dp"
-+            android:layout_height="wrap_content"
-+            android:layout_weight="1"
-+            android:orientation="vertical"
-+            android:layout_gravity="center_vertical" >
-+
-+            <TextView
-+                android:id="@+id/title"
-+                android:layout_width="match_parent"
-+                android:layout_height="wrap_content"
-+                style="@style/PreferenceTitle" />
-+
-+            <TextView
-+                android:id="@+id/description"
-+                android:layout_width="match_parent"
-+                android:layout_height="wrap_content"
-+                style="@style/PreferenceSummary" />
-+
-+            <LinearLayout
-+                android:layout_width="match_parent"
-+                android:layout_height="wrap_content"
-+                android:layout_weight="1"
-+                android:paddingTop="5dp"
-+                android:layout_gravity="center_vertical" >
-+
-+               <TextView
-+                    android:layout_width="wrap_content"
-+                    android:layout_height="wrap_content"
-+                    android:paddingEnd="5dp"
-+                    style="@style/PreferenceSummary"
-+                    android:text="@string/scripts_item_version"
-+                    android:textStyle="bold" />
-+
-+                <TextView
-+                    android:id="@+id/version"
-+                    android:layout_width="match_parent"
-+                    android:layout_height="wrap_content"
-+                    style="@style/PreferenceSummary" />
-+
-+            </LinearLayout>
-+
-+            <LinearLayout
-+                android:layout_width="match_parent"
-+                android:layout_height="wrap_content"
-+                android:layout_weight="1"
-+                android:layout_gravity="center_vertical" >
-+
-+               <TextView
-+                    android:layout_width="wrap_content"
-+                    android:layout_height="wrap_content"
-+                    android:paddingEnd="5dp"
-+                    style="@style/PreferenceSummary"
-+                    android:text="@string/scripts_item_filename"
-+                    android:textStyle="bold" />
-+
-+                <TextView
-+                    android:id="@+id/file"
-+                    android:layout_width="match_parent"
-+                    android:layout_height="wrap_content"
-+                    style="@style/PreferenceSummary" />
-+
-+            </LinearLayout>
-+
-+            <LinearLayout
-+                android:id="@+id/url_container"
-+                android:layout_width="match_parent"
-+                android:layout_height="wrap_content"
-+                android:layout_weight="1"
-+                android:layout_gravity="center_vertical" >
-+
-+               <TextView
-+                    android:layout_width="wrap_content"
-+                    android:layout_height="wrap_content"
-+                    android:paddingEnd="5dp"
-+                    style="@style/PreferenceSummary"
-+                    android:text="@string/scripts_item_url"
-+                    android:textStyle="bold" />
-+
-+                <TextView
-+                    android:id="@+id/url"
-+                    android:layout_width="match_parent"
-+                    android:layout_height="wrap_content"
-+                    android:autoLink="web"
-+                    android:focusable="true"
-+                    android:linksClickable="true" />
-+
-+            </LinearLayout>
-+
-+        </LinearLayout>
-+
-+        <org.chromium.components.browser_ui.widget.listmenu.ListMenuButton
-+            android:id="@+id/more"
-+            android:layout_width="wrap_content"
-+            android:layout_height="match_parent"
-+            android:paddingStart="@dimen/default_list_row_padding"
-+            android:paddingEnd="@dimen/default_list_row_padding"
-+            android:background="@null"
-+            android:src="@drawable/ic_more_vert_24dp"
-+            app:menuMaxWidth="@dimen/pref_scripts_item_popup_width"
-+            app:tint="@color/default_icon_color_tint_list"
-+            tools:ignore="ContentDescription" />
-+
-+    </LinearLayout>
-+
-+    <LinearLayout
-+        android:id="@+id/error_layout"
-+        android:layout_marginStart="0dp"
-+        android:paddingStart="@dimen/draggable_list_item_padding"
-+        android:paddingEnd="2dp"
-+        android:layout_width="match_parent"
-+        android:layout_height="wrap_content"
-+        style="@style/ListItemContainer">
-+
-+        <org.chromium.ui.widget.ChromeImageView
-+                android:id="@+id/icon"
-+                android:layout_width="40dp"
-+                android:layout_height="wrap_content"
-+                android:paddingEnd="15dp"
-+                android:adjustViewBounds="true"
-+                android:importantForAccessibility="no"
-+                app:srcCompat="@drawable/ic_error_outline_red_24dp"/>
-+
-+        <TextView
-+            android:id="@+id/error"
-+            android:layout_width="match_parent"
-+            android:layout_height="wrap_content"
-+            android:textColor="#F00"
-+            style="@style/PreferenceSummary" />
-+
-+    </LinearLayout>
-+</LinearLayout>
-\ No newline at end of file
-diff --git a/components/user_scripts/android/java/res/layout/accept_script_list.xml b/components/user_scripts/android/java/res/layout/accept_script_list.xml
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/android/java/res/layout/accept_script_list.xml
-@@ -0,0 +1,10 @@
-+<?xml version="1.0" encoding="utf-8"?>
-+<!-- Copyright 2017 The Chromium Authors. All rights reserved.
-+     Use of this source code is governed by a BSD-style license that can be
-+     found in the LICENSE file. -->
-+
-+<androidx.recyclerview.widget.RecyclerView
-+    xmlns:android="http://schemas.android.com/apk/res/android"
-+    android:id="@+id/script_list"
-+    android:layout_width="match_parent"
-+    android:layout_height="wrap_content" />
-\ No newline at end of file
-diff --git a/components/user_scripts/android/java/res/layout/scripts_preference.xml b/components/user_scripts/android/java/res/layout/scripts_preference.xml
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/android/java/res/layout/scripts_preference.xml
-@@ -0,0 +1,40 @@
-+<?xml version="1.0" encoding="utf-8"?>
-+<!-- Copyright 2017 The Chromium Authors. All rights reserved.
-+     Use of this source code is governed by a BSD-style license that can be
-+     found in the LICENSE file. -->
-+
-+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-+    android:id="@+id/accept_scripts_list_container"
-+    style="@style/PreferenceLayout"
-+    android:layout_width="match_parent"
-+    android:layout_height="wrap_content"
-+    android:paddingStart="0dp"
-+    android:paddingEnd="0dp"
-+    android:padding="0dp"
-+    android:orientation="vertical" >
-+
-+    <TextView
-+        android:layout_width="match_parent"
-+        android:layout_height="wrap_content"
-+        android:padding="@dimen/draggable_list_item_padding"
-+        android:text="@string/scripts_list_description" />
-+
-+    <FrameLayout
-+        android:id="@android:id/widget_frame"
-+        android:layout_width="match_parent"
-+        android:layout_height="wrap_content" />
-+
-+    <TextView
-+        android:id="@+id/add_script"
-+        android:layout_width="match_parent"
-+        android:layout_height="wrap_content"
-+        android:background="?attr/selectableItemBackground"
-+        android:clickable="true"
-+        android:gravity="center_vertical"
-+        android:padding="@dimen/draggable_list_item_padding"
-+        android:paddingStart="@dimen/pref_scripts_add_button_padding"
-+        android:drawablePadding="@dimen/pref_scripts_add_button_padding"
-+        android:text="@string/add_script"
-+        style="@style/PreferenceTitle" />
-+
-+</LinearLayout>
-\ No newline at end of file
-diff --git a/components/user_scripts/android/java/res/values/dimens.xml b/components/user_scripts/android/java/res/values/dimens.xml
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/android/java/res/values/dimens.xml
-@@ -0,0 +1,11 @@
-+<?xml version="1.0" encoding="utf-8"?>
-+<!-- Copyright 2014 The Chromium Authors. All rights reserved.
-+     Use of this source code is governed by a BSD-style license that can be
-+     found in the LICENSE file. -->
-+
-+<resources xmlns:tools="http://schemas.android.com/tools">
-+
-+    <dimen name="pref_scripts_add_button_padding">24dp</dimen>
-+    <dimen name="pref_scripts_item_popup_width">260dp</dimen>
-+
-+</resources>
-diff --git a/components/user_scripts/android/java/res/xml/userscripts_preferences.xml b/components/user_scripts/android/java/res/xml/userscripts_preferences.xml
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/android/java/res/xml/userscripts_preferences.xml
-@@ -0,0 +1,34 @@
-+<?xml version="1.0" encoding="utf-8"?>
-+<!--
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+-->
-+
-+<PreferenceScreen
-+    xmlns:android="http://schemas.android.com/apk/res/android"
-+    xmlns:app="http://schemas.android.com/apk/res-auto">
-+
-+    <org.chromium.components.browser_ui.settings.ChromeSwitchPreference
-+        android:key="enabled_switch"
-+        android:title="@string/option_userscript_flag"
-+        android:summaryOn="@string/option_userscript_flag_on"
-+        android:summaryOff="@string/option_userscript_flag_off" />
-+
-+    <org.chromium.components.user_scripts.ScriptListPreference
-+        android:key="script_list"
-+        android:layout="@layout/scripts_preference"
-+        android:widgetLayout="@layout/accept_script_list" />
-+
-+</PreferenceScreen>
-diff --git a/components/user_scripts/android/java/src/org/chromium/chrome/browser/user_scripts/UserScriptsUtils.java b/components/user_scripts/android/java/src/org/chromium/chrome/browser/user_scripts/UserScriptsUtils.java
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/android/java/src/org/chromium/chrome/browser/user_scripts/UserScriptsUtils.java
-@@ -0,0 +1,84 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+package org.chromium.chrome.browser.user_scripts;
-+
-+import android.content.Context;
-+import android.content.Intent;
-+import android.provider.Browser;
-+import android.provider.MediaStore;
-+import android.net.Uri;
-+
-+import org.chromium.base.ContextUtils;
-+import org.chromium.base.ContentUriUtils;
-+import org.chromium.base.IntentUtils;
-+
-+import org.chromium.chrome.browser.IntentHandler;
-+import org.chromium.chrome.browser.settings.SettingsLauncherImpl;
-+import org.chromium.components.browser_ui.settings.SettingsLauncher;
-+
-+import org.chromium.components.user_scripts.UserScriptsPreferences;
-+import org.chromium.components.user_scripts.UserScriptsBridge;
-+import org.chromium.components.user_scripts.IUserScriptsUtils;
-+
-+public class UserScriptsUtils implements IUserScriptsUtils
-+{
-+    private static UserScriptsUtils instance;
-+
-+    private UserScriptsUtils() {}
-+
-+    public static void Initialize() {
-+        instance = new UserScriptsUtils();
-+        UserScriptsBridge.registerUtils(instance);
-+    }
-+
-+    public static UserScriptsUtils getInstance() {
-+        return instance;
-+    }
-+
-+    public boolean openFile(String filePath, String mimeType, String downloadGuid,
-+                            String originalUrl, String referrer, Uri contentUri) {
-+        if (UserScriptsBridge.isEnabled() == false) return false;
-+
-+        Context context = ContextUtils.getApplicationContext();
-+
-+        if (ContentUriUtils.isContentUri(filePath))
-+            filePath = ContentUriUtils.getDisplayName(contentUri, context,
-+                MediaStore.MediaColumns.DISPLAY_NAME);
-+
-+        if (filePath.toUpperCase().endsWith(".USER.JS") == false) return false;
-+
-+        SettingsLauncher settingsLauncher = new SettingsLauncherImpl();
-+        Intent intent = settingsLauncher.createSettingsActivityIntent(
-+                context, UserScriptsPreferences.class.getName(),
-+                UserScriptsPreferences.createFragmentArgsForInstall(filePath));
-+        IntentUtils.safeStartActivity(context, intent);
-+
-+        return true;
-+    }
-+
-+    public void openSourceFile(String scriptKey) {
-+        Context context = ContextUtils.getApplicationContext();
-+
-+        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("chrome://user-scripts/?key=" + scriptKey));
-+        intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
-+        intent.putExtra(Browser.EXTRA_CREATE_NEW_TAB, true);
-+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-+        intent.setPackage(context.getPackageName());
-+        IntentHandler.startChromeLauncherActivityForTrustedIntent(intent);
-+    }
-+}
-\ No newline at end of file
-diff --git a/components/user_scripts/android/java/src/org/chromium/components/user_scripts/FragmentWindowAndroid.java b/components/user_scripts/android/java/src/org/chromium/components/user_scripts/FragmentWindowAndroid.java
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/android/java/src/org/chromium/components/user_scripts/FragmentWindowAndroid.java
-@@ -0,0 +1,89 @@
-+// Copyright 2019 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+package org.chromium.components.user_scripts;
-+
-+import android.annotation.TargetApi;
-+import android.app.Activity;
-+import android.content.Context;
-+import android.content.Intent;
-+import android.content.IntentSender;
-+import android.os.Build;
-+import android.view.View;
-+
-+import androidx.fragment.app.Fragment;
-+
-+import org.chromium.ui.base.ActivityKeyboardVisibilityDelegate;
-+import org.chromium.ui.base.ActivityAndroidPermissionDelegate;
-+import org.chromium.ui.base.ImmutableWeakReference;
-+import org.chromium.ui.base.IntentRequestTracker;
-+import org.chromium.ui.base.IntentRequestTracker.Delegate;
-+import org.chromium.ui.base.WindowAndroid;
-+
-+import java.lang.ref.WeakReference;
-+
-+/**
-+ * Implements intent sending for a fragment based window. This should be created when
-+ * onAttach() is called on the fragment, and destroyed when onDetach() is called.
-+ */
-+public class FragmentWindowAndroid extends WindowAndroid {
-+    private Fragment mFragment;
-+
-+    private static class TrackerDelegateImpl implements Delegate {
-+        private final Fragment mFragment;
-+        // This WeakReference is purely to avoid gc churn of creating a new WeakReference in
-+        // every getActivity call. It is not needed for correctness.
-+        private ImmutableWeakReference<Activity> mActivityWeakRefHolder;
-+
-+        /**
-+         * Create an instance of delegate for the given fragment that will own the
-+         * IntentRequestTracker.
-+         * @param fragment The fragment that owns the IntentRequestTracker.
-+         */
-+        private TrackerDelegateImpl(Fragment fragment) {
-+            mFragment = fragment;
-+        }
-+
-+        @Override
-+        public boolean startActivityForResult(Intent intent, int requestCode) {
-+            mFragment.startActivityForResult(intent, requestCode, null);
-+            return true;
-+        }
-+
-+        @Override
-+        public boolean startIntentSenderForResult(IntentSender intentSender, int requestCode) {
-+            try {
-+                mFragment.startIntentSenderForResult(
-+                        intentSender, requestCode, new Intent(), 0, 0, 0, null);
-+            } catch (IntentSender.SendIntentException e) {
-+                return false;
-+            }
-+            return true;
-+        }
-+
-+        @Override
-+        public void finishActivity(int requestCode) {
-+            Activity activity = getActivity().get();
-+            if (activity == null) return;
-+            activity.finishActivity(requestCode);
-+        }
-+
-+        @Override
-+        public final WeakReference<Activity> getActivity() {
-+            if (mActivityWeakRefHolder == null
-+                    || mActivityWeakRefHolder.get() != mFragment.getActivity()) {
-+                mActivityWeakRefHolder = new ImmutableWeakReference<>(mFragment.getActivity());
-+            }
-+            return mActivityWeakRefHolder;
-+        }
-+    }
-+
-+    FragmentWindowAndroid(Context context, Fragment fragment) {
-+        super(context, IntentRequestTracker.createFromDelegate(new TrackerDelegateImpl(fragment)));
-+        mFragment = fragment;
-+
-+        setKeyboardDelegate(new ActivityKeyboardVisibilityDelegate(getActivity()));
-+        setAndroidPermissionDelegate(new ActivityAndroidPermissionDelegate(getActivity()));
-+    }
-+}
-\ No newline at end of file
-diff --git a/components/user_scripts/android/java/src/org/chromium/components/user_scripts/IUserScriptsUtils.java b/components/user_scripts/android/java/src/org/chromium/components/user_scripts/IUserScriptsUtils.java
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/android/java/src/org/chromium/components/user_scripts/IUserScriptsUtils.java
-@@ -0,0 +1,22 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+package org.chromium.components.user_scripts;
-+
-+public interface IUserScriptsUtils {
-+    public void openSourceFile(String scriptKey);
-+}
-\ No newline at end of file
-diff --git a/components/user_scripts/android/java/src/org/chromium/components/user_scripts/ScriptInfo.java b/components/user_scripts/android/java/src/org/chromium/components/user_scripts/ScriptInfo.java
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/android/java/src/org/chromium/components/user_scripts/ScriptInfo.java
-@@ -0,0 +1,37 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+package org.chromium.components.user_scripts;
-+
-+import java.time.LocalDateTime;
-+
-+public class ScriptInfo {
-+    public String Key;
-+    public String Name;
-+    public String Description;
-+    public String Version;
-+    public String FilePath;
-+    public String UrlSource;
-+
-+    public boolean Enabled;
-+    public LocalDateTime InstallTime;
-+
-+    public String ParserError;
-+    public boolean ForceDisabled;
-+
-+    public ScriptInfo() {}
-+}
-diff --git a/components/user_scripts/android/java/src/org/chromium/components/user_scripts/ScriptListBaseAdapter.java b/components/user_scripts/android/java/src/org/chromium/components/user_scripts/ScriptListBaseAdapter.java
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/android/java/src/org/chromium/components/user_scripts/ScriptListBaseAdapter.java
-@@ -0,0 +1,163 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+package org.chromium.components.user_scripts;
-+
-+import android.content.Context;
-+import android.view.LayoutInflater;
-+import android.view.MotionEvent;
-+import android.view.View;
-+import android.view.ViewGroup;
-+import android.view.accessibility.AccessibilityManager;
-+import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
-+import android.widget.ImageView;
-+import android.widget.TextView;
-+import android.widget.Switch;
-+import android.widget.CompoundButton;
-+import android.widget.LinearLayout;
-+
-+import androidx.annotation.DrawableRes;
-+import androidx.annotation.NonNull;
-+import androidx.core.view.ViewCompat;
-+import androidx.recyclerview.widget.RecyclerView.ViewHolder;
-+
-+import org.chromium.components.browser_ui.widget.dragreorder.DragReorderableListAdapter;
-+import org.chromium.components.browser_ui.widget.dragreorder.DragStateDelegate;
-+import org.chromium.components.browser_ui.widget.listmenu.ListMenuButton;
-+import org.chromium.components.browser_ui.widget.listmenu.ListMenuButtonDelegate;
-+import org.chromium.ui.widget.ChromeImageView;
-+
-+import java.util.ArrayList;
-+import java.util.List;
-+
-+public class ScriptListBaseAdapter extends DragReorderableListAdapter<ScriptInfo> {
-+
-+    class ItemClickListener {
-+        void onScriptOnOff(boolean Enabled) {}
-+        void onScriptClicked() {}
-+    }
-+
-+    static class ScriptInfoRowViewHolder extends ViewHolder {
-+        private TextView mTitle;
-+        private TextView mDescription;
-+        private TextView mVersion;
-+        private TextView mFile;
-+        private TextView mUrl;
-+        private TextView mError;
-+        private Switch mSwitch;
-+        private ChromeImageView mIcon;
-+        private LinearLayout mErrorLayout;
-+        private LinearLayout mUrlContainer;
-+
-+        private ListMenuButton mMoreButton;
-+
-+        private CompoundButton.OnCheckedChangeListener mOnOffListener;
-+
-+        ScriptInfoRowViewHolder(View view) {
-+            super(view);
-+
-+            mSwitch = view.findViewById(R.id.switch_widget);
-+            mTitle = view.findViewById(R.id.title);
-+            mDescription = view.findViewById(R.id.description);
-+            mVersion = view.findViewById(R.id.version);
-+            mFile = view.findViewById(R.id.file);
-+            mUrl = view.findViewById(R.id.url);
-+            mUrlContainer = view.findViewById(R.id.url_container);
-+            mError = view.findViewById(R.id.error);
-+            mIcon = view.findViewById(R.id.icon);
-+            mErrorLayout = view.findViewById(R.id.error_layout);
-+
-+            mMoreButton = view.findViewById(R.id.more);
-+        }
-+
-+        protected void updateScriptInfo(ScriptInfo item) {
-+            mSwitch.setOnCheckedChangeListener(null);
-+            mSwitch.setChecked(item.Enabled);
-+            mSwitch.setOnCheckedChangeListener(mOnOffListener);
-+
-+            mSwitch.setEnabled(true);
-+            if (item.ForceDisabled) {
-+                mSwitch.setEnabled(false);
-+            }
-+
-+            mTitle.setText(item.Name);
-+            mDescription.setText(item.Description);
-+            mVersion.setText(item.Version);
-+            mFile.setText(item.Key);
-+            mUrl.setText(item.UrlSource);
-+            mError.setText(item.ParserError);
-+
-+            mUrl.setVisibility(View.VISIBLE);
-+            if (item.UrlSource == null || item.UrlSource.isEmpty()) {
-+                mUrlContainer.setVisibility(View.GONE);
-+            }
-+            mErrorLayout.setVisibility(View.VISIBLE);
-+            if (item.ParserError == null || item.ParserError.isEmpty()) {
-+                mErrorLayout.setVisibility(View.GONE);
-+            }
-+        }
-+
-+        void setMenuButtonDelegate(@NonNull ListMenuButtonDelegate delegate) {
-+            mMoreButton.setVisibility(View.VISIBLE);
-+            mMoreButton.setDelegate(delegate);
-+            // Set item row end padding 0 when MenuButton is visible.
-+            ViewCompat.setPaddingRelative(itemView, ViewCompat.getPaddingStart(itemView),
-+                    itemView.getPaddingTop(), 0, itemView.getPaddingBottom());
-+        }
-+
-+        void setItemListener(@NonNull ItemClickListener listener) {
-+            mOnOffListener = (buttonView, isChecked) -> listener.onScriptOnOff(isChecked);
-+            mSwitch.setOnCheckedChangeListener(mOnOffListener);
-+            itemView.setOnClickListener(view -> listener.onScriptClicked());
-+        }
-+    }
-+
-+    ScriptListBaseAdapter(Context context) {
-+        super(context);
-+    }
-+
-+    @Override
-+    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
-+        View row = LayoutInflater.from(viewGroup.getContext())
-+                           .inflate(R.layout.accept_script_item, viewGroup, false);
-+        return new ScriptInfoRowViewHolder(row);
-+    }
-+
-+    @Override
-+    public void onBindViewHolder(ViewHolder viewHolder, int i) {
-+        ((ScriptInfoRowViewHolder) viewHolder).updateScriptInfo(mElements.get(i));
-+    }
-+
-+    void setDisplayedScriptInfo(List<ScriptInfo> values) {
-+        mElements = new ArrayList<>(values);
-+        notifyDataSetChanged();
-+    }
-+
-+    @Override
-+    protected void setOrder(List<ScriptInfo> order) {
-+    }
-+
-+    @Override
-+    protected boolean isActivelyDraggable(ViewHolder viewHolder) {
-+        return isPassivelyDraggable(viewHolder);
-+    }
-+
-+    @Override
-+    protected boolean isPassivelyDraggable(ViewHolder viewHolder) {
-+        return viewHolder instanceof ScriptInfoRowViewHolder;
-+    }
-+}
-diff --git a/components/user_scripts/android/java/src/org/chromium/components/user_scripts/ScriptListPreference.java b/components/user_scripts/android/java/src/org/chromium/components/user_scripts/ScriptListPreference.java
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/android/java/src/org/chromium/components/user_scripts/ScriptListPreference.java
-@@ -0,0 +1,171 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+package org.chromium.components.user_scripts;
-+
-+import static org.chromium.components.browser_ui.widget.listmenu.BasicListMenu.buildMenuListItem;
-+import static org.chromium.components.browser_ui.widget.listmenu.BasicListMenu.buildMenuListItemWithEndIcon;
-+
-+import android.content.Context;
-+import android.content.Intent;
-+import android.provider.Browser;
-+import android.net.Uri;
-+import android.util.AttributeSet;
-+import android.widget.TextView;
-+import android.widget.Toast;
-+
-+import androidx.preference.Preference;
-+import androidx.preference.PreferenceViewHolder;
-+import androidx.recyclerview.widget.DividerItemDecoration;
-+import androidx.recyclerview.widget.LinearLayoutManager;
-+import androidx.recyclerview.widget.RecyclerView;
-+import androidx.recyclerview.widget.RecyclerView.ViewHolder;
-+
-+import org.chromium.ui.base.WindowAndroid;
-+import org.chromium.ui.base.ActivityWindowAndroid;
-+
-+import org.chromium.base.ApplicationStatus;
-+import org.chromium.base.ContextUtils;
-+import org.chromium.components.browser_ui.widget.TintedDrawable;
-+import org.chromium.components.browser_ui.widget.listmenu.BasicListMenu;
-+import org.chromium.components.browser_ui.widget.listmenu.ListMenu;
-+import org.chromium.components.browser_ui.widget.listmenu.ListMenuItemProperties;
-+import org.chromium.ui.modelutil.MVCListAdapter.ModelList;
-+
-+import org.chromium.components.user_scripts.ScriptListBaseAdapter;
-+import org.chromium.components.user_scripts.FragmentWindowAndroid;
-+
-+import java.util.List;
-+
-+public class ScriptListPreference extends Preference {
-+    private static class ScriptListAdapter
-+            extends ScriptListBaseAdapter {
-+        private final Context mContext;
-+
-+        ScriptListAdapter(Context context) {
-+            super(context);
-+            mContext = context;
-+        }
-+
-+        @Override
-+        public void onBindViewHolder(ViewHolder holder, int position) {
-+            super.onBindViewHolder(holder, position);
-+
-+            final ScriptInfo info = getItemByPosition(position);
-+
-+            ModelList menuItems = new ModelList();
-+
-+            menuItems.add(buildMenuListItem(R.string.remove, 0, 0, true));
-+            menuItems.add(buildMenuListItem(R.string.scripts_view_source, 0, 0,
-+                                                    info.ParserError == null || info.ParserError.isEmpty()));
-+
-+            ListMenu.Delegate delegate = (model) -> {
-+                int textId = model.get(ListMenuItemProperties.TITLE_ID);
-+                if (textId == R.string.remove) {
-+                    UserScriptsBridge.RemoveScript(info.Key);
-+                } else if (textId == R.string.scripts_view_source) {
-+                    UserScriptsBridge.getUtils().openSourceFile(info.Key);
-+                }
-+            };
-+            ((ScriptInfoRowViewHolder) holder)
-+                    .setMenuButtonDelegate(() -> new BasicListMenu(mContext, menuItems, delegate));
-+            ((ScriptInfoRowViewHolder) holder)
-+                    .setItemListener(new ScriptListBaseAdapter.ItemClickListener() {
-+                        @Override
-+                        public void onScriptOnOff(boolean Enabled) {
-+                            UserScriptsBridge.SetScriptEnabled(info.Key, Enabled);
-+                        }
-+
-+                        @Override
-+                        public void onScriptClicked() {}
-+                    });
-+        }
-+
-+        // @Override
-+        public void onDataUpdated(boolean enabled) {
-+            List<ScriptInfo> list = UserScriptsBridge.getUserScriptItems();
-+            if (enabled == false) {
-+                for (ScriptInfo script : list) {
-+                    script.ForceDisabled = true;
-+                }
-+            }
-+            setDisplayedScriptInfo(list);
-+        }
-+    }
-+
-+    private TextView mAddButton;
-+    private RecyclerView mRecyclerView;
-+    private ScriptListAdapter mAdapter;
-+    private FragmentWindowAndroid mWindowAndroid;
-+
-+    public ScriptListPreference(Context context, AttributeSet attrs) {
-+        super(context, attrs);
-+        mAdapter = new ScriptListAdapter(context);
-+    }
-+
-+    public void setWindowAndroid(FragmentWindowAndroid windowAndroid) {
-+        mWindowAndroid = windowAndroid;
-+    }
-+
-+    @Override
-+    public void onBindViewHolder(PreferenceViewHolder holder) {
-+        super.onBindViewHolder(holder);
-+
-+        mAddButton = (TextView) holder.findViewById(R.id.add_script);
-+        mAddButton.setCompoundDrawablesRelativeWithIntrinsicBounds(
-+                TintedDrawable.constructTintedDrawable(
-+                        getContext(), R.drawable.plus, R.color.default_control_color_active),
-+                null, null, null);
-+        mAddButton.setOnClickListener(view -> {
-+            UserScriptsBridge.SelectAndAddScriptFromFile(mWindowAndroid);
-+        });
-+
-+        mRecyclerView = (RecyclerView) holder.findViewById(R.id.script_list);
-+        LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
-+        mRecyclerView.setLayoutManager(layoutManager);
-+        mRecyclerView.addItemDecoration(
-+                new DividerItemDecoration(getContext(), layoutManager.getOrientation()));
-+        mRecyclerView.setEnabled(this.isEnabled());
-+        UserScriptsBridge.RegisterLoadCallback(this);
-+
-+        // We do not want the RecyclerView to be announced by screen readers every time
-+        // the view is bound.
-+        if (mRecyclerView.getAdapter() != mAdapter) {
-+            mRecyclerView.setAdapter(mAdapter);
-+            // Initialize script list.
-+            mAdapter.onDataUpdated(this.isEnabled());
-+        }
-+    }
-+
-+    @Override
-+    public void setEnabled (boolean enabled) {
-+        super.setEnabled(enabled);
-+        if (mRecyclerView != null) mRecyclerView.setEnabled(enabled);
-+        NotifyScriptsChanged();
-+    }
-+
-+    public void NotifyScriptsChanged() {
-+        mAdapter.onDataUpdated(this.isEnabled());
-+    }
-+
-+    public void OnUserScriptLoaded(boolean result, String error) {
-+        if (result == false) {
-+            Toast toast = Toast.makeText(getContext(), error, Toast.LENGTH_LONG);
-+            toast.show();
-+        }
-+    }
-+}
-\ No newline at end of file
-diff --git a/components/user_scripts/android/java/src/org/chromium/components/user_scripts/UserScriptsBridge.java b/components/user_scripts/android/java/src/org/chromium/components/user_scripts/UserScriptsBridge.java
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/android/java/src/org/chromium/components/user_scripts/UserScriptsBridge.java
-@@ -0,0 +1,200 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+package org.chromium.components.user_scripts;
-+
-+import java.util.ArrayList;
-+import java.util.List;
-+import java.lang.ref.WeakReference;
-+
-+import org.json.JSONArray;
-+import org.json.JSONException;
-+import org.json.JSONObject;
-+
-+import android.content.Context;
-+import android.content.Intent;
-+import android.net.Uri;
-+import androidx.annotation.Nullable;
-+import android.app.AlertDialog;
-+import android.content.DialogInterface;
-+
-+import org.chromium.base.annotations.CalledByNative;
-+import org.chromium.base.annotations.JNINamespace;
-+import org.chromium.base.annotations.NativeMethods;
-+import org.chromium.base.Log;
-+import org.chromium.ui.base.WindowAndroid;
-+
-+import org.chromium.components.user_scripts.ScriptListPreference;
-+import org.chromium.components.user_scripts.IUserScriptsUtils;
-+
-+@JNINamespace("user_scripts")
-+public class UserScriptsBridge {
-+    private static final String TAG = "UserScript";
-+
-+    static WeakReference<ScriptListPreference> observer;
-+
-+    private static IUserScriptsUtils utilInstance;
-+
-+    public static void registerUtils(IUserScriptsUtils instance) {
-+        utilInstance = instance;
-+    }
-+
-+    public static IUserScriptsUtils getUtils() {
-+        return utilInstance;
-+    }
-+
-+    public static boolean isEnabled() {
-+        return UserScriptsBridgeJni.get().isEnabled();
-+    }
-+
-+    public static void setEnabled(boolean enabled) {
-+        UserScriptsBridgeJni.get().setEnabled(enabled);
-+    }
-+
-+    public static void RemoveScript(String key) {
-+        UserScriptsBridgeJni.get().removeScript(key);
-+    }
-+
-+    public static void SetScriptEnabled(String key,
-+                                        boolean enabled) {
-+        UserScriptsBridgeJni.get().setScriptEnabled(key, enabled);
-+    }
-+
-+    public static void Reload() {
-+        UserScriptsBridgeJni.get().reload();
-+    }
-+
-+    public static void SelectAndAddScriptFromFile(WindowAndroid window) {
-+        Context context = window.getContext().get();
-+
-+        Intent fileSelector = new Intent(Intent.ACTION_OPEN_DOCUMENT);
-+        fileSelector.addCategory(Intent.CATEGORY_OPENABLE);
-+        fileSelector.setType("*/*");
-+        fileSelector.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-+
-+        window.showIntent(fileSelector,
-+            new WindowAndroid.IntentCallback() {
-+                @Override
-+                public void onIntentCompleted(int resultCode, Intent data) {
-+                    if (data == null) return;
-+                    Uri filePath = data.getData();
-+                    TryToInstall(context, filePath.toString());
-+                }
-+            },
-+            null);
-+    }
-+
-+    public static void TryToInstall(Context context, String ScriptFullPath) {
-+        DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
-+            @Override
-+            public void onClick(DialogInterface dialog, int which) {
-+                switch (which){
-+                    case DialogInterface.BUTTON_POSITIVE:
-+                        UserScriptsBridgeJni.get().tryToInstall(ScriptFullPath);
-+                        break;
-+
-+                    case DialogInterface.BUTTON_NEGATIVE:
-+                        break;
-+                }
-+            }
-+        };
-+
-+        String message = context.getString(R.string.ask_to_install, ScriptFullPath);
-+
-+        AlertDialog.Builder builder = new AlertDialog.Builder(context);
-+        builder.setMessage(message)
-+            .setPositiveButton(context.getString(R.string.yes), dialogClickListener)
-+            .setNegativeButton(context.getString(R.string.no), dialogClickListener)
-+            .show();
-+    }
-+
-+    public static List<ScriptInfo> getUserScriptItems() {
-+        List<ScriptInfo> list = new ArrayList<>();
-+        try {
-+            String json = UserScriptsBridgeJni.get().getScriptsInfo();
-+
-+            JSONObject jsonObject = new JSONObject(json);
-+
-+            JSONArray scripts = jsonObject.names();
-+            if (scripts != null) {
-+                Log.i(TAG, "User Scripts Loaded: %s", json);
-+                Log.i(TAG, "Totals scripts: %s", Integer.toString(scripts.length()));
-+                for (int i = 0; i < scripts.length(); i++) {
-+                    String key = (String) scripts.get(i);
-+                    JSONObject script = jsonObject.getJSONObject(key);
-+
-+                    ScriptInfo si = new ScriptInfo();
-+                    si.Key = key;
-+                    list.add(si);
-+
-+                    if(script.has("name")) si.Name = script.getString("name");
-+                    if(script.has("description")) si.Description = script.getString("description");
-+                    if(script.has("version")) si.Version = script.getString("version");
-+                    if(script.has("file_path")) si.FilePath = script.getString("file_path");
-+                    if(script.has("url_source")) si.UrlSource = script.getString("url_source");
-+                    if(script.has("parser_error")) si.ParserError = script.getString("parser_error");
-+                    if(script.has("force_disabled")) si.ForceDisabled = script.getBoolean("force_disabled");;
-+                    si.Enabled = script.getBoolean("enabled");
-+                }
-+            } else {
-+                Log.i(TAG, "User Scripts list empty");
-+            }
-+        } catch (Exception e) {
-+            Log.e(TAG, "User Scripts Load Error", e.toString());
-+        }
-+        return list;
-+    }
-+
-+    public static void RegisterLoadCallback(ScriptListPreference caller) {
-+        UserScriptsBridgeJni.get().registerLoadCallback();
-+        observer = new WeakReference<ScriptListPreference>(caller);
-+    }
-+
-+    @CalledByNative
-+    private static void shouldRefreshUserScriptList() {
-+        ScriptListPreference reference = observer.get();
-+        if (reference != null) {
-+            reference.NotifyScriptsChanged();
-+        }
-+    }
-+
-+    @CalledByNative
-+    private static void onUserScriptLoaded(boolean result, String error) {
-+        ScriptListPreference reference = observer.get();
-+        if (reference != null) {
-+            reference.OnUserScriptLoaded(result, error);
-+        }
-+    }
-+
-+    @NativeMethods
-+    interface Natives {
-+        boolean isEnabled();
-+        void setEnabled(boolean enabled);
-+
-+        String getScriptsInfo();
-+
-+        void removeScript(String scriptKey);
-+        void setScriptEnabled(String scriptKey, boolean enabled);
-+
-+        void reload();
-+        void selectAndAddScriptFromFile(WindowAndroid window);
-+        void tryToInstall(String scriptFullPath);
-+
-+        void registerLoadCallback();
-+    }
-+
-+}
-diff --git a/components/user_scripts/android/java/src/org/chromium/components/user_scripts/UserScriptsPreferences.java b/components/user_scripts/android/java/src/org/chromium/components/user_scripts/UserScriptsPreferences.java
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/android/java/src/org/chromium/components/user_scripts/UserScriptsPreferences.java
-@@ -0,0 +1,116 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+package org.chromium.components.user_scripts;
-+
-+import android.app.Activity;
-+import android.content.Context;
-+import android.content.Intent;
-+import android.os.Bundle;
-+import android.provider.Browser;
-+import android.net.Uri;
-+import android.view.MenuItem;
-+import android.view.View;
-+
-+import androidx.preference.Preference;
-+import androidx.preference.PreferenceFragmentCompat;
-+
-+import org.chromium.base.Log;
-+import org.chromium.ui.base.WindowAndroid;
-+import org.chromium.ui.base.ActivityWindowAndroid;
-+
-+import org.chromium.components.browser_ui.settings.ChromeSwitchPreference;
-+import org.chromium.components.browser_ui.settings.SettingsUtils;
-+import org.chromium.components.browser_ui.settings.TextMessagePreference;
-+
-+import org.chromium.components.user_scripts.UserScriptsBridge;
-+import org.chromium.components.user_scripts.FragmentWindowAndroid;
-+
-+public class UserScriptsPreferences
-+        extends PreferenceFragmentCompat
-+        implements SettingsUtils.ISupportHelpAndFeedback {
-+
-+    private static final String PREF_ENABLED_SWITCH = "enabled_switch";
-+    private static final String PREF_SCRIPTLISTPREFERENCE = "script_list";
-+
-+    public static final String EXTRA_SCRIPT_FILE = "org.chromium.chrome.preferences.script_file";
-+
-+    private FragmentWindowAndroid mWindowAndroid;
-+
-+    @Override
-+    public void onDestroy() {
-+        if (mWindowAndroid != null) mWindowAndroid.destroy();
-+        super.onDestroy();
-+    }
-+
-+    @Override
-+    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
-+        getActivity().setTitle(R.string.prefs_userscripts_settings);
-+        SettingsUtils.addPreferencesFromResource(this, R.xml.userscripts_preferences);
-+
-+        ChromeSwitchPreference enabledSwitch =
-+                (ChromeSwitchPreference) findPreference(PREF_ENABLED_SWITCH);
-+        ScriptListPreference listPreference =
-+                (ScriptListPreference) findPreference(PREF_SCRIPTLISTPREFERENCE);
-+
-+        boolean enabled = UserScriptsBridge.isEnabled();
-+        enabledSwitch.setChecked(enabled);
-+        listPreference.setEnabled(enabled);
-+        enabledSwitch.setOnPreferenceChangeListener((preference, newValue) -> {
-+            UserScriptsBridge.setEnabled((boolean) newValue);
-+            listPreference.setEnabled((boolean) newValue);
-+            return true;
-+        });
-+
-+        mWindowAndroid = new FragmentWindowAndroid(getContext(), this);
-+        listPreference.setWindowAndroid(mWindowAndroid);
-+    }
-+
-+    @Override
-+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
-+        // handle picker callback from SelectFileDialog
-+        mWindowAndroid.getIntentRequestTracker().onActivityResult(requestCode, resultCode, data);
-+    }
-+
-+    public void onHelpAndFeebackPressed() {
-+        Context context = getContext();
-+
-+        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/bromite/bromite/wiki/UserScripts"));
-+        // Let Chromium know that this intent is from Chromium, so that it does not close the app when
-+        // the user presses 'back' button.
-+        intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName());
-+        intent.putExtra(Browser.EXTRA_CREATE_NEW_TAB, true);
-+        intent.setPackage(context.getPackageName());
-+        context.startActivity(intent);
-+    }
-+
-+    public static Bundle createFragmentArgsForInstall(String filePath) {
-+        Bundle fragmentArgs = new Bundle();
-+        fragmentArgs.putSerializable(EXTRA_SCRIPT_FILE, filePath);
-+        return fragmentArgs;
-+    }
-+
-+    @Override
-+    public void onActivityCreated(Bundle savedInstanceState) {
-+        super.onActivityCreated(savedInstanceState);
-+
-+        String scriptToInstall = (String)getArguments().getSerializable(EXTRA_SCRIPT_FILE);
-+        if (scriptToInstall != null) {
-+            UserScriptsBridge.TryToInstall(getContext(), scriptToInstall);
-+        }
-+    }
-+}
-diff --git a/components/user_scripts/android/java_sources.gni b/components/user_scripts/android/java_sources.gni
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/android/java_sources.gni
-@@ -0,0 +1,18 @@
-+# This file is part of Bromite.
-+
-+# Bromite 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.
-+
-+# Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+
-+userscripts_java_sources = [
-+  "//components/user_scripts/android/java/src/org/chromium/chrome/browser/user_scripts/UserScriptsUtils.java",
-+]
-diff --git a/components/user_scripts/android/user_scripts_bridge.cc b/components/user_scripts/android/user_scripts_bridge.cc
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/android/user_scripts_bridge.cc
-@@ -0,0 +1,173 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+#include <jni.h>
-+#include <algorithm>
-+#include <string>
-+#include <vector>
-+#include <sstream>
-+#include <iterator>
-+
-+#include "base/android/callback_android.h"
-+#include "base/android/jni_android.h"
-+#include "base/android/jni_array.h"
-+#include "base/android/jni_string.h"
-+#include "base/android/scoped_java_ref.h"
-+#include "ui/android/window_android.h"
-+
-+#include "components/user_scripts/android/user_scripts_jni_headers/UserScriptsBridge_jni.h"
-+#include "../browser/userscripts_browser_client.h"
-+#include "user_scripts_bridge.h"
-+
-+using base::android::AttachCurrentThread;
-+using base::android::ConvertJavaStringToUTF8;
-+using base::android::ConvertUTF16ToJavaString;
-+using base::android::ConvertUTF8ToJavaString;
-+using base::android::JavaParamRef;
-+using base::android::JavaRef;
-+using base::android::ScopedJavaGlobalRef;
-+using base::android::ScopedJavaLocalRef;
-+using content::BrowserContext;
-+
-+namespace {
-+
-+user_scripts::UserScriptsBrowserClient* GetUserScriptsBrowserClient() {
-+  return user_scripts::UserScriptsBrowserClient::GetInstance();
-+}
-+
-+class CallbackObserver : public user_scripts::UserScriptLoader::Observer {
-+  private:
-+    void OnScriptsLoaded(user_scripts::UserScriptLoader* loader,
-+                         content::BrowserContext* browser_context) override {
-+        user_scripts::ShouldRefreshUserScriptList(base::android::AttachCurrentThread());
-+    }
-+
-+    void OnUserScriptLoaded(user_scripts::UserScriptLoader* loader,
-+                            bool result, const std::string& error) override {
-+        user_scripts::OnUserScriptLoaded(base::android::AttachCurrentThread(),
-+          result, error);
-+    }
-+
-+    void OnUserScriptLoaderDestroyed(user_scripts::UserScriptLoader* loader) override {}
-+};
-+
-+CallbackObserver* g_userscripts_loader_observer = NULL;
-+
-+}
-+
-+namespace user_scripts {
-+
-+static jboolean JNI_UserScriptsBridge_IsEnabled(
-+                    JNIEnv* env) {
-+  user_scripts::UserScriptsBrowserClient* client = GetUserScriptsBrowserClient();
-+  if (client == NULL) return false;
-+  return client->GetPrefs()->IsEnabled();
-+}
-+
-+static void JNI_UserScriptsBridge_SetEnabled(
-+                    JNIEnv* env,
-+                    jboolean is_enabled) {
-+  user_scripts::UserScriptsBrowserClient* client = GetUserScriptsBrowserClient();
-+  if (client == NULL) return;
-+  client->GetPrefs()->SetEnabled(is_enabled);
-+  client->GetLoader()->StartLoad();
-+}
-+
-+static base::android::ScopedJavaLocalRef<jstring> JNI_UserScriptsBridge_GetScriptsInfo(
-+                    JNIEnv* env) {
-+  user_scripts::UserScriptsBrowserClient* client = GetUserScriptsBrowserClient();
-+  if (client == NULL) return ConvertUTF8ToJavaString(env, {});
-+
-+  std::string json = client->GetPrefs()->GetScriptsInfo();
-+  return ConvertUTF8ToJavaString(env, json);
-+}
-+
-+static void JNI_UserScriptsBridge_RemoveScript(
-+                    JNIEnv* env,
-+                    const JavaParamRef<jstring>& jscript_key) {
-+  user_scripts::UserScriptsBrowserClient* client = GetUserScriptsBrowserClient();
-+  if (client == NULL) return;
-+
-+  std::string script_key = base::android::ConvertJavaStringToUTF8(jscript_key);
-+  client->GetLoader()->RemoveScript(script_key);
-+}
-+
-+static void JNI_UserScriptsBridge_SetScriptEnabled(
-+                    JNIEnv* env,
-+                    const JavaParamRef<jstring>& jscript_key,
-+                    jboolean is_enabled) {
-+  user_scripts::UserScriptsBrowserClient* client = GetUserScriptsBrowserClient();
-+  if (client == NULL) return;
-+
-+  std::string script_key = base::android::ConvertJavaStringToUTF8(jscript_key);
-+  client->GetLoader()->SetScriptEnabled(script_key, is_enabled);
-+}
-+
-+static void JNI_UserScriptsBridge_Reload(
-+                    JNIEnv* env) {
-+  user_scripts::UserScriptsBrowserClient* client = GetUserScriptsBrowserClient();
-+  if (client == NULL) return;
-+
-+  client->GetLoader()->StartLoad();
-+  user_scripts::ShouldRefreshUserScriptList(env);
-+}
-+
-+static void JNI_UserScriptsBridge_SelectAndAddScriptFromFile(
-+                    JNIEnv* env,
-+                    const JavaParamRef<jobject>& jwindow_android) {
-+  user_scripts::UserScriptsBrowserClient* client = GetUserScriptsBrowserClient();
-+  if (client == NULL) return;
-+
-+  client->GetLoader()->SelectAndAddScriptFromFile(
-+                    ui::WindowAndroid::FromJavaWindowAndroid(jwindow_android));
-+}
-+
-+static void JNI_UserScriptsBridge_TryToInstall(JNIEnv* env,
-+                         const JavaParamRef<jstring>& jscript_path) {
-+  user_scripts::UserScriptsBrowserClient* client = GetUserScriptsBrowserClient();
-+  if (client == NULL) return;
-+
-+  std::string script_path = base::android::ConvertJavaStringToUTF8(jscript_path);
-+  base::FilePath path(script_path);
-+
-+  client->GetLoader()->TryToInstall(path);
-+}
-+
-+static void JNI_UserScriptsBridge_RegisterLoadCallback(
-+                    JNIEnv* env) {
-+  user_scripts::UserScriptsBrowserClient* client = GetUserScriptsBrowserClient();
-+  if (client == NULL) return;
-+
-+  if (g_userscripts_loader_observer == NULL) {
-+    g_userscripts_loader_observer = new CallbackObserver();
-+    client->GetLoader()->AddObserver(g_userscripts_loader_observer);
-+  }
-+}
-+
-+static void ShouldRefreshUserScriptList(JNIEnv* env) {
-+  Java_UserScriptsBridge_shouldRefreshUserScriptList(env);
-+}
-+
-+static void OnUserScriptLoaded(JNIEnv* env,
-+              bool result, const std::string& error) {
-+  base::android::ScopedJavaLocalRef<jstring> j_error =
-+    base::android::ConvertUTF8ToJavaString(env, error);
-+
-+  Java_UserScriptsBridge_onUserScriptLoaded(env, result, j_error);
-+}
-+
-+}
-diff --git a/components/user_scripts/android/user_scripts_bridge.h b/components/user_scripts/android/user_scripts_bridge.h
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/android/user_scripts_bridge.h
-@@ -0,0 +1,31 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+#ifndef COMPONENTS_USERSCRIPS_HELPER_ANDROID_H_
-+#define COMPONENTS_USERSCRIPS_HELPER_ANDROID_H_
-+
-+#include <jni.h>
-+
-+namespace user_scripts {
-+
-+static void ShouldRefreshUserScriptList(JNIEnv* env);
-+static void OnUserScriptLoaded(JNIEnv* env,
-+              bool result, const std::string& error);
-+
-+}  // namespace user_scripts
-+
-+#endif
-\ No newline at end of file
-diff --git a/components/user_scripts/browser/BUILD.gn b/components/user_scripts/browser/BUILD.gn
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/browser/BUILD.gn
-@@ -0,0 +1,83 @@
-+# This file is part of Bromite.
-+
-+# Bromite 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.
-+
-+# Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+
-+import("//build/config/features.gni")
-+import("//tools/grit/grit_rule.gni")
-+
-+group("browser") {
-+  public_deps = [
-+    "//components/user_scripts/browser:browser_sources",
-+  ]
-+}
-+
-+source_set("browser_sources") {
-+  visibility = [ "./*" ]
-+
-+  sources = [
-+    "file_task_runner.cc",
-+    "file_task_runner.h",
-+    "userscripts_browser_client.cc",
-+    "userscripts_browser_client.h",
-+    "user_script_loader.cc",
-+    "user_script_loader.h",
-+    "user_script_prefs.cc",
-+    "user_script_prefs.h",
-+    "user_script_pref_info.cc",
-+    "user_script_pref_info.h",
-+    "ui/user_scripts_ui.h",
-+    "ui/user_scripts_ui.cc",
-+  ]
-+
-+  deps = [
-+    ":userscripts_browser_resources",
-+    "//base:i18n",
-+    "//components/keyed_service/content",
-+    "//components/keyed_service/core",
-+    "//components/pref_registry",
-+    "//components/prefs",
-+    "//content/public/browser",
-+    "//crypto:platform",
-+    "//components/user_scripts/common",
-+    "//services/device/public/mojom",
-+    "//services/preferences/public/cpp",
-+    "//services/service_manager/public/cpp",
-+    "//third_party/blink/public/common",
-+    "//third_party/blink/public/mojom/frame",
-+    "//ui/display",
-+  ]
-+
-+  public_deps = [
-+    "//content/public/common",
-+  ]
-+
-+  configs += [
-+    "//build/config:precompiled_headers",
-+    "//build/config/compiler:wexit_time_destructors",
-+  ]
-+}
-+
-+group("closure_compile") {
-+  deps = [ "resources/user-script-ui:closure_compile" ]
-+}
-+
-+grit("userscripts_browser_resources") {
-+  source = "resources/browser_resources.grd"
-+
-+  output_dir = "$root_gen_dir/chrome"
-+  outputs = [
-+    "grit/userscripts_browser_resources.h",
-+    "userscripts_browser_resources.pak",
-+  ]
-+}
-diff --git a/components/user_scripts/browser/file_task_runner.cc b/components/user_scripts/browser/file_task_runner.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/browser/file_task_runner.cc
-@@ -0,0 +1,40 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+#include "file_task_runner.h"
-+
-+#include "base/sequenced_task_runner.h"
-+#include "base/task/lazy_thread_pool_task_runner.h"
-+#include "base/task/task_traits.h"
-+
-+namespace user_scripts {
-+
-+namespace {
-+
-+base::LazyThreadPoolSequencedTaskRunner g_us_task_runner =
-+    LAZY_THREAD_POOL_SEQUENCED_TASK_RUNNER_INITIALIZER(
-+        base::TaskTraits(base::MayBlock(),
-+                         base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN,
-+                         base::TaskPriority::USER_VISIBLE));
-+
-+}  // namespace
-+
-+scoped_refptr<base::SequencedTaskRunner> GetUserScriptsFileTaskRunner() {
-+  return g_us_task_runner.Get();
-+}
-+
-+}  // namespace user_scripts
-diff --git a/components/user_scripts/browser/file_task_runner.h b/components/user_scripts/browser/file_task_runner.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/browser/file_task_runner.h
-@@ -0,0 +1,34 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+#ifndef USERSCRIPTS_BROWSER_FILE_TASK_RUNNER_H_
-+#define USERSCRIPTS_BROWSER_FILE_TASK_RUNNER_H_
-+
-+#include "base/memory/ref_counted.h"
-+#include "base/task/task_traits.h"
-+
-+namespace base {
-+class SequencedTaskRunner;
-+}
-+
-+namespace user_scripts {
-+
-+scoped_refptr<base::SequencedTaskRunner> GetUserScriptsFileTaskRunner();
-+
-+}  // namespace extensions
-+
-+#endif  // USERSCRIPTS_BROWSER_FILE_TASK_RUNNER_H_
-diff --git a/components/user_scripts/browser/resources/browser_resources.grd b/components/user_scripts/browser/resources/browser_resources.grd
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/browser/resources/browser_resources.grd
-@@ -0,0 +1,14 @@
-+<grit latest_public_release="0" current_release="1" output_all_resource_defines="false">
-+  <outputs>
-+    <output filename="grit/userscripts_browser_resources.h" type="rc_header">
-+      <emit emit_type='prepend'></emit>
-+    </output>
-+    <output filename="userscripts_browser_resources.pak" type="data_package" />
-+  </outputs>
-+  <release seq="1">
-+    <includes>
-+      <include name="IDR_USER_SCRIPTS_HTML" file="user-script-ui\user-scripts-ui.html" type="BINDATA" />
-+      <include name="IDR_USER_SCRIPTS_JS" file="user-script-ui\user-scripts-ui.js" type="BINDATA" />
-+    </includes>
-+  </release>
-+</grit>
-\ No newline at end of file
-diff --git a/components/user_scripts/browser/resources/user-script-ui/BUILD.gn b/components/user_scripts/browser/resources/user-script-ui/BUILD.gn
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/browser/resources/user-script-ui/BUILD.gn
-@@ -0,0 +1,12 @@
-+import("//third_party/closure_compiler/compile_js.gni")
-+
-+js_type_check("closure_compile") {
-+  deps = [ ":view_script_source" ]
-+}
-+
-+js_library("view_script_source") {
-+  deps = [
-+    "//ui/webui/resources/js:cr.m",
-+    "//ui/webui/resources/js:util.m",
-+  ]
-+}
-\ No newline at end of file
-diff --git a/components/user_scripts/browser/resources/user-script-ui/user-scripts-ui.html b/components/user_scripts/browser/resources/user-script-ui/user-scripts-ui.html
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/browser/resources/user-script-ui/user-scripts-ui.html
-@@ -0,0 +1,14 @@
-+<!doctype html>
-+<html lang="en">
-+<head>
-+  <meta charset="utf-8">
-+  <title>Local State Debug Page</title>
-+  <link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
-+  <script type="module" src="user-scripts-ui.js"></script>
-+</head>
-+<body>
-+  <pre id="content">
-+    Loading Script Source file...
-+  </pre>
-+</body>
-+</html>
-\ No newline at end of file
-diff --git a/components/user_scripts/browser/resources/user-script-ui/user-scripts-ui.js b/components/user_scripts/browser/resources/user-script-ui/user-scripts-ui.js
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/browser/resources/user-script-ui/user-scripts-ui.js
-@@ -0,0 +1,9 @@
-+import {sendWithPromise} from 'chrome://resources/js/cr.m.js';
-+import {$} from 'chrome://resources/js/util.m.js';
-+
-+document.addEventListener('DOMContentLoaded', function() {
-+  const urlParams = new URLSearchParams(window.location.search);
-+  sendWithPromise('requestSource', urlParams.get('key')).then(textContent => {
-+    $('content').textContent = textContent[0].content;
-+  });
-+});
-\ No newline at end of file
-diff --git a/components/user_scripts/browser/ui/user_scripts_ui.cc b/components/user_scripts/browser/ui/user_scripts_ui.cc
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/browser/ui/user_scripts_ui.cc
-@@ -0,0 +1,148 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+
-+#include <memory>
-+
-+#include "base/bind.h"
-+#include "base/json/json_string_value_serializer.h"
-+#include "base/macros.h"
-+#include "base/memory/writable_shared_memory_region.h"
-+#include "base/strings/string_util.h"
-+#include "base/values.h"
-+
-+#include "chrome/browser/browser_process.h"
-+#include "chrome/browser/profiles/profile.h"
-+#include "chrome/common/url_constants.h"
-+#include "chrome/grit/userscripts_browser_resources.h"
-+#include "components/prefs/pref_service.h"
-+#include "content/public/browser/web_ui.h"
-+#include "content/public/browser/web_ui_controller.h"
-+#include "content/public/browser/web_ui_data_source.h"
-+#include "content/public/browser/web_ui_message_handler.h"
-+
-+#include "user_scripts_ui.h"
-+#include "../userscripts_browser_client.h"
-+#include "../../common/user_script.h"
-+
-+namespace {
-+
-+class UserScriptsUIHandler : public content::WebUIMessageHandler {
-+ public:
-+  UserScriptsUIHandler();
-+  ~UserScriptsUIHandler() override;
-+
-+  // content::WebUIMessageHandler:
-+  void RegisterMessages() override;
-+
-+ private:
-+  void HandleRequestSource(base::Value::ConstListView args);
-+  void OnScriptsLoaded(
-+      const std::string callback_id,
-+      const std::string script_key,
-+      std::unique_ptr<user_scripts::UserScriptList> user_scripts);
-+
-+  std::unique_ptr<user_scripts::UserScriptList> loaded_scripts_;
-+
-+  base::WeakPtrFactory<UserScriptsUIHandler> weak_factory_{this};
-+
-+  DISALLOW_COPY_AND_ASSIGN(UserScriptsUIHandler);
-+};
-+
-+UserScriptsUIHandler::UserScriptsUIHandler()
-+  : loaded_scripts_(new user_scripts::UserScriptList()) {
-+}
-+
-+UserScriptsUIHandler::~UserScriptsUIHandler() {
-+}
-+
-+void UserScriptsUIHandler::RegisterMessages() {
-+  web_ui()->RegisterMessageCallback(
-+      "requestSource",
-+      base::BindRepeating(&UserScriptsUIHandler::HandleRequestSource,
-+                          base::Unretained(this)));
-+}
-+
-+void UserScriptsUIHandler::HandleRequestSource(base::Value::ConstListView args) {
-+  AllowJavascript();
-+  if (args.size() < 2) return;
-+
-+  std::string callback_id = args[0].GetString();
-+  std::string script_key = args[1].GetString();
-+  if (script_key.empty()) {
-+    std::string json = "Missing key value.";
-+    ResolveJavascriptCallback(base::Value(callback_id), base::Value(json));
-+    return;
-+  }
-+
-+  user_scripts::UserScriptsBrowserClient* client = user_scripts::UserScriptsBrowserClient::GetInstance();
-+  if (client == NULL) {
-+    std::string json = "User scripts disabled.";
-+    ResolveJavascriptCallback(base::Value(callback_id), base::Value(json));
-+  } else {
-+    std::unique_ptr<user_scripts::UserScriptList> scripts_to_load =
-+                                    std::move(loaded_scripts_);
-+    scripts_to_load->clear();
-+
-+    client->GetLoader()->LoadScripts(std::move(scripts_to_load),
-+      base::BindOnce(
-+          &UserScriptsUIHandler::OnScriptsLoaded,
-+          weak_factory_.GetWeakPtr(),
-+          callback_id, script_key)
-+      );
-+  }
-+}
-+
-+void UserScriptsUIHandler::OnScriptsLoaded(
-+    const std::string callback_id,
-+    const std::string script_key,
-+    std::unique_ptr<user_scripts::UserScriptList> user_scripts) {
-+  loaded_scripts_ = std::move(user_scripts);
-+
-+  base::ListValue response;
-+  for (const std::unique_ptr<user_scripts::UserScript>& script : *loaded_scripts_) {
-+    if (script->key() == script_key) {
-+      auto scriptData = std::make_unique<base::DictionaryValue>();
-+      for (const std::unique_ptr<user_scripts::UserScript::File>& js_file :
-+          script->js_scripts()) {
-+        base::StringPiece contents = js_file->GetContent();
-+        scriptData->SetString("content", contents.data());
-+      }
-+      response.Append(std::move(scriptData));
-+    }
-+  }
-+
-+  ResolveJavascriptCallback(base::Value(callback_id), response);
-+}
-+
-+}  // namespace
-+
-+namespace user_scripts {
-+
-+UserScriptsUI::UserScriptsUI(content::WebUI* web_ui) : WebUIController(web_ui) {
-+  content::WebUIDataSource* html_source =
-+      content::WebUIDataSource::Create(kChromeUIUserScriptsHost);
-+  html_source->SetDefaultResource(IDR_USER_SCRIPTS_HTML);
-+  html_source->AddResourcePath("user-scripts-ui.js", IDR_USER_SCRIPTS_JS);
-+  content::WebUIDataSource::Add(Profile::FromWebUI(web_ui), html_source);
-+  web_ui->AddMessageHandler(std::make_unique<UserScriptsUIHandler>());
-+}
-+
-+UserScriptsUI::~UserScriptsUI() {
-+}
-+
-+}
-diff --git a/components/user_scripts/browser/ui/user_scripts_ui.h b/components/user_scripts/browser/ui/user_scripts_ui.h
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/browser/ui/user_scripts_ui.h
-@@ -0,0 +1,39 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+#ifndef USERSCRIPTS_BROWSER_UI_USER_SCRIPTS_UI_H_
-+#define USERSCRIPTS_BROWSER_UI_USER_SCRIPTS_UI_H_
-+
-+#include "base/macros.h"
-+#include "content/public/browser/web_ui_controller.h"
-+
-+namespace user_scripts {
-+
-+const char kChromeUIUserScriptsHost[] = "user-scripts";
-+
-+class UserScriptsUI : public content::WebUIController {
-+ public:
-+  explicit UserScriptsUI(content::WebUI* web_ui);
-+  ~UserScriptsUI() override;
-+
-+ private:
-+  DISALLOW_COPY_AND_ASSIGN(UserScriptsUI);
-+};
-+
-+}
-+
-+#endif
-\ No newline at end of file
-diff --git a/components/user_scripts/browser/user_script_loader.cc b/components/user_scripts/browser/user_script_loader.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/browser/user_script_loader.cc
-@@ -0,0 +1,721 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+#include "user_script_loader.h"
-+
-+#include <stddef.h>
-+
-+#include <set>
-+#include <string>
-+#include <utility>
-+
-+#include "base/bind.h"
-+#include "base/memory/writable_shared_memory_region.h"
-+#include "base/strings/string_util.h"
-+#include "base/strings/strcat.h"
-+#include "base/files/file.h"
-+#include "base/files/file_util.h"
-+#include "base/files/file_enumerator.h"
-+#include "base/i18n/file_util_icu.h"
-+#include "base/path_service.h"
-+#include "base/base_paths_android.h"
-+#include "base/strings/utf_string_conversions.h"
-+#include "base/android/content_uri_utils.h"
-+#include "base/android/jni_android.h"
-+#include "base/task/task_traits.h"
-+#include "base/version.h"
-+
-+#include "crypto/sha2.h"
-+#include "base/base64.h"
-+
-+#include "build/build_config.h"
-+#include "content/public/browser/browser_context.h"
-+#include "content/public/browser/browser_task_traits.h"
-+#include "content/public/browser/browser_thread.h"
-+#include "content/public/browser/notification_service.h"
-+#include "content/public/browser/notification_types.h"
-+#include "content/public/browser/render_process_host.h"
-+#include "ui/shell_dialogs/select_file_dialog.h"
-+#include "content/browser/file_system_access/file_system_chooser.h"
-+#include "chrome/browser/ui/chrome_select_file_policy.h"
-+#include "ui/android/window_android.h"
-+
-+#include "../common/user_scripts_features.h"
-+#include "../common/extension_messages.h"
-+#include "file_task_runner.h"
-+#include "user_script_prefs.h"
-+#include "user_script_pref_info.h"
-+
-+using content::BrowserThread;
-+using content::BrowserContext;
-+
-+namespace user_scripts {
-+
-+namespace {
-+
-+static const base::StringPiece kUserScriptBegin("// ==UserScript==");
-+static const base::StringPiece kUserScriptEnd("// ==/UserScript==");
-+static const base::StringPiece kNamespaceDeclaration("// @namespace");
-+static const base::StringPiece kNameDeclaration("// @name");
-+static const base::StringPiece kVersionDeclaration("// @version");
-+static const base::StringPiece kDescriptionDeclaration("// @description");
-+static const base::StringPiece kIncludeDeclaration("// @include");
-+static const base::StringPiece kExcludeDeclaration("// @exclude");
-+static const base::StringPiece kMatchDeclaration("// @match");
-+static const base::StringPiece kExcludeMatchDeclaration("// @exclude_match");
-+static const base::StringPiece kRunAtDeclaration("// @run-at");
-+static const base::StringPiece kRunAtDocumentStartValue("document-start");
-+static const base::StringPiece kRunAtDocumentEndValue("document-end");
-+static const base::StringPiece kRunAtDocumentIdleValue("document-idle");
-+static const base::StringPiece kUrlSourceDeclaration("// @url");
-+static const base::StringPiece kUrlHomePageDeclaration("// @homepage");
-+
-+// internal use
-+static const base::StringPiece kParserError("// @error");
-+static const base::StringPiece kForceDisabled("// @disabled");
-+
-+bool invalidChar(unsigned char c)
-+{
-+  return !(c>=0 && c <128);
-+}
-+
-+void stripUnicode(std::string& str)
-+{
-+  str.erase(remove_if(str.begin(),str.end(), invalidChar), str.end());
-+}
-+
-+// Helper function to parse greasesmonkey headers
-+bool GetDeclarationValue(const base::StringPiece& line,
-+                         const base::StringPiece& prefix,
-+                         std::string* value) {
-+  base::StringPiece::size_type index = line.find(prefix);
-+  if (index == base::StringPiece::npos)
-+    return false;
-+
-+  std::string temp(line.data() + index + prefix.length(),
-+                   line.length() - index - prefix.length());
-+
-+  if (temp.empty() || !base::IsUnicodeWhitespace(temp[0]))
-+    return false;
-+
-+  base::TrimWhitespaceASCII(temp, base::TRIM_ALL, value);
-+  return true;
-+}
-+
-+}  // namespace
-+
-+// static
-+bool UserScriptLoader::ParseMetadataHeader(const base::StringPiece& script_text,
-+                                           std::unique_ptr<UserScript>& script,
-+                                           bool *found_metadata,
-+                                           std::string& error_message) {
-+  // http://wiki.greasespot.net/Metadata_block
-+  base::StringPiece line;
-+  size_t line_start = 0;
-+  size_t line_end = line_start;
-+  *found_metadata = false;
-+
-+  while (line_start < script_text.length()) {
-+    line_end = script_text.find('\n', line_start);
-+
-+    // Handle the case where there is no trailing newline in the file.
-+    if (line_end == std::string::npos)
-+      line_end = script_text.length() - 1;
-+
-+    line = base::StringPiece(script_text.data() + line_start,
-+                             line_end - line_start);
-+
-+    if (!*found_metadata) {
-+      if (base::StartsWith(line, kUserScriptBegin))
-+        *found_metadata = true;
-+    } else {
-+      if (base::StartsWith(line, kUserScriptEnd))
-+        break;
-+
-+      std::string value;
-+      if (GetDeclarationValue(line, kIncludeDeclaration, &value)) {
-+        // We escape some characters that MatchPattern() considers special.
-+        base::ReplaceSubstringsAfterOffset(&value, 0, "\\", "\\\\");
-+        base::ReplaceSubstringsAfterOffset(&value, 0, "?", "\\?");
-+        script->add_glob(value);
-+      } else if (GetDeclarationValue(line, kExcludeDeclaration, &value)) {
-+        base::ReplaceSubstringsAfterOffset(&value, 0, "\\", "\\\\");
-+        base::ReplaceSubstringsAfterOffset(&value, 0, "?", "\\?");
-+        script->add_exclude_glob(value);
-+      } else if (GetDeclarationValue(line, kNamespaceDeclaration, &value)) {
-+        script->set_name_space(value);
-+      } else if (GetDeclarationValue(line, kNameDeclaration, &value)) {
-+        script->set_name(value);
-+      } else if (GetDeclarationValue(line, kVersionDeclaration, &value)) {
-+        base::Version version(value);
-+        if (version.IsValid())
-+          script->set_version(version.GetString());
-+      } else if (GetDeclarationValue(line, kDescriptionDeclaration, &value)) {
-+        script->set_description(value);
-+      } else if (GetDeclarationValue(line, kMatchDeclaration, &value)) {
-+        URLPattern pattern(UserScript::ValidUserScriptSchemes());
-+        if (URLPattern::ParseResult::kSuccess != pattern.Parse(value)) {
-+          error_message = "Invalid UserScript Schema " + value;
-+          return false;
-+        }
-+        script->add_url_pattern(pattern);
-+      } else if (GetDeclarationValue(line, kExcludeMatchDeclaration, &value)) {
-+        URLPattern exclude(UserScript::ValidUserScriptSchemes());
-+        if (URLPattern::ParseResult::kSuccess != exclude.Parse(value)) {
-+          error_message = "Invalid UserScript Schema " + value;
-+          return false;
-+        }
-+        script->add_exclude_url_pattern(exclude);
-+      } else if (GetDeclarationValue(line, kRunAtDeclaration, &value)) {
-+        if (value == kRunAtDocumentStartValue)
-+          script->set_run_location(UserScript::DOCUMENT_START);
-+        else if (value == kRunAtDocumentEndValue)
-+          script->set_run_location(UserScript::DOCUMENT_END);
-+        else if (value == kRunAtDocumentIdleValue)
-+          script->set_run_location(UserScript::DOCUMENT_IDLE);
-+        else {
-+          error_message = "Invalid RunAtDeclaration " + value;
-+          return false;
-+        }
-+      } else if (GetDeclarationValue(line, kUrlSourceDeclaration, &value) ||
-+                 GetDeclarationValue(line, kUrlHomePageDeclaration, &value)) {
-+        script->set_url_source(value);
-+      } else if (GetDeclarationValue(line, kParserError, &value)) {
-+        script->set_parser_error(value);
-+      } else if (GetDeclarationValue(line, kForceDisabled, &value)) {
-+        script->set_force_disabled();
-+      }
-+
-+      // TODO(aa): Handle more types of metadata.
-+    }
-+
-+    line_start = line_end + 1;
-+  }
-+
-+  // If no patterns were specified, default to @include *. This is what
-+  // Greasemonkey does.
-+  if (script->globs().empty() && script->url_patterns().is_empty())
-+    script->add_glob("*");
-+
-+  return true;
-+}
-+
-+// static
-+bool LoadUserScriptFromFile(
-+    const base::FilePath& user_script_path, const GURL& original_url,
-+    std::unique_ptr<UserScript>& script,
-+    bool* found_metadata,
-+    std::u16string* error) {
-+
-+    base::File infile;
-+    if (user_script_path.IsContentUri()) {
-+      if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+        LOG(INFO) << "UserScriptLoader: path " << user_script_path << " is a content uri";
-+
-+      infile = OpenContentUriForRead(user_script_path);
-+    } else {
-+      infile = base::File(user_script_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
-+    }
-+
-+    if (!infile.IsValid()) {
-+      *error = u"Cannot open script source.";
-+      return false;
-+    }
-+
-+    auto length = infile.GetLength();
-+    if (length<=0) {
-+      *error = u"File is empty.";
-+      return false;
-+    }
-+
-+    auto buffer = std::vector<char>(length);
-+    int bytes_read = infile.Read(0, buffer.data(), length);
-+    if (bytes_read == -1) {
-+      *error = u"Could not read source file.";
-+      return false;
-+    }
-+
-+    std::string content(buffer.begin(), buffer.end());
-+    if (!base::IsStringUTF8(content)) {
-+      *error = u"User script must be UTF8 encoded.";
-+      return false;
-+    }
-+
-+    std::string detailed_error;
-+    bool parseResult = UserScriptLoader::ParseMetadataHeader(content, script,
-+                                found_metadata, detailed_error);
-+    if (parseResult == false || *found_metadata == false) {
-+      std::u16string detailed_error16;
-+      base::UTF8ToUTF16(detailed_error.c_str(), detailed_error.length(), &detailed_error16);
-+      *error = base::StrCat({u"Invalid script header. ", detailed_error16});
-+      return false;
-+    }
-+
-+    script->set_match_origin_as_fallback(MatchOriginAsFallbackBehavior::kNever);
-+
-+    // remove unicode chars and set content into File
-+    stripUnicode(content);
-+    std::unique_ptr<UserScript::File> file(new UserScript::File());
-+    file->set_content(content);
-+    file->set_url(GURL(/*script_key*/ "script.js")); // name doesn't matter
-+
-+    // create SHA256 of file
-+    char raw[crypto::kSHA256Length] = {0};
-+    std::string key;
-+    crypto::SHA256HashString(content, raw, crypto::kSHA256Length);
-+    base::Base64Encode(base::StringPiece(raw, crypto::kSHA256Length), &key);
-+    file->set_key(key);
-+
-+    script->js_scripts().push_back(std::move(file));
-+
-+    // add into key the filename
-+    // this value is used in ui to discriminate scripts
-+    script->set_key(user_script_path.BaseName().value());
-+    return true;
-+}
-+
-+// static
-+bool GetOrCreatePath(base::FilePath& path) {
-+  base::PathService::Get(base::DIR_ANDROID_APP_DATA, &path);
-+  path = path.AppendASCII("userscripts");
-+
-+  // create snippets directory if not exists
-+  if (!base::PathExists(path)) {
-+    LOG(INFO) << "Path " << path << " doesn't exists. Creating";
-+    base::File::Error error = base::File::FILE_OK;
-+    if (!base::CreateDirectoryAndGetError(path, &error)) {
-+      LOG(ERROR) <<
-+               "UserScriptLoader: failed to create directory: " << path
-+               << " with error code " << error;
-+      return false;
-+    }
-+  }
-+  return true;
-+}
-+
-+// static
-+void LoadUserScripts(UserScriptList* user_scripts_list) {
-+  base::FilePath path;
-+  if (GetOrCreatePath(path) == false) return;
-+
-+  // enumerate all files from script path
-+  // we accept all files, but we check if it's a real
-+  // userscript
-+  base::FileEnumerator dir_enum(
-+    path,
-+    /*recursive=*/false, base::FileEnumerator::FILES);
-+  base::FilePath full_name;
-+  while (full_name = dir_enum.Next(), !full_name.empty()) {
-+    std::unique_ptr<UserScript> userscript(new UserScript());
-+
-+    std::u16string error;
-+    bool found_metadata;
-+    if (LoadUserScriptFromFile(full_name, GURL(), userscript, &found_metadata, &error)) {
-+      if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+        LOG(INFO) << "UserScriptLoader: Found user script " << userscript->name() <<
-+              "-" << userscript->version() <<
-+              "-" << userscript->description();
-+
-+      userscript->set_file_path(full_name.AsUTF8Unsafe());
-+      user_scripts_list->push_back(std::move(userscript));
-+    } else {
-+      LOG(ERROR) << "UserScriptLoader: load error " << error;
-+    }
-+  }
-+}
-+
-+UserScriptLoader::UserScriptLoader(BrowserContext* browser_context,
-+                                   UserScriptsPrefs* prefs)
-+    : loaded_scripts_(new UserScriptList()),
-+      ready_(false),
-+      browser_context_(browser_context),
-+      prefs_(prefs) {}
-+
-+UserScriptLoader::~UserScriptLoader() {
-+  for (auto& observer : observers_)
-+     observer.OnUserScriptLoaderDestroyed(this);
-+}
-+
-+void UserScriptLoader::OnRenderProcessHostCreated(
-+    content::RenderProcessHost* process_host) {
-+  if (initial_load_complete()) {
-+    SendUpdate(process_host, shared_memory_);
-+  }
-+}
-+
-+void UserScriptLoader::SetReady(bool ready) {
-+  bool was_ready = ready_;
-+  ready_ = ready;
-+  if (ready_ && !was_ready)
-+    AttemptLoad();
-+}
-+
-+void UserScriptLoader::AttemptLoad() {
-+  int tryOut = prefs_->GetCurrentStartupTryout();
-+  if (tryOut >= 3) {
-+    LOG(INFO) << "UserScriptLoader: Possible crash detected. UserScript disabled";
-+    prefs_->SetEnabled(false);
-+  } else {
-+    prefs_->StartupTryout(tryOut+1);
-+    StartLoad();
-+  }
-+}
-+
-+void UserScriptLoader::StartLoad() {
-+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-+
-+  if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+    LOG(INFO) << "UserScriptLoader: StartLoad";
-+
-+  // Reload any loaded scripts, and clear out |loaded_scripts_| to indicate that
-+  // the scripts aren't currently ready.
-+  std::unique_ptr<UserScriptList> scripts_to_load = std::move(loaded_scripts_);
-+  scripts_to_load->clear();
-+
-+  if (prefs_->IsEnabled()) {
-+    LoadScripts(std::move(scripts_to_load),
-+                base::BindOnce(&UserScriptLoader::OnScriptsLoaded,
-+                              weak_factory_.GetWeakPtr()));
-+  } else {
-+    OnScriptsLoaded(std::move(scripts_to_load));
-+  }
-+}
-+
-+// static
-+base::ReadOnlySharedMemoryRegion UserScriptLoader::Serialize(
-+    const UserScriptList& scripts) {
-+  base::Pickle pickle;
-+  pickle.WriteUInt32(scripts.size());
-+  for (const std::unique_ptr<UserScript>& script : scripts) {
-+    // TODO(aa): This can be replaced by sending content script metadata to
-+    // renderers along with other extension data in ExtensionMsg_Loaded.
-+    // See crbug.com/70516.
-+    script->Pickle(&pickle);
-+    // Write scripts as 'data' so that we can read it out in the slave without
-+    // allocating a new string.
-+    for (const std::unique_ptr<UserScript::File>& js_file :
-+         script->js_scripts()) {
-+      base::StringPiece contents = js_file->GetContent();
-+      pickle.WriteData(contents.data(), contents.length());
-+    }
-+    for (const std::unique_ptr<UserScript::File>& css_file :
-+         script->css_scripts()) {
-+      base::StringPiece contents = css_file->GetContent();
-+      pickle.WriteData(contents.data(), contents.length());
-+    }
-+  }
-+
-+  // Create the shared memory object.
-+  base::MappedReadOnlyRegion shared_memory =
-+      base::ReadOnlySharedMemoryRegion::Create(pickle.size());
-+  if (!shared_memory.IsValid())
-+    return {};
-+
-+  // Copy the pickle to shared memory.
-+  memcpy(shared_memory.mapping.memory(), pickle.data(), pickle.size());
-+  return std::move(shared_memory.region);
-+}
-+
-+void UserScriptLoader::AddObserver(Observer* observer) {
-+   observers_.AddObserver(observer);
-+}
-+
-+void UserScriptLoader::RemoveObserver(Observer* observer) {
-+   observers_.RemoveObserver(observer);
-+}
-+
-+void UserScriptLoader::OnScriptsLoaded(
-+    std::unique_ptr<UserScriptList> user_scripts) {
-+
-+  if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+    LOG(INFO) << "UserScriptLoader: OnScriptsLoaded";
-+
-+  // Check user preferences for loaded user scripts
-+  prefs_->CompareWithPrefs(*user_scripts);
-+  loaded_scripts_ = std::move(user_scripts);
-+
-+  base::ReadOnlySharedMemoryRegion shared_memory;
-+  shared_memory =
-+      UserScriptLoader::Serialize(*loaded_scripts_);
-+
-+  if (!shared_memory.IsValid()) {
-+    // This can happen if we run out of file descriptors.  In that case, we
-+    // have a choice between silently omitting all user scripts for new tabs,
-+    // by nulling out shared_memory_, or only silently omitting new ones by
-+    // leaving the existing object in place. The second seems less bad, even
-+    // though it removes the possibility that freeing the shared memory block
-+    // would open up enough FDs for long enough for a retry to succeed.
-+
-+    // Pretend the extension change didn't happen.
-+    return;
-+  }
-+
-+  // We've got scripts ready to go.
-+  shared_memory_ = std::move(shared_memory);
-+
-+  for (content::RenderProcessHost::iterator i(
-+           content::RenderProcessHost::AllHostsIterator());
-+       !i.IsAtEnd(); i.Advance()) {
-+    SendUpdate(i.GetCurrentValue(), shared_memory_);
-+  }
-+
-+  // DCHECK(false); trying crash
-+  prefs_->StartupTryout(0);
-+
-+  for (auto& observer : observers_)
-+    observer.OnScriptsLoaded(this, browser_context_);
-+}
-+
-+void UserScriptLoader::SendUpdate(
-+    content::RenderProcessHost* process,
-+    const base::ReadOnlySharedMemoryRegion& shared_memory) {
-+  if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+    LOG(INFO) << "UserScriptLoader: SendUpdate";
-+
-+  // If the process is being started asynchronously, early return.  We'll end up
-+  // calling InitUserScripts when it's created which will call this again.
-+  base::ProcessHandle handle = process->GetProcess().Handle();
-+  if (!handle)
-+    return;
-+
-+  base::ReadOnlySharedMemoryRegion region_for_process =
-+      shared_memory.Duplicate();
-+  if (!region_for_process.IsValid())
-+    return;
-+
-+  process->Send(new ExtensionMsg_UpdateUserScripts(
-+     std::move(region_for_process)));
-+}
-+
-+void LoadScriptsOnFileTaskRunner(
-+    std::unique_ptr<UserScriptList> user_scripts,
-+    UserScriptLoader::LoadScriptsCallback callback) {
-+  DCHECK(GetUserScriptsFileTaskRunner()->RunsTasksInCurrentSequence());
-+  DCHECK(user_scripts.get());
-+
-+  // load user scripts from path
-+  LoadUserScripts(user_scripts.get());
-+
-+  // Explicit priority to prevent unwanted task priority inheritance.
-+  content::GetUIThreadTaskRunner({base::TaskPriority::USER_BLOCKING})
-+      ->PostTask(FROM_HERE,
-+                 base::BindOnce(std::move(callback), std::move(user_scripts)));
-+}
-+
-+void UserScriptLoader::LoadScripts(
-+    std::unique_ptr<UserScriptList> user_scripts,
-+    LoadScriptsCallback callback) {
-+  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
-+
-+  GetUserScriptsFileTaskRunner()->PostTask(
-+      FROM_HERE,
-+      base::BindOnce(&LoadScriptsOnFileTaskRunner, std::move(user_scripts),
-+                     std::move(callback)));
-+}
-+
-+void RemoveScriptsOnFileTaskRunner(
-+    const std::string& script_id,
-+    UserScriptLoader::RemoveScriptCallback callback) {
-+  DCHECK(GetUserScriptsFileTaskRunner()->RunsTasksInCurrentSequence());
-+
-+  base::FilePath path;
-+  if (GetOrCreatePath(path)) {
-+    base::FilePath file = path.Append(script_id);
-+    if (base::DeleteFile(file) == false) {
-+      LOG(ERROR) <<
-+               "ERROR: failed to delete file : " << path;
-+    }
-+  }
-+
-+  content::GetUIThreadTaskRunner({base::TaskPriority::USER_BLOCKING})
-+      ->PostTask(FROM_HERE,
-+                 base::BindOnce(std::move(callback)));
-+}
-+
-+void UserScriptLoader::OnScriptRemoved() {
-+  StartLoad();
-+}
-+
-+void UserScriptLoader::RemoveScript(const std::string& script_id) {
-+  if (!prefs_->IsEnabled()) return;
-+  prefs_->RemoveScriptFromPrefs(script_id);
-+
-+  GetUserScriptsFileTaskRunner()->PostTask(
-+      FROM_HERE,
-+      base::BindOnce(&RemoveScriptsOnFileTaskRunner,
-+                     std::move(script_id),
-+                     base::BindOnce(&UserScriptLoader::OnScriptRemoved,
-+                             weak_factory_.GetWeakPtr())));
-+}
-+
-+void UserScriptLoader::SetScriptEnabled(const std::string& script_id, bool is_enabled) {
-+  if (!prefs_->IsEnabled()) return;
-+  prefs_->SetScriptEnabled(script_id, is_enabled);
-+  StartLoad();
-+}
-+
-+void UserScriptLoader::SelectAndAddScriptFromFile(ui::WindowAndroid* nativeWindow) {
-+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-+
-+  if (!prefs_->IsEnabled()) return;
-+
-+  dialog_ = ui::SelectFileDialog::Create(
-+      this, std::make_unique<ChromeSelectFilePolicy>(nullptr /*web_contents*/));
-+
-+  ui::SelectFileDialog::FileTypeInfo allowed_file_info;
-+  allowed_file_info.extensions = {{FILE_PATH_LITERAL("js")}};
-+  allowed_file_info.allowed_paths =
-+      ui::SelectFileDialog::FileTypeInfo::ANY_PATH;
-+  base::FilePath suggested_name;
-+
-+  std::vector<std::u16string> types;
-+  types.push_back(u"*/*"); /*= java SelectFileDialog.ALL_TYPES*/
-+  std::pair<std::vector<std::u16string>, bool> accept_types = std::make_pair(
-+      types, false /*use_media_capture*/);
-+
-+  dialog_->SelectFile(
-+      ui::SelectFileDialog::SELECT_OPEN_FILE,
-+      std::u16string() /* dialog title*/, suggested_name, &allowed_file_info,
-+      0 /* file type index */, std::string() /* default file extension */,
-+      nativeWindow,
-+      &accept_types /* params */);
-+}
-+
-+
-+void LoadScriptFromPathOnFileTaskRunner(
-+  const base::FilePath& path,
-+  const std::string& display_name,
-+  UserScriptLoader::LoadSingleScriptCallback callback ) {
-+  DCHECK(GetUserScriptsFileTaskRunner()->RunsTasksInCurrentSequence());
-+
-+  std::unique_ptr<UserScript> userscript(new UserScript());
-+  std::u16string error;
-+  bool found_metadata = false;
-+  bool loaded = LoadUserScriptFromFile(path, GURL(), userscript, &found_metadata, &error);
-+
-+  bool result = loaded;
-+  if (result || found_metadata) {
-+    if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+      LOG(INFO) << "UserScriptLoader: found " << userscript->name() <<
-+                                    "-" << userscript->version() <<
-+                                    "-" << userscript->description();
-+    base::FilePath destination;
-+    if (GetOrCreatePath(destination) == false) {
-+      error = u"Cannot create destination.";
-+    } else {
-+      // we need an unique file name
-+      if (display_name.empty() == false) {
-+        userscript->set_key(display_name);
-+      }
-+
-+      // filename is original filename or display_name
-+      std::string file_name(userscript->key());
-+      base::i18n::ReplaceIllegalCharactersInPath(&file_name, '_');
-+      destination = destination.Append(file_name);
-+
-+      if (destination.ReferencesParent()) {
-+        error = u"Invalid file name.";
-+        result = false;
-+      } else if (base::PathExists(destination)) {
-+        error = u"User script already loaded.";
-+        result = false;
-+      } else {
-+        if (loaded) {
-+          // if is a correct userscript, copy it
-+          result = base::CopyFile(path, destination);
-+          if (result == false) {
-+            error = u"Copy error.";
-+          }
-+        } else {
-+          // else, there is a parser error
-+          // write minimal values and the error string, so UI can show it
-+          std::string combined_string = base::StrCat({
-+              kUserScriptBegin, "\n",
-+              kNamespaceDeclaration, " ", userscript->name_space(), "\n",
-+              kNameDeclaration, " ", userscript->name(), "\n",
-+              kVersionDeclaration, " ", userscript->version(), "\n",
-+              kDescriptionDeclaration, " ", userscript->description(), "\n",
-+              kUrlSourceDeclaration, " ", userscript->url_source(), "\n",
-+              kParserError, " ", base::UTF16ToASCII(error), "\n",
-+              kForceDisabled, " true\n",
-+              kUserScriptEnd, "\n"
-+          });
-+
-+          if (!base::WriteFile(destination, combined_string)) {
-+            error = u"Cannot write.";
-+            result = false;
-+          }
-+        }
-+      }
-+    }
-+  }
-+
-+  if (!error.empty()) {
-+    LOG(ERROR) << "UserScriptLoader: load error " << error;
-+  }
-+
-+  // return to callback with eventually the error
-+  const std::string string_error = base::UTF16ToASCII(error);
-+  content::GetUIThreadTaskRunner({base::TaskPriority::USER_BLOCKING})
-+      ->PostTask(FROM_HERE,
-+                 base::BindOnce(std::move(callback), result,
-+                                std::move(string_error)));
-+}
-+
-+void UserScriptLoader::TryToInstall(const base::FilePath& script_path) {
-+  if (!prefs_->IsEnabled()) return;
-+
-+  std::u16string file_display_name;
-+  base::MaybeGetFileDisplayName(script_path, &file_display_name);
-+
-+  std::string display_name = script_path.BaseName().value();
-+  if (base::IsStringASCII(file_display_name))
-+    display_name = base::UTF16ToASCII(file_display_name);
-+
-+  GetUserScriptsFileTaskRunner()->PostTask(
-+      FROM_HERE,
-+      base::BindOnce(
-+        &LoadScriptFromPathOnFileTaskRunner,
-+        script_path, display_name,
-+        base::BindOnce(
-+            &UserScriptLoader::LoadScriptFromPathOnFileTaskRunnerCallback,
-+            weak_factory_.GetWeakPtr()
-+        )
-+      ));
-+}
-+
-+void UserScriptLoader::FileSelected(
-+    const base::FilePath& path, int index, void* params) {
-+  if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+    LOG(INFO) << "UserScriptLoader: FileSelected " << path;
-+
-+  UserScriptLoader::TryToInstall(path);
-+}
-+
-+void UserScriptLoader::LoadScriptFromPathOnFileTaskRunnerCallback(
-+              bool result, const std::string& error) {
-+  for (auto& observer : observers_)
-+     observer.OnUserScriptLoaded(this, result, error);
-+
-+  StartLoad();
-+}
-+
-+void UserScriptLoader::FileSelectionCanceled(
-+    void* params) {
-+}
-+
-+}  // namespace extensions
-diff --git a/components/user_scripts/browser/user_script_loader.h b/components/user_scripts/browser/user_script_loader.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/browser/user_script_loader.h
-@@ -0,0 +1,170 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+#ifndef USERSCRIPTS_BROWSER_USER_SCRIPT_LOADER_H_
-+#define USERSCRIPTS_BROWSER_USER_SCRIPT_LOADER_H_
-+
-+#include <map>
-+#include <memory>
-+#include <set>
-+
-+#include "base/callback_forward.h"
-+#include "base/compiler_specific.h"
-+#include "base/macros.h"
-+#include "base/memory/read_only_shared_memory_region.h"
-+#include "base/memory/weak_ptr.h"
-+#include "base/observer_list.h"
-+#include "content/public/browser/render_process_host_creation_observer.h"
-+#include "ui/shell_dialogs/select_file_dialog.h"
-+#include "content/browser/file_system_access/file_system_chooser.h"
-+#include "ui/android/window_android.h"
-+
-+#include "../common/host_id.h"
-+#include "../common/user_script.h"
-+#include "user_script_prefs.h"
-+
-+namespace base {
-+class ReadOnlySharedMemoryRegion;
-+}
-+
-+namespace content {
-+class BrowserContext;
-+class RenderProcessHost;
-+}
-+
-+namespace user_scripts {
-+
-+// Manages one "logical unit" of user scripts in shared memory by constructing a
-+// new shared memory region when the set of scripts changes. Also notifies
-+// renderers of new shared memory region when new renderers appear, or when
-+// script reloading completes. Script loading lives on the file thread.
-+class UserScriptLoader : public content::RenderProcessHostCreationObserver,
-+                         public ui::SelectFileDialog::Listener {
-+ public:
-+  using LoadScriptsCallback =
-+      base::OnceCallback<void(std::unique_ptr<UserScriptList>)>;
-+  using LoadSingleScriptCallback =
-+      base::OnceCallback<void(bool result, const std::string& error)>;
-+
-+  using RemoveScriptCallback =
-+      base::OnceCallback<void()>;
-+  class Observer {
-+   public:
-+    virtual void OnScriptsLoaded(UserScriptLoader* loader,
-+                                 content::BrowserContext* browser_context) = 0;
-+    virtual void OnUserScriptLoaderDestroyed(UserScriptLoader* loader) = 0;
-+    virtual void OnUserScriptLoaded(UserScriptLoader* loader,
-+                                bool result, const std::string& error) = 0;
-+  };
-+
-+  // Parses the includes out of |script| and returns them in |includes|.
-+  static bool ParseMetadataHeader(const base::StringPiece& script_text,
-+                                  std::unique_ptr<UserScript>& script,
-+                                  bool *found_metadata,
-+                                  std::string& error_message);
-+
-+  UserScriptLoader(content::BrowserContext* browser_context,
-+                   UserScriptsPrefs* prefs);
-+                   //const HostID& host_id);
-+  ~UserScriptLoader() override;
-+
-+  // Initiates procedure to start loading scripts on the file thread.
-+  void StartLoad();
-+
-+  // Returns true if we have any scripts ready.
-+  bool initial_load_complete() const { return shared_memory_.IsValid(); }
-+
-+  // Pickle user scripts and return pointer to the shared memory.
-+  static base::ReadOnlySharedMemoryRegion Serialize(
-+      const user_scripts::UserScriptList& scripts);
-+
-+  // Adds or removes observers.
-+  void AddObserver(Observer* observer);
-+  void RemoveObserver(Observer* observer);
-+
-+  // Sets the flag if the initial set of hosts has finished loading; if it's
-+  // set to be true, calls AttempLoad() to bootstrap.
-+  void SetReady(bool ready);
-+
-+  void RemoveScript(const std::string& script_id);
-+  void SetScriptEnabled(const std::string& script_id, bool is_enabled);
-+
-+  void SelectAndAddScriptFromFile(ui::WindowAndroid* wa);
-+  void TryToInstall(const base::FilePath& script_path);
-+
-+  void LoadScripts(std::unique_ptr<UserScriptList> user_scripts,
-+                      LoadScriptsCallback callback);
-+
-+ protected:
-+  content::BrowserContext* browser_context() const { return browser_context_; }
-+
-+  UserScriptsPrefs* prefs() const { return prefs_; }
-+
-+ private:
-+  void OnRenderProcessHostCreated(
-+      content::RenderProcessHost* process_host) override;
-+
-+  // Attempts to initiate a load.
-+  void AttemptLoad();
-+
-+  // Called once we have finished loading the scripts on the file thread.
-+  void OnScriptsLoaded(std::unique_ptr<UserScriptList> user_scripts);
-+
-+  // Sends the renderer process a new set of user scripts. If
-+  // |changed_hosts| is not empty, this signals that only the scripts from
-+  // those hosts should be updated. Otherwise, all hosts will be
-+  // updated.
-+  void SendUpdate(content::RenderProcessHost* process,
-+                  const base::ReadOnlySharedMemoryRegion& shared_memory);
-+
-+  // Contains the scripts that were found the last time scripts were updated.
-+  base::ReadOnlySharedMemoryRegion shared_memory_;
-+
-+  // List of scripts that are currently loaded. This is null when a load is in
-+  // progress.
-+  std::unique_ptr<UserScriptList> loaded_scripts_;
-+
-+  // If the initial set of hosts has finished loading.
-+  bool ready_;
-+
-+  // The browser_context for which the scripts managed here are installed.
-+  content::BrowserContext* browser_context_;
-+
-+  // Manage load and store from preferences
-+  UserScriptsPrefs* prefs_;
-+
-+  // The associated observers.
-+  base::ObserverList<Observer>::Unchecked observers_;
-+
-+  void OnScriptRemoved();
-+
-+  // Manage file dialog requests
-+  scoped_refptr<ui::SelectFileDialog> dialog_;
-+  void FileSelected(const base::FilePath& path,
-+                    int index, void* params) override;
-+  void FileSelectionCanceled(void* params) override;
-+  void LoadScriptFromPathOnFileTaskRunnerCallback(
-+                    bool result, const std::string& error );
-+
-+  base::WeakPtrFactory<UserScriptLoader> weak_factory_{this};
-+
-+  DISALLOW_COPY_AND_ASSIGN(UserScriptLoader);
-+};
-+
-+}  // namespace extensions
-+
-+#endif  // USERSCRIPTS_BROWSER_USER_SCRIPT_LOADER_H_
-diff --git a/components/user_scripts/browser/user_script_pref_info.cc b/components/user_scripts/browser/user_script_pref_info.cc
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/browser/user_script_pref_info.cc
-@@ -0,0 +1,34 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+#include "user_script_pref_info.h"
-+
-+namespace user_scripts {
-+
-+UserScriptsListPrefs::ScriptInfo::ScriptInfo(const std::string& name,
-+                                             const std::string& description,
-+                                             const base::Time& install_time,
-+                                             bool enabled)
-+    : install_time(install_time),
-+      enabled(enabled),
-+      name_(name),
-+      description_(description) {}
-+
-+UserScriptsListPrefs::ScriptInfo::ScriptInfo(const ScriptInfo& other) = default;
-+UserScriptsListPrefs::ScriptInfo::~ScriptInfo() = default;
-+
-+}
-\ No newline at end of file
-diff --git a/components/user_scripts/browser/user_script_pref_info.h b/components/user_scripts/browser/user_script_pref_info.h
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/browser/user_script_pref_info.h
-@@ -0,0 +1,72 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+#ifndef USERSCRIPTS_BROWSER_USERSCRIPT_PREF_INFO_H_
-+#define USERSCRIPTS_BROWSER_USERSCRIPT_PREF_INFO_H_
-+
-+#include "base/values.h"
-+#include "base/time/time.h"
-+#include "components/keyed_service/core/keyed_service.h"
-+
-+namespace user_scripts {
-+
-+class UserScriptsListPrefs : public KeyedService {
-+ public:
-+  struct ScriptInfo {
-+    ScriptInfo(const std::string& name,
-+               const std::string& description,
-+               const base::Time& install_time,
-+               bool enabled);
-+    ScriptInfo(const ScriptInfo& other);
-+    ~ScriptInfo();
-+
-+    const std::string& name() const { return name_; }
-+    void set_name(const std::string& name) { name_ = name; }
-+
-+    const std::string& description() const { return description_; }
-+    void set_description(const std::string& description) { description_ = description; }
-+
-+    const std::string& version() const { return version_; }
-+    void set_version(const std::string& version) { version_ = version; }
-+
-+    const std::string& file_path() const { return file_path_; }
-+    void set_file_path(const std::string& file_path) { file_path_ = file_path; }
-+
-+    const std::string& url_source() const { return url_source_; }
-+    void set_url_source(const std::string& url_source) { url_source_ = url_source; }
-+
-+    const std::string& parser_error() const { return parser_error_; }
-+    void set_parser_error(const std::string& parser_error) { parser_error_ = parser_error; }
-+
-+    base::Time install_time;
-+    bool enabled;
-+
-+    bool force_disabled;
-+
-+  private:
-+    std::string name_;
-+    std::string description_;
-+    std::string version_;
-+    std::string file_path_;
-+    std::string url_source_;
-+    std::string parser_error_;
-+  };
-+};
-+
-+}
-+
-+#endif // USERSCRIPTS_BROWSER_USERSCRIPT_PREF_INFO_H_
-\ No newline at end of file
-diff --git a/components/user_scripts/browser/user_script_prefs.cc b/components/user_scripts/browser/user_script_prefs.cc
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/browser/user_script_prefs.cc
-@@ -0,0 +1,276 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+#include <map>
-+
-+#include "base/values.h"
-+#include "base/strings/string_number_conversions.h"
-+#include "base/json/json_writer.h"
-+
-+#include "chrome/browser/browser_process.h"
-+#include "chrome/browser/profiles/profile.h"
-+#include "chrome/browser/profiles/profile_manager.h"
-+
-+#include "components/prefs/pref_service.h"
-+#include "components/prefs/scoped_user_pref_update.h"
-+#include "components/pref_registry/pref_registry_syncable.h"
-+#include "user_script_prefs.h"
-+#include "user_script_pref_info.h"
-+#include "../common/user_script.h"
-+#include "../common/user_scripts_features.h"
-+
-+namespace user_scripts {
-+
-+namespace prefs {
-+  const char kUserScriptsEnabled[] = "userscripts.enabled";
-+}
-+
-+namespace {
-+
-+const char kUserScriptsStartup[] = "userscripts.startup";
-+
-+const char kUserScriptsList[] = "userscripts.scripts";
-+const char kScriptIsEnabled[] = "enabled";
-+const char kScriptName[] = "name";
-+const char kScriptDescription[] = "description";
-+const char kScriptVersion[] = "version";
-+const char kScriptInstallTime[] = "install_time";
-+const char kScriptFilePath[] = "file_path";
-+const char kScriptUrlSource[] = "url_source";
-+const char kScriptParserError[] = "parser_error";
-+const char kScriptForceDisabled[] = "force_disabled";
-+
-+class PrefUpdate : public DictionaryPrefUpdate {
-+ public:
-+  PrefUpdate(PrefService* service,
-+             const std::string& id,
-+             const std::string& path)
-+      : DictionaryPrefUpdate(service, path), id_(id) {}
-+
-+  ~PrefUpdate() override = default;
-+
-+  base::DictionaryValue* Get() override {
-+    base::DictionaryValue* dict = DictionaryPrefUpdate::Get();
-+    base::Value* dict_item =
-+        dict->FindKeyOfType(id_, base::Value::Type::DICTIONARY);
-+    if (!dict_item)
-+      dict_item = dict->SetKey(id_, base::Value(base::Value::Type::DICTIONARY));
-+    return static_cast<base::DictionaryValue*>(dict_item);
-+  }
-+
-+ private:
-+  const std::string id_;
-+
-+  DISALLOW_COPY_AND_ASSIGN(PrefUpdate);
-+};
-+
-+bool GetInt64FromPref(const base::DictionaryValue* dict,
-+                      const std::string& key,
-+                      int64_t* value) {
-+  DCHECK(dict);
-+  const std::string* value_str = dict->FindStringKey(key);
-+  if (!value_str) {
-+    VLOG(2) << "Can't find key in local pref dictionary. Invalid key: " << key
-+            << ".";
-+    return false;
-+  }
-+
-+  if (!base::StringToInt64(*value_str, value)) {
-+    VLOG(2) << "Can't change string to int64_t. Invalid string value: "
-+            << *value_str << ".";
-+    return false;
-+  }
-+
-+  return true;
-+}
-+
-+}
-+
-+UserScriptsPrefs::UserScriptsPrefs(
-+    PrefService* prefs)
-+    : prefs_(prefs) {
-+}
-+
-+// static
-+void UserScriptsPrefs::RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
-+  registry->RegisterBooleanPref(prefs::kUserScriptsEnabled, false);
-+  registry->RegisterIntegerPref(kUserScriptsStartup, 0);
-+  registry->RegisterDictionaryPref(kUserScriptsList);
-+}
-+
-+bool UserScriptsPrefs::IsEnabled() {
-+  return prefs_->GetBoolean(prefs::kUserScriptsEnabled);
-+}
-+
-+void UserScriptsPrefs::SetEnabled(bool enabled) {
-+  prefs_->SetBoolean(prefs::kUserScriptsEnabled, enabled);
-+  prefs_->CommitPendingWrite();
-+}
-+
-+void UserScriptsPrefs::StartupTryout(int number) {
-+  prefs_->SetInteger(kUserScriptsStartup, number);
-+  prefs_->CommitPendingWrite();
-+}
-+
-+int UserScriptsPrefs::GetCurrentStartupTryout() {
-+  return prefs_->GetInteger(kUserScriptsStartup);
-+}
-+
-+void UserScriptsPrefs::CompareWithPrefs(UserScriptList& user_scripts) {
-+  if (IsEnabled() == false) {
-+    if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+      LOG(INFO) << "UserScriptsPrefs: disabled by user";
-+
-+    user_scripts.clear();
-+    return;
-+  }
-+
-+  std::vector<std::string> all_scripts;
-+
-+  auto it = user_scripts.begin();
-+  while (it != user_scripts.end())
-+  {
-+    std::string key = it->get()->key();
-+    all_scripts.push_back(key);
-+
-+    std::unique_ptr<UserScriptsListPrefs::ScriptInfo> scriptInfo =
-+        UserScriptsPrefs::CreateScriptInfoFromPrefs(key);
-+
-+    // add or update prefs
-+    scriptInfo->set_name(it->get()->name());
-+    scriptInfo->set_description(it->get()->description());
-+    scriptInfo->set_version(it->get()->version());
-+    scriptInfo->set_file_path(it->get()->file_path());
-+    scriptInfo->set_url_source(it->get()->url_source());
-+    scriptInfo->set_parser_error(it->get()->parser_error());
-+    scriptInfo->force_disabled = (it->get()->force_disabled());
-+
-+    PrefUpdate update(prefs_, key, kUserScriptsList);
-+    base::DictionaryValue* script_dict = update.Get();
-+
-+    script_dict->SetString(kScriptName, scriptInfo->name());
-+    script_dict->SetString(kScriptDescription, scriptInfo->description());
-+    script_dict->SetBoolean(kScriptIsEnabled, scriptInfo->enabled);
-+    script_dict->SetString(kScriptVersion, scriptInfo->version());
-+    script_dict->SetString(kScriptFilePath, scriptInfo->file_path());
-+    script_dict->SetString(kScriptUrlSource, scriptInfo->url_source());
-+    script_dict->SetString(kScriptParserError, scriptInfo->parser_error());
-+    script_dict->SetBoolean(kScriptForceDisabled, scriptInfo->force_disabled);
-+
-+    std::string install_time_str =
-+        base::NumberToString(scriptInfo->install_time.ToInternalValue());
-+    script_dict->SetString(kScriptInstallTime, install_time_str);
-+
-+   if (!scriptInfo->enabled) {
-+      it = user_scripts.erase(it);
-+    } else {
-+      ++it;
-+    }
-+  }
-+
-+  // remove script from prefs if no more present
-+  std::vector<std::string> all_scripts_to_remove;
-+  const base::DictionaryValue* dict =
-+    prefs_->GetDictionary(kUserScriptsList);
-+  for (base::DictionaryValue::Iterator script_it(*dict); !script_it.IsAtEnd();
-+       script_it.Advance()) {
-+    const std::string& key = script_it.key();
-+
-+    if (std::find(all_scripts.begin(), all_scripts.end(), key) == all_scripts.end()) {
-+      all_scripts_to_remove.push_back(key);
-+    }
-+  }
-+
-+  DictionaryPrefUpdate update(prefs_, kUserScriptsList);
-+  base::DictionaryValue* const update_dict = update.Get();
-+  for (auto key : all_scripts_to_remove) {
-+      update_dict->RemoveKey(key);
-+  }
-+
-+  return;
-+}
-+
-+std::string UserScriptsPrefs::GetScriptsInfo() {
-+  std::string json_string;
-+
-+  const base::DictionaryValue* dict =
-+    prefs_->GetDictionary(kUserScriptsList);
-+
-+  if (dict) {
-+    base::JSONWriter::WriteWithOptions(
-+        *dict, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json_string);
-+    base::TrimWhitespaceASCII(json_string, base::TRIM_ALL, &json_string);
-+  }
-+
-+  return json_string;
-+}
-+
-+std::unique_ptr<UserScriptsListPrefs::ScriptInfo> UserScriptsPrefs::CreateScriptInfoFromPrefs(
-+    const std::string& script_id) const {
-+
-+  auto scriptInfo = std::make_unique<UserScriptsListPrefs::ScriptInfo>(
-+      script_id, "", base::Time::Now(), false);
-+
-+  const base::DictionaryValue* scripts =
-+      prefs_->GetDictionary(kUserScriptsList);
-+  if (!scripts)
-+    return scriptInfo;
-+
-+  const base::DictionaryValue* script = static_cast<const base::DictionaryValue*>(
-+    scripts->FindDictKey(script_id));
-+  if (!script)
-+    return scriptInfo;
-+
-+  const std::string* name = script->FindStringKey(kScriptName);
-+  const std::string* description = script->FindStringKey(kScriptDescription);
-+  const std::string* version = script->FindStringKey(kScriptVersion);
-+  const std::string* file_path = script->FindStringKey(kScriptFilePath);
-+  const std::string* url_source = script->FindStringKey(kScriptUrlSource);
-+  const std::string* parser_error = script->FindStringKey(kScriptParserError);
-+
-+  scriptInfo->set_name( name ? *name : "no name" );
-+  scriptInfo->set_description( description ? *description : "no description" );
-+  scriptInfo->set_version( version ? *version : "no version" );
-+  scriptInfo->enabled = script->FindBoolKey(kScriptIsEnabled).value_or(false);
-+  scriptInfo->set_file_path( file_path ? *file_path : "no file path" );
-+  scriptInfo->set_url_source( url_source ? *url_source : "" );
-+  scriptInfo->set_parser_error( parser_error ? *parser_error : "" );
-+  scriptInfo->force_disabled = script->FindBoolKey(kScriptForceDisabled).value_or(false);
-+
-+  int64_t time_interval = 0;
-+  if (GetInt64FromPref(script, kScriptInstallTime, &time_interval)) {
-+    scriptInfo->install_time = base::Time::FromInternalValue(time_interval);
-+  }
-+
-+  return scriptInfo;
-+}
-+
-+void UserScriptsPrefs::RemoveScriptFromPrefs(const std::string& script_id) {
-+  DictionaryPrefUpdate update(prefs_, kUserScriptsList);
-+  base::DictionaryValue* const update_dict = update.Get();
-+  update_dict->RemoveKey(script_id);
-+}
-+
-+void UserScriptsPrefs::SetScriptEnabled(const std::string& script_id, bool is_enabled) {
-+  PrefUpdate update(prefs_, script_id, kUserScriptsList);
-+  base::DictionaryValue* script_dict = update.Get();
-+  if (script_dict->FindBoolKey(kScriptForceDisabled).value_or(false))
-+    is_enabled = true;
-+  script_dict->SetBoolean(kScriptIsEnabled, is_enabled);
-+}
-+
-+}
-diff --git a/components/user_scripts/browser/user_script_prefs.h b/components/user_scripts/browser/user_script_prefs.h
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/browser/user_script_prefs.h
-@@ -0,0 +1,62 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+#ifndef USERSCRIPTS_BROWSER_USERSCRIPT_PREFS_H_
-+#define USERSCRIPTS_BROWSER_USERSCRIPT_PREFS_H_
-+
-+#include "content/public/browser/browser_context.h"
-+#include "components/prefs/pref_service.h"
-+#include "components/pref_registry/pref_registry_syncable.h"
-+
-+#include "user_script_pref_info.h"
-+#include "../common/user_script.h"
-+
-+namespace user_scripts {
-+
-+namespace prefs {
-+    extern const char kUserScriptsEnabled[];
-+}
-+
-+class UserScriptsPrefs {
-+ public:
-+    UserScriptsPrefs(
-+        PrefService* prefs);
-+
-+    static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
-+
-+    bool IsEnabled();
-+    void SetEnabled(bool enabled);
-+
-+    void StartupTryout(int number);
-+    int GetCurrentStartupTryout();
-+
-+    void CompareWithPrefs(UserScriptList& user_scripts);
-+
-+    std::string GetScriptsInfo();
-+    void RemoveScriptFromPrefs(const std::string& script_id);
-+    void SetScriptEnabled(const std::string& script_id, bool is_enabled);
-+
-+    std::unique_ptr<UserScriptsListPrefs::ScriptInfo> CreateScriptInfoFromPrefs(
-+        const std::string& script_id) const;
-+
-+ private:
-+    PrefService* prefs_;
-+};
-+
-+}
-+
-+#endif // USERSCRIPTS_BROWSER_USERSCRIPT_PREFS_H_
-\ No newline at end of file
-diff --git a/components/user_scripts/browser/userscripts_browser_client.cc b/components/user_scripts/browser/userscripts_browser_client.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/browser/userscripts_browser_client.cc
-@@ -0,0 +1,78 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+#include "userscripts_browser_client.h"
-+
-+#include "base/logging.h"
-+
-+#include "chrome/browser/browser_process.h"
-+
-+#include "chrome/browser/profiles/profile.h"
-+#include "chrome/browser/profiles/profile_manager.h"
-+
-+#include "../common/user_scripts_features.h"
-+#include "user_script_loader.h"
-+#include "file_task_runner.h"
-+#include "user_script_prefs.h"
-+
-+namespace user_scripts {
-+
-+namespace {
-+
-+// remember: was ExtensionsBrowserClient
-+UserScriptsBrowserClient* g_userscripts_browser_client = NULL;
-+
-+}  // namespace
-+
-+UserScriptsBrowserClient::UserScriptsBrowserClient() {}
-+
-+UserScriptsBrowserClient::~UserScriptsBrowserClient() = default;
-+
-+// static
-+UserScriptsBrowserClient* UserScriptsBrowserClient::GetInstance() {
-+  // only for browser process
-+  if (!g_browser_process)
-+    return NULL;
-+
-+  // singleton
-+  if (g_userscripts_browser_client)
-+    return g_userscripts_browser_client;
-+
-+  // make file task runner
-+  GetUserScriptsFileTaskRunner().get();
-+
-+  // new instance singleton
-+  g_userscripts_browser_client = new UserScriptsBrowserClient();
-+
-+  return g_userscripts_browser_client;
-+}
-+
-+void UserScriptsBrowserClient::SetProfile(content::BrowserContext* context) {
-+  browser_context_ = context;
-+
-+  prefs_ =
-+    std::make_unique<user_scripts::UserScriptsPrefs>(
-+      static_cast<Profile*>(context)->GetPrefs());
-+
-+  userscript_loader_ =
-+    std::make_unique<user_scripts::UserScriptLoader>(browser_context_, prefs_.get());
-+  if (prefs_->IsEnabled()) {
-+    userscript_loader_->SetReady(true);
-+  }
-+}
-+
-+}  // namespace user_scripts
-diff --git a/components/user_scripts/browser/userscripts_browser_client.h b/components/user_scripts/browser/userscripts_browser_client.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/browser/userscripts_browser_client.h
-@@ -0,0 +1,62 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+#ifndef USERSCRIPTS_BROWSER_USERSCRIPTS_BROWSER_CLIENT_H_
-+#define USERSCRIPTS_BROWSER_USERSCRIPTS_BROWSER_CLIENT_H_
-+
-+#include <memory>
-+#include <string>
-+#include <vector>
-+
-+#include "content/public/browser/browser_context.h"
-+
-+#include "../common/user_script.h"
-+#include "user_script_loader.h"
-+#include "user_script_prefs.h"
-+
-+namespace user_scripts {
-+
-+class UserScriptsBrowserClient {
-+ public:
-+  UserScriptsBrowserClient();
-+  UserScriptsBrowserClient(const UserScriptsBrowserClient&) = delete;
-+  UserScriptsBrowserClient& operator=(const UserScriptsBrowserClient&) = delete;
-+  virtual ~UserScriptsBrowserClient();
-+
-+  // Returns the single instance of |this|.
-+  static UserScriptsBrowserClient* GetInstance();
-+
-+  void SetProfile(content::BrowserContext* context);
-+
-+  user_scripts::UserScriptsPrefs* GetPrefs() {
-+    return prefs_.get();
-+  }
-+
-+  user_scripts::UserScriptLoader* GetLoader() {
-+    return userscript_loader_.get();
-+  }
-+
-+  private:
-+    std::unique_ptr<UserScriptList> scripts_;
-+    content::BrowserContext* browser_context_;
-+    std::unique_ptr<user_scripts::UserScriptsPrefs> prefs_;
-+    std::unique_ptr<user_scripts::UserScriptLoader> userscript_loader_;
-+};
-+
-+}  // namespace extensions
-+
-+#endif  // USERSCRIPTS_BROWSER_USERSCRIPTS_BROWSER_CLIENT_H_
-diff --git a/components/user_scripts/common/BUILD.gn b/components/user_scripts/common/BUILD.gn
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/common/BUILD.gn
-@@ -0,0 +1,49 @@
-+# Copyright 2014 The Chromium Authors. All rights reserved.
-+# Use of this source code is governed by a BSD-style license that can be
-+# found in the LICENSE file.
-+
-+import("//build/config/features.gni")
-+import("//mojo/public/tools/bindings/mojom.gni")
-+
-+static_library("common") {
-+  sources = [
-+    "user_scripts_features.cc",
-+    "user_scripts_features.h",
-+    "constants.h",
-+    "host_id.cc",
-+    "host_id.h",
-+    "script_constants.h",
-+    "url_pattern_set.cc",
-+    "url_pattern_set.h",
-+    "url_pattern.cc",
-+    "url_pattern.h",
-+    "user_script.cc",
-+    "user_script.h",
-+    "view_type.cc",
-+    "view_type.h",
-+    "extension_messages.cc",
-+    "extension_messages.h",
-+    "extension_message_generator.cc",
-+    "extension_message_generator.h",
-+  ]
-+
-+  configs += [
-+    "//build/config:precompiled_headers",
-+    "//build/config/compiler:wexit_time_destructors",
-+  ]
-+
-+  public_deps = [
-+    "//components/services/app_service/public/cpp:app_file_handling",
-+    "//content/public/common",
-+    "//ipc",
-+    "//skia",
-+  ]
-+
-+  deps = [
-+    "//base",
-+    "//components/url_formatter",
-+    "//components/url_matcher",
-+    "//components/version_info",
-+    "//crypto",
-+  ]
-+}
-diff --git a/components/user_scripts/common/constants.h b/components/user_scripts/common/constants.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/common/constants.h
-@@ -0,0 +1,21 @@
-+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#ifndef USERSCRIPTS_COMMON_CONSTANTS_H_
-+#define USERSCRIPTS_COMMON_CONSTANTS_H_
-+
-+#include "base/files/file_path.h"
-+#include "base/strings/string_piece_forward.h"
-+#include "components/services/app_service/public/mojom/types.mojom.h"
-+#include "components/version_info/channel.h"
-+#include "ui/base/layout.h"
-+
-+namespace user_scripts {
-+
-+// The origin of injected CSS.
-+enum CSSOrigin { /*CSS_ORIGIN_AUTHOR,*/ CSS_ORIGIN_USER };
-+
-+}  // namespace user_scripts
-+
-+#endif  // USERSCRIPTS_COMMON_CONSTANTS_H_
-diff --git a/components/user_scripts/common/error_utils.cc b/components/user_scripts/common/error_utils.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/common/error_utils.cc
-@@ -0,0 +1,54 @@
-+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#include "error_utils.h"
-+
-+#include <initializer_list>
-+
-+#include "base/check_op.h"
-+#include "base/strings/string_tokenizer.h"
-+#include "base/strings/string_util.h"
-+#include "base/strings/utf_string_conversions.h"
-+
-+namespace user_scripts {
-+
-+namespace {
-+
-+std::string FormatErrorMessageInternal(
-+    base::StringPiece format,
-+    std::initializer_list<base::StringPiece> args) {
-+  std::string format_str = format.as_string();
-+  base::StringTokenizer tokenizer(format_str, "*");
-+  tokenizer.set_options(base::StringTokenizer::RETURN_DELIMS);
-+
-+  std::vector<base::StringPiece> result_pieces;
-+  auto* args_it = args.begin();
-+  while (tokenizer.GetNext()) {
-+    if (!tokenizer.token_is_delim()) {
-+      result_pieces.push_back(tokenizer.token_piece());
-+      continue;
-+    }
-+
-+    CHECK_NE(args_it, args.end())
-+        << "More placeholders (*) than substitutions.";
-+
-+    // Substitute the argument.
-+    result_pieces.push_back(*args_it);
-+    args_it++;
-+  }
-+
-+  // Not all substitutions were consumed.
-+  CHECK_EQ(args_it, args.end()) << "Fewer placeholders (*) than substitutions.";
-+
-+  return base::JoinString(result_pieces, "" /* separator */);
-+}
-+
-+}  // namespace
-+
-+std::string ErrorUtils::FormatErrorMessage(base::StringPiece format,
-+                                           base::StringPiece s1) {
-+  return FormatErrorMessageInternal(format, {s1});
-+}
-+
-+}  // namespace user_scripts
-diff --git a/components/user_scripts/common/error_utils.h b/components/user_scripts/common/error_utils.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/common/error_utils.h
-@@ -0,0 +1,24 @@
-+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#ifndef USERSCRIPTS_COMMON_ERROR_UTILS_H_
-+#define USERSCRIPTS_COMMON_ERROR_UTILS_H_
-+
-+#include <string>
-+
-+#include "base/strings/string_piece.h"
-+
-+namespace user_scripts {
-+
-+class ErrorUtils {
-+ public:
-+   // Creates an error messages from a pattern.
-+   static std::string FormatErrorMessage(base::StringPiece format,
-+                                         base::StringPiece s1);
-+
-+};
-+
-+}  // namespace extensions
-+
-+#endif  // USERSCRIPTS_COMMON_ERROR_UTILS_H_
-diff --git a/components/user_scripts/common/extension_message_generator.cc b/components/user_scripts/common/extension_message_generator.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/common/extension_message_generator.cc
-@@ -0,0 +1,29 @@
-+// Copyright 2014 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+// Get basic type definitions.
-+#define IPC_MESSAGE_IMPL
-+#include "components/user_scripts/common/extension_message_generator.h"
-+
-+// Generate constructors.
-+#include "ipc/struct_constructor_macros.h"
-+#include "components/user_scripts/common/extension_message_generator.h"
-+
-+// Generate param traits write methods.
-+#include "ipc/param_traits_write_macros.h"
-+namespace IPC {
-+#include "components/user_scripts/common/extension_message_generator.h"
-+}  // namespace IPC
-+
-+// Generate param traits read methods.
-+#include "ipc/param_traits_read_macros.h"
-+namespace IPC {
-+#include "components/user_scripts/common/extension_message_generator.h"
-+}  // namespace IPC
-+
-+// Generate param traits log methods.
-+#include "ipc/param_traits_log_macros.h"
-+namespace IPC {
-+#include "components/user_scripts/common/extension_message_generator.h"
-+}  // namespace IPC
-diff --git a/components/user_scripts/common/extension_message_generator.h b/components/user_scripts/common/extension_message_generator.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/common/extension_message_generator.h
-@@ -0,0 +1,11 @@
-+// Copyright 2014 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+// Multiply-included file, hence no include guard.
-+
-+#undef USERSCRIPTS_COMMON_EXTENSION_MESSAGES_H_
-+#include "extension_messages.h"
-+#ifndef USERSCRIPTS_COMMON_EXTENSION_MESSAGES_H_
-+#error "Failed to include header extension_messages.h"
-+#endif
-diff --git a/components/user_scripts/common/extension_messages.cc b/components/user_scripts/common/extension_messages.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/common/extension_messages.cc
-@@ -0,0 +1,40 @@
-+// Copyright 2014 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#include "extension_messages.h"
-+
-+#include <stddef.h>
-+
-+#include <memory>
-+#include <utility>
-+
-+#include "content/public/common/common_param_traits.h"
-+
-+namespace IPC {
-+
-+void ParamTraits<HostID>::Write(base::Pickle* m, const param_type& p) {
-+  WriteParam(m, p.type());
-+  WriteParam(m, p.id());
-+}
-+
-+bool ParamTraits<HostID>::Read(const base::Pickle* m,
-+                               base::PickleIterator* iter,
-+                               param_type* r) {
-+  HostID::HostType type;
-+  std::string id;
-+  if (!ReadParam(m, iter, &type))
-+    return false;
-+  if (!ReadParam(m, iter, &id))
-+    return false;
-+  *r = HostID(type, id);
-+  return true;
-+}
-+
-+void ParamTraits<HostID>::Log(
-+    const param_type& p, std::string* l) {
-+  LogParam(p.type(), l);
-+  LogParam(p.id(), l);
-+}
-+
-+}  // namespace IPC
-diff --git a/components/user_scripts/common/extension_messages.h b/components/user_scripts/common/extension_messages.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/common/extension_messages.h
-@@ -0,0 +1,71 @@
-+// Copyright 2014 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+// IPC messages for extensions.
-+
-+#ifndef USERSCRIPTS_COMMON_EXTENSION_MESSAGES_H_
-+#define USERSCRIPTS_COMMON_EXTENSION_MESSAGES_H_
-+
-+#include <stdint.h>
-+
-+#include <map>
-+#include <memory>
-+#include <set>
-+#include <string>
-+#include <vector>
-+
-+#include "base/macros.h"
-+#include "base/memory/read_only_shared_memory_region.h"
-+#include "base/values.h"
-+#include "content/public/common/common_param_traits.h"
-+#include "constants.h"
-+#include "host_id.h"
-+#include "ipc/ipc_message_start.h"
-+#include "ipc/ipc_message_macros.h"
-+#include "url/gurl.h"
-+#include "url/origin.h"
-+
-+#define IPC_MESSAGE_START ExtensionMsgStart
-+
-+IPC_ENUM_TRAITS_MAX_VALUE(HostID::HostType, HostID::HOST_TYPE_LAST)
-+
-+// Singly-included section for custom IPC traits.
-+#ifndef INTERNAL_USERSCRIPTS_COMMON_EXTENSION_MESSAGES_H_
-+#define INTERNAL_USERSCRIPTS_COMMON_EXTENSION_MESSAGES_H_
-+
-+namespace IPC {
-+
-+template <>
-+struct ParamTraits<HostID> {
-+  typedef HostID param_type;
-+  static void Write(base::Pickle* m, const param_type& p);
-+  static bool Read(const base::Pickle* m,
-+                   base::PickleIterator* iter,
-+                   param_type* r);
-+  static void Log(const param_type& p, std::string* l);
-+};
-+
-+
-+}  // namespace IPC
-+
-+#endif  // INTERNAL_USERSCRIPTS_COMMON_EXTENSION_MESSAGES_H_
-+
-+// Notification that the user scripts have been updated. It has one
-+// ReadOnlySharedMemoryRegion argument consisting of the pickled script data.
-+// This memory region is valid in the context of the renderer.
-+// If |owner| is not empty, then the shared memory handle refers to |owner|'s
-+// programmatically-defined scripts. Otherwise, the handle refers to all
-+// hosts' statically defined scripts. So far, only extension-hosts support
-+// statically defined scripts; WebUI-hosts don't.
-+// If |changed_hosts| is not empty, only the host in that set will
-+// be updated. Otherwise, all hosts that have scripts in the shared memory
-+// region will be updated. Note that the empty set => all hosts case is not
-+// supported for per-extension programmatically-defined script regions; in such
-+// regions, the owner is expected to list itself as the only changed host.
-+// If |whitelisted_only| is true, this process should only run whitelisted
-+// scripts and not all user scripts.
-+IPC_MESSAGE_CONTROL1(ExtensionMsg_UpdateUserScripts,
-+                     base::ReadOnlySharedMemoryRegion)
-+
-+#endif  // USERSCRIPTS_COMMON_EXTENSION_MESSAGES_H_
-diff --git a/components/user_scripts/common/host_id.cc b/components/user_scripts/common/host_id.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/common/host_id.cc
-@@ -0,0 +1,31 @@
-+// Copyright 2015 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#include "host_id.h"
-+
-+#include <tuple>
-+
-+HostID::HostID()
-+    : type_(HostType::EXTENSIONS) {
-+}
-+
-+HostID::HostID(HostType type, const std::string& id)
-+    : type_(type), id_(id) {
-+}
-+
-+HostID::HostID(const HostID& host_id)
-+    : type_(host_id.type()),
-+      id_(host_id.id()) {
-+}
-+
-+HostID::~HostID() {
-+}
-+
-+bool HostID::operator<(const HostID& host_id) const {
-+  return std::tie(type_, id_) < std::tie(host_id.type_, host_id.id_);
-+}
-+
-+bool HostID::operator==(const HostID& host_id) const {
-+  return type_ == host_id.type_ && id_ == host_id.id_;
-+}
-diff --git a/components/user_scripts/common/host_id.h b/components/user_scripts/common/host_id.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/common/host_id.h
-@@ -0,0 +1,35 @@
-+// Copyright 2015 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#ifndef USERSCRIPTS_COMMON_HOST_ID_H_
-+#define USERSCRIPTS_COMMON_HOST_ID_H_
-+
-+#include <string>
-+
-+// IDs of hosts who own user scripts.
-+// A HostID is immutable after creation.
-+struct HostID {
-+  enum HostType { EXTENSIONS, WEBUI, HOST_TYPE_LAST = WEBUI };
-+
-+  HostID();
-+  HostID(HostType type, const std::string& id);
-+  HostID(const HostID& host_id);
-+  ~HostID();
-+
-+  bool operator<(const HostID& host_id) const;
-+  bool operator==(const HostID& host_id) const;
-+
-+  HostType type() const { return type_; }
-+  const std::string& id() const { return id_; }
-+
-+ private:
-+  // The type of the host.
-+  HostType type_;
-+
-+  // Similar to extension_id, host_id is a unique indentifier for a host,
-+  // e.g., an Extension or WebUI.
-+  std::string id_;
-+};
-+
-+#endif  // USERSCRIPTS_COMMON_HOST_ID_H_
-diff --git a/components/user_scripts/common/script_constants.h b/components/user_scripts/common/script_constants.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/common/script_constants.h
-@@ -0,0 +1,33 @@
-+// Copyright 2020 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#ifndef USERSCRIPTS_COMMON_SCRIPT_CONSTANTS_H_
-+#define USERSCRIPTS_COMMON_SCRIPT_CONSTANTS_H_
-+
-+namespace user_scripts {
-+
-+// Whether to fall back to matching the origin for frames where the URL
-+// cannot be matched directly, such as those with about: or data: schemes.
-+enum class MatchOriginAsFallbackBehavior {
-+  // Never fall back on the origin; this means scripts will never match on
-+  // these frames.
-+  kNever,
-+  // Match the origin only for about:-scheme frames, and then climb the frame
-+  // tree to find an appropriate ancestor to get a full URL (including path).
-+  // This is for supporting the "match_about_blank" key.
-+  // TODO(devlin): I wonder if we could simplify this to be "MatchForAbout",
-+  // and not worry about climbing the frame tree. It would be a behavior
-+  // change, but I wonder how many extensions it would impact in practice.
-+  kMatchForAboutSchemeAndClimbTree,
-+  // Match the origin as a fallback whenever applicable. This won't have a
-+  // corresponding path.
-+  kAlways,
-+};
-+
-+// TODO(devlin): Move the other non-UserScript-specific constants like
-+// RunLocation and InjectionType from UserScript into here.
-+
-+}
-+
-+#endif  // USERSCRIPTS_COMMON_SCRIPT_CONSTANTS_H_
-diff --git a/components/user_scripts/common/url_pattern.cc b/components/user_scripts/common/url_pattern.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/common/url_pattern.cc
-@@ -0,0 +1,803 @@
-+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#include "url_pattern.h"
-+
-+#include <stddef.h>
-+
-+#include <ostream>
-+
-+#include "base/logging.h"
-+#include "base/strings/pattern.h"
-+#include "base/strings/strcat.h"
-+#include "base/strings/string_number_conversions.h"
-+#include "base/strings/string_piece.h"
-+#include "base/strings/string_split.h"
-+#include "base/strings/string_util.h"
-+#include "base/strings/stringprintf.h"
-+#include "content/public/common/url_constants.h"
-+#include "constants.h"
-+#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
-+#include "net/base/url_util.h"
-+#include "url/gurl.h"
-+#include "url/url_util.h"
-+
-+const char URLPattern::kAllUrlsPattern[] = "<all_urls>";
-+
-+namespace {
-+
-+// TODO(aa): What about more obscure schemes like javascript: ?
-+// Note: keep this array in sync with kValidSchemeMasks.
-+const char* const kValidSchemes[] = {
-+    url::kHttpScheme,         url::kHttpsScheme,
-+    url::kFileScheme,         url::kFtpScheme,
-+    /*content::kChromeUIScheme,*/ /*extensions::kExtensionScheme,*/
-+    url::kFileSystemScheme,   url::kWsScheme,
-+    url::kWssScheme,          url::kDataScheme,
-+    url::kUrnScheme,
-+};
-+
-+const int kValidSchemeMasks[] = {
-+    URLPattern::SCHEME_HTTP,       URLPattern::SCHEME_HTTPS,
-+    URLPattern::SCHEME_FILE,       URLPattern::SCHEME_FTP,
-+    /*URLPattern::SCHEME_CHROMEUI,*/   /*URLPattern::SCHEME_EXTENSION,*/
-+    URLPattern::SCHEME_FILESYSTEM, URLPattern::SCHEME_WS,
-+    URLPattern::SCHEME_WSS,        URLPattern::SCHEME_DATA,
-+    URLPattern::SCHEME_URN,
-+};
-+
-+static_assert(base::size(kValidSchemes) == base::size(kValidSchemeMasks),
-+              "must keep these arrays in sync");
-+
-+const char kParseSuccess[] = "Success.";
-+const char kParseErrorMissingSchemeSeparator[] = "Missing scheme separator.";
-+const char kParseErrorInvalidScheme[] = "Invalid scheme.";
-+const char kParseErrorWrongSchemeType[] = "Wrong scheme type.";
-+const char kParseErrorEmptyHost[] = "Host can not be empty.";
-+const char kParseErrorInvalidHostWildcard[] = "Invalid host wildcard.";
-+const char kParseErrorEmptyPath[] = "Empty path.";
-+const char kParseErrorInvalidPort[] = "Invalid port.";
-+const char kParseErrorInvalidHost[] = "Invalid host.";
-+
-+// Message explaining each URLPattern::ParseResult.
-+const char* const kParseResultMessages[] = {
-+  kParseSuccess,
-+  kParseErrorMissingSchemeSeparator,
-+  kParseErrorInvalidScheme,
-+  kParseErrorWrongSchemeType,
-+  kParseErrorEmptyHost,
-+  kParseErrorInvalidHostWildcard,
-+  kParseErrorEmptyPath,
-+  kParseErrorInvalidPort,
-+  kParseErrorInvalidHost,
-+};
-+
-+static_assert(static_cast<int>(URLPattern::ParseResult::kNumParseResults) ==
-+                  base::size(kParseResultMessages),
-+              "must add message for each parse result");
-+
-+const char kPathSeparator[] = "/";
-+
-+bool IsStandardScheme(base::StringPiece scheme) {
-+  // "*" gets the same treatment as a standard scheme.
-+  if (scheme == "*")
-+    return true;
-+
-+  return url::IsStandard(scheme.data(),
-+                         url::Component(0, static_cast<int>(scheme.length())));
-+}
-+
-+bool IsValidPortForScheme(base::StringPiece scheme, base::StringPiece port) {
-+  if (port == "*")
-+    return true;
-+
-+  // Only accept non-wildcard ports if the scheme uses ports.
-+  if (url::DefaultPortForScheme(scheme.data(), scheme.length()) ==
-+      url::PORT_UNSPECIFIED) {
-+    return false;
-+  }
-+
-+  int parsed_port = url::PORT_UNSPECIFIED;
-+  if (!base::StringToInt(port, &parsed_port))
-+    return false;
-+  return (parsed_port >= 0) && (parsed_port < 65536);
-+}
-+
-+// Returns |path| with the trailing wildcard stripped if one existed.
-+//
-+// The functions that rely on this (OverlapsWith and Contains) are only
-+// called for the patterns inside URLPatternSet. In those cases, we know that
-+// the path will have only a single wildcard at the end. This makes figuring
-+// out overlap much easier. It seems like there is probably a computer-sciency
-+// way to solve the general case, but we don't need that yet.
-+base::StringPiece StripTrailingWildcard(base::StringPiece path) {
-+  if (base::EndsWith(path, "*"))
-+    path.remove_suffix(1);
-+  return path;
-+}
-+
-+// Removes trailing dot from |host_piece| if any.
-+base::StringPiece CanonicalizeHostForMatching(base::StringPiece host_piece) {
-+  if (base::EndsWith(host_piece, "."))
-+    host_piece.remove_suffix(1);
-+  return host_piece;
-+}
-+
-+}  // namespace
-+
-+// static
-+bool URLPattern::IsValidSchemeForExtensions(base::StringPiece scheme) {
-+  for (size_t i = 0; i < base::size(kValidSchemes); ++i) {
-+    if (scheme == kValidSchemes[i])
-+      return true;
-+  }
-+  return false;
-+}
-+
-+// static
-+int URLPattern::GetValidSchemeMaskForExtensions() {
-+  int result = 0;
-+  for (size_t i = 0; i < base::size(kValidSchemeMasks); ++i)
-+    result |= kValidSchemeMasks[i];
-+  return result;
-+}
-+
-+URLPattern::URLPattern()
-+    : valid_schemes_(SCHEME_NONE),
-+      match_all_urls_(false),
-+      match_subdomains_(false),
-+      port_("*") {}
-+
-+URLPattern::URLPattern(int valid_schemes)
-+    : valid_schemes_(valid_schemes),
-+      match_all_urls_(false),
-+      match_subdomains_(false),
-+      port_("*") {}
-+
-+URLPattern::URLPattern(int valid_schemes, base::StringPiece pattern)
-+    // Strict error checking is used, because this constructor is only
-+    // appropriate when we know |pattern| is valid.
-+    : valid_schemes_(valid_schemes),
-+      match_all_urls_(false),
-+      match_subdomains_(false),
-+      port_("*") {
-+  ParseResult result = Parse(pattern);
-+  DCHECK_EQ(ParseResult::kSuccess, result)
-+      << "Parsing unexpectedly failed for pattern: " << pattern << ": "
-+      << GetParseResultString(result);
-+}
-+
-+URLPattern::URLPattern(const URLPattern& other) = default;
-+
-+URLPattern::URLPattern(URLPattern&& other) = default;
-+
-+URLPattern::~URLPattern() {
-+}
-+
-+URLPattern& URLPattern::operator=(const URLPattern& other) = default;
-+
-+URLPattern& URLPattern::operator=(URLPattern&& other) = default;
-+
-+bool URLPattern::operator<(const URLPattern& other) const {
-+  return GetAsString() < other.GetAsString();
-+}
-+
-+bool URLPattern::operator>(const URLPattern& other) const {
-+  return GetAsString() > other.GetAsString();
-+}
-+
-+bool URLPattern::operator==(const URLPattern& other) const {
-+  return GetAsString() == other.GetAsString();
-+}
-+
-+std::ostream& operator<<(std::ostream& out, const URLPattern& url_pattern) {
-+  return out << '"' << url_pattern.GetAsString() << '"';
-+}
-+
-+URLPattern::ParseResult URLPattern::Parse(base::StringPiece pattern) {
-+  spec_.clear();
-+  SetMatchAllURLs(false);
-+  SetMatchSubdomains(false);
-+  SetPort("*");
-+
-+  // Special case pattern to match every valid URL.
-+  if (pattern == kAllUrlsPattern) {
-+    SetMatchAllURLs(true);
-+    return ParseResult::kSuccess;
-+  }
-+
-+  // Parse out the scheme.
-+  size_t scheme_end_pos = pattern.find(url::kStandardSchemeSeparator);
-+  bool has_standard_scheme_separator = true;
-+
-+  // Some urls also use ':' alone as the scheme separator.
-+  if (scheme_end_pos == base::StringPiece::npos) {
-+    scheme_end_pos = pattern.find(':');
-+    has_standard_scheme_separator = false;
-+  }
-+
-+  if (scheme_end_pos == base::StringPiece::npos)
-+    return ParseResult::kMissingSchemeSeparator;
-+
-+  if (!SetScheme(pattern.substr(0, scheme_end_pos)))
-+    return ParseResult::kInvalidScheme;
-+
-+  bool standard_scheme = IsStandardScheme(scheme_);
-+  if (standard_scheme != has_standard_scheme_separator)
-+    return ParseResult::kWrongSchemeSeparator;
-+
-+  // Advance past the scheme separator.
-+  scheme_end_pos +=
-+      (standard_scheme ? strlen(url::kStandardSchemeSeparator) : 1);
-+  if (scheme_end_pos >= pattern.size())
-+    return ParseResult::kEmptyHost;
-+
-+  // Parse out the host and path.
-+  size_t host_start_pos = scheme_end_pos;
-+  size_t path_start_pos = 0;
-+
-+  if (!standard_scheme) {
-+    path_start_pos = host_start_pos;
-+  } else if (scheme_ == url::kFileScheme) {
-+    size_t host_end_pos = pattern.find(kPathSeparator, host_start_pos);
-+    if (host_end_pos == base::StringPiece::npos) {
-+      // Allow hostname omission.
-+      // e.g. file://* is interpreted as file:///*,
-+      // file://foo* is interpreted as file:///foo*.
-+      path_start_pos = host_start_pos - 1;
-+    } else {
-+      // Ignore hostname if scheme is file://.
-+      // e.g. file://localhost/foo is equal to file:///foo.
-+      path_start_pos = host_end_pos;
-+    }
-+  } else {
-+    size_t host_end_pos = pattern.find(kPathSeparator, host_start_pos);
-+
-+    // Host is required.
-+    if (host_start_pos == host_end_pos)
-+      return ParseResult::kEmptyHost;
-+
-+    if (host_end_pos == base::StringPiece::npos)
-+      return ParseResult::kEmptyPath;
-+
-+    base::StringPiece host_and_port =
-+        pattern.substr(host_start_pos, host_end_pos - host_start_pos);
-+
-+    size_t port_separator_pos = base::StringPiece::npos;
-+    if (host_and_port[0] != '[') {
-+      // Not IPv6 (either IPv4 or just a normal address).
-+      port_separator_pos = host_and_port.find(':');
-+    } else {  // IPv6.
-+      size_t host_end_pos = host_and_port.find(']');
-+      if (host_end_pos == base::StringPiece::npos)
-+        return ParseResult::kInvalidHost;
-+      if (host_end_pos == 1)
-+        return ParseResult::kEmptyHost;
-+
-+      if (host_end_pos < host_and_port.length() - 1) {
-+        // The host isn't the only component. Check for a port. This would
-+        // require a ':' to follow the closing ']' from the host.
-+        if (host_and_port[host_end_pos + 1] != ':')
-+          return ParseResult::kInvalidHost;
-+
-+        port_separator_pos = host_end_pos + 1;
-+      }
-+    }
-+
-+    if (port_separator_pos != base::StringPiece::npos &&
-+        !SetPort(host_and_port.substr(port_separator_pos + 1))) {
-+      return ParseResult::kInvalidPort;
-+    }
-+
-+    // Note: this substr() will be the entire string if the port position
-+    // wasn't found.
-+    base::StringPiece host_piece = host_and_port.substr(0, port_separator_pos);
-+
-+    if (host_piece.empty())
-+      return ParseResult::kEmptyHost;
-+
-+    if (host_piece == "*") {
-+      match_subdomains_ = true;
-+      host_piece = base::StringPiece();
-+    } else if (base::StartsWith(host_piece, "*.")) {
-+      if (host_piece.length() == 2) {
-+        // We don't allow just '*.' as a host.
-+        return ParseResult::kEmptyHost;
-+      }
-+      match_subdomains_ = true;
-+      host_piece = host_piece.substr(2);
-+    }
-+
-+    host_ = std::string(host_piece);
-+
-+    path_start_pos = host_end_pos;
-+  }
-+
-+  SetPath(pattern.substr(path_start_pos));
-+
-+  // No other '*' can occur in the host, though. This isn't necessary, but is
-+  // done as a convenience to developers who might otherwise be confused and
-+  // think '*' works as a glob in the host.
-+  if (host_.find('*') != std::string::npos)
-+    return ParseResult::kInvalidHostWildcard;
-+
-+  if (!host_.empty()) {
-+    // If |host_| is present (i.e., isn't a wildcard), we need to canonicalize
-+    // it.
-+    url::CanonHostInfo host_info;
-+    host_ = net::CanonicalizeHost(host_, &host_info);
-+    // net::CanonicalizeHost() returns an empty string on failure.
-+    if (host_.empty())
-+      return ParseResult::kInvalidHost;
-+  }
-+
-+  // Null characters are not allowed in hosts.
-+  if (host_.find('\0') != std::string::npos)
-+    return ParseResult::kInvalidHost;
-+
-+  return ParseResult::kSuccess;
-+}
-+
-+void URLPattern::SetValidSchemes(int valid_schemes) {
-+  // TODO(devlin): Should we check that valid_schemes agrees with |scheme_|
-+  // here? Otherwise, valid_schemes_ and schemes_ may stop agreeing with each
-+  // other (e.g., in the case of `*://*/*`, where the scheme should only be
-+  // http or https).
-+  spec_.clear();
-+  valid_schemes_ = valid_schemes;
-+}
-+
-+void URLPattern::SetHost(base::StringPiece host) {
-+  spec_.clear();
-+  host_.assign(host.data(), host.size());
-+}
-+
-+void URLPattern::SetMatchAllURLs(bool val) {
-+  spec_.clear();
-+  match_all_urls_ = val;
-+
-+  if (val) {
-+    match_subdomains_ = true;
-+    scheme_ = "*";
-+    host_.clear();
-+    SetPath("/*");
-+  }
-+}
-+
-+void URLPattern::SetMatchSubdomains(bool val) {
-+  spec_.clear();
-+  match_subdomains_ = val;
-+}
-+
-+bool URLPattern::SetScheme(base::StringPiece scheme) {
-+  spec_.clear();
-+  scheme_.assign(scheme.data(), scheme.size());
-+  if (scheme_ == "*") {
-+    valid_schemes_ &= (SCHEME_HTTP | SCHEME_HTTPS);
-+  } else if (!IsValidScheme(scheme_)) {
-+    return false;
-+  }
-+  return true;
-+}
-+
-+bool URLPattern::IsValidScheme(base::StringPiece scheme) const {
-+  if (valid_schemes_ == SCHEME_ALL)
-+    return true;
-+
-+  for (size_t i = 0; i < base::size(kValidSchemes); ++i) {
-+    if (scheme == kValidSchemes[i] && (valid_schemes_ & kValidSchemeMasks[i]))
-+      return true;
-+  }
-+
-+  return false;
-+}
-+
-+void URLPattern::SetPath(base::StringPiece path) {
-+  spec_.clear();
-+  path_.assign(path.data(), path.size());
-+  path_escaped_ = path_;
-+  base::ReplaceSubstringsAfterOffset(&path_escaped_, 0, "\\", "\\\\");
-+  base::ReplaceSubstringsAfterOffset(&path_escaped_, 0, "?", "\\?");
-+}
-+
-+bool URLPattern::SetPort(base::StringPiece port) {
-+  spec_.clear();
-+  if (IsValidPortForScheme(scheme_, port)) {
-+    port_.assign(port.data(), port.size());
-+    return true;
-+  }
-+  return false;
-+}
-+
-+bool URLPattern::MatchesURL(const GURL& test) const {
-+  // Invalid URLs can never match.
-+  if (!test.is_valid())
-+    return false;
-+
-+  const GURL* test_url = &test;
-+  bool has_inner_url = test.inner_url() != nullptr;
-+
-+  if (has_inner_url) {
-+    if (!test.SchemeIsFileSystem())
-+      return false;  // The only nested URLs we handle are filesystem URLs.
-+    test_url = test.inner_url();
-+  }
-+
-+  // Ensure the scheme matches first, since <all_urls> may not match this URL if
-+  // the scheme is excluded.
-+  if (!MatchesScheme(test_url->scheme_piece()))
-+    return false;
-+
-+  if (match_all_urls_)
-+    return true;
-+
-+  // Unless |match_all_urls_| is true, the grammar only permits matching
-+  // URLs with nonempty paths.
-+  if (!test.has_path())
-+    return false;
-+
-+  std::string path_for_request = test.PathForRequest();
-+  if (has_inner_url) {
-+    path_for_request = base::StringPrintf("%s%s", test_url->path_piece().data(),
-+                                          path_for_request.c_str());
-+  }
-+
-+  return MatchesSecurityOriginHelper(*test_url) &&
-+         MatchesPath(path_for_request);
-+}
-+
-+bool URLPattern::MatchesSecurityOrigin(const GURL& test) const {
-+  const GURL* test_url = &test;
-+  bool has_inner_url = test.inner_url() != NULL;
-+
-+  if (has_inner_url) {
-+    if (!test.SchemeIsFileSystem())
-+      return false;  // The only nested URLs we handle are filesystem URLs.
-+    test_url = test.inner_url();
-+  }
-+
-+  if (!MatchesScheme(test_url->scheme()))
-+    return false;
-+
-+  if (match_all_urls_)
-+    return true;
-+
-+  return MatchesSecurityOriginHelper(*test_url);
-+}
-+
-+bool URLPattern::MatchesScheme(base::StringPiece test) const {
-+  if (!IsValidScheme(test))
-+    return false;
-+
-+  return scheme_ == "*" || test == scheme_;
-+}
-+
-+bool URLPattern::MatchesHost(base::StringPiece host) const {
-+  // TODO(devlin): This is a bit sad. Parsing urls is expensive. However, it's
-+  // important that we do this conversion to a GURL in order to canonicalize the
-+  // host (the pattern's host_ already is canonicalized from Parse()). We can't
-+  // just do string comparison.
-+  return MatchesHost(
-+      GURL(base::StringPrintf("%s%s%s/", url::kHttpScheme,
-+                              url::kStandardSchemeSeparator, host.data())));
-+}
-+
-+bool URLPattern::MatchesHost(const GURL& test) const {
-+  base::StringPiece test_host(CanonicalizeHostForMatching(test.host_piece()));
-+  const base::StringPiece pattern_host(CanonicalizeHostForMatching(host_));
-+
-+  // If the hosts are exactly equal, we have a match.
-+  if (test_host == pattern_host)
-+    return true;
-+
-+  // If we're matching subdomains, and we have no host in the match pattern,
-+  // that means that we're matching all hosts, which means we have a match no
-+  // matter what the test host is.
-+  if (match_subdomains_ && pattern_host.empty())
-+    return true;
-+
-+  // Otherwise, we can only match if our match pattern matches subdomains.
-+  if (!match_subdomains_)
-+    return false;
-+
-+  // We don't do subdomain matching against IP addresses, so we can give up now
-+  // if the test host is an IP address.
-+  if (test.HostIsIPAddress())
-+    return false;
-+
-+  // Check if the test host is a subdomain of our host.
-+  if (test_host.length() <= (pattern_host.length() + 1))
-+    return false;
-+
-+  if (!base::EndsWith(test_host, pattern_host))
-+    return false;
-+
-+  return test_host[test_host.length() - pattern_host.length() - 1] == '.';
-+}
-+
-+bool URLPattern::MatchesEffectiveTld(
-+    net::registry_controlled_domains::PrivateRegistryFilter private_filter,
-+    net::registry_controlled_domains::UnknownRegistryFilter unknown_filter)
-+    const {
-+  // Check if it matches all urls or is a pattern like http://*/*.
-+  if (match_all_urls_ || (match_subdomains_ && host_.empty()))
-+    return true;
-+
-+  // If this doesn't even match subdomains, it can't possibly be a TLD wildcard.
-+  if (!match_subdomains_)
-+    return false;
-+
-+  // If there was more than just a TLD in the host (e.g., *.foobar.com), it
-+  // doesn't match all hosts in an effective TLD.
-+  if (net::registry_controlled_domains::HostHasRegistryControlledDomain(
-+          host_, unknown_filter, private_filter)) {
-+    return false;
-+  }
-+
-+  // At this point the host could either be just a TLD ("com") or some unknown
-+  // TLD-like string ("notatld"). To disambiguate between them construct a
-+  // fake URL, and check the registry.
-+  //
-+  // If we recognized this TLD, then this is a pattern like *.com, and it
-+  // matches an effective TLD.
-+  return net::registry_controlled_domains::HostHasRegistryControlledDomain(
-+      "notatld." + host_, unknown_filter, private_filter);
-+}
-+
-+bool URLPattern::MatchesSingleOrigin() const {
-+  // Strictly speaking, the port is part of the origin, but in URLPattern it
-+  // defaults to *. It's not very interesting anyway, so leave it out.
-+  return !MatchesEffectiveTld() && scheme_ != "*" && !match_subdomains_;
-+}
-+
-+bool URLPattern::MatchesPath(base::StringPiece test) const {
-+  // Make the behaviour of OverlapsWith consistent with MatchesURL, which is
-+  // need to match hosted apps on e.g. 'google.com' also run on 'google.com/'.
-+  // The below if is a no-copy way of doing (test + "/*" == path_escaped_).
-+  if (path_escaped_.length() == test.length() + 2 &&
-+      base::StartsWith(path_escaped_.c_str(), test) &&
-+      base::EndsWith(path_escaped_, "/*")) {
-+    return true;
-+  }
-+
-+  return base::MatchPattern(test, path_escaped_);
-+}
-+
-+const std::string& URLPattern::GetAsString() const {
-+  if (!spec_.empty())
-+    return spec_;
-+
-+  if (match_all_urls_) {
-+    spec_ = kAllUrlsPattern;
-+    return spec_;
-+  }
-+
-+  bool standard_scheme = IsStandardScheme(scheme_);
-+
-+  std::string spec = scheme_ +
-+      (standard_scheme ? url::kStandardSchemeSeparator : ":");
-+
-+  if (scheme_ != url::kFileScheme && standard_scheme) {
-+    if (match_subdomains_) {
-+      spec += "*";
-+      if (!host_.empty())
-+        spec += ".";
-+    }
-+
-+    if (!host_.empty())
-+      spec += host_;
-+
-+    if (port_ != "*") {
-+      spec += ":";
-+      spec += port_;
-+    }
-+  }
-+
-+  if (!path_.empty())
-+    spec += path_;
-+
-+  spec_ = std::move(spec);
-+  return spec_;
-+}
-+
-+bool URLPattern::OverlapsWith(const URLPattern& other) const {
-+  if (match_all_urls() || other.match_all_urls())
-+    return true;
-+  return (MatchesAnyScheme(other.GetExplicitSchemes()) ||
-+          other.MatchesAnyScheme(GetExplicitSchemes()))
-+      && (MatchesHost(other.host()) || other.MatchesHost(host()))
-+      && (MatchesPortPattern(other.port()) || other.MatchesPortPattern(port()))
-+      && (MatchesPath(StripTrailingWildcard(other.path())) ||
-+          other.MatchesPath(StripTrailingWildcard(path())));
-+}
-+
-+bool URLPattern::Contains(const URLPattern& other) const {
-+  // Important: it's not enough to just check match_all_urls(); we also need to
-+  // make sure that the schemes in this pattern are a superset of those in
-+  // |other|.
-+  if (match_all_urls() &&
-+      (valid_schemes_ & other.valid_schemes_) == other.valid_schemes_) {
-+    return true;
-+  }
-+
-+  return MatchesAllSchemes(other.GetExplicitSchemes()) &&
-+         MatchesHost(other.host()) &&
-+         (!other.match_subdomains_ || match_subdomains_) &&
-+         MatchesPortPattern(other.port()) &&
-+         MatchesPath(StripTrailingWildcard(other.path()));
-+}
-+
-+absl::optional<URLPattern> URLPattern::CreateIntersection(
-+    const URLPattern& other) const {
-+  // Easy case: Schemes don't overlap. Return nullopt.
-+  int intersection_schemes = URLPattern::SCHEME_NONE;
-+  if (valid_schemes_ == URLPattern::SCHEME_ALL)
-+    intersection_schemes = other.valid_schemes_;
-+  else if (other.valid_schemes_ == URLPattern::SCHEME_ALL)
-+    intersection_schemes = valid_schemes_;
-+  else
-+    intersection_schemes = valid_schemes_ & other.valid_schemes_;
-+
-+  if (intersection_schemes == URLPattern::SCHEME_NONE)
-+    return absl::nullopt;
-+
-+  {
-+    // In a few cases, we can (mostly) return a copy of one of the patterns.
-+    // This can happen when either:
-+    // - The URLPattern's are identical (possibly excluding valid_schemes_)
-+    // - One of the patterns has match_all_urls() equal to true.
-+    // NOTE(devlin): Theoretically, we could use Contains() instead of
-+    // match_all_urls() here. However, Contains() strips the trailing wildcard
-+    // from the path, which could yield the incorrect result.
-+    const URLPattern* copy_source = nullptr;
-+    if (*this == other || other.match_all_urls())
-+      copy_source = this;
-+    else if (match_all_urls())
-+      copy_source = &other;
-+
-+    if (copy_source) {
-+      // NOTE: equality checks don't take into account valid_schemes_, and
-+      // schemes can be different in the case of match_all_urls() as well, so
-+      // we can't always just return *copy_source.
-+      if (intersection_schemes == copy_source->valid_schemes_)
-+        return *copy_source;
-+      URLPattern result(intersection_schemes);
-+      ParseResult parse_result = result.Parse(copy_source->GetAsString());
-+      CHECK_EQ(ParseResult::kSuccess, parse_result);
-+      return result;
-+    }
-+  }
-+
-+  // No more easy cases. Go through component by component to find the patterns
-+  // that intersect.
-+
-+  // Note: Alias the function type (rather than using auto) because
-+  // MatchesHost() is overloaded.
-+  using match_function_type = bool (URLPattern::*)(base::StringPiece) const;
-+
-+  auto get_intersection = [this, &other](base::StringPiece own_str,
-+                                         base::StringPiece other_str,
-+                                         match_function_type match_function,
-+                                         base::StringPiece* out) {
-+    if ((this->*match_function)(other_str)) {
-+      *out = other_str;
-+      return true;
-+    }
-+    if ((other.*match_function)(own_str)) {
-+      *out = own_str;
-+      return true;
-+    }
-+    return false;
-+  };
-+
-+  base::StringPiece scheme;
-+  base::StringPiece host;
-+  base::StringPiece port;
-+  base::StringPiece path;
-+  // If any pieces fail to overlap, then there is no intersection.
-+  if (!get_intersection(scheme_, other.scheme_, &URLPattern::MatchesScheme,
-+                        &scheme) ||
-+      !get_intersection(host_, other.host_, &URLPattern::MatchesHost, &host) ||
-+      !get_intersection(port_, other.port_, &URLPattern::MatchesPortPattern,
-+                        &port) ||
-+      !get_intersection(path_, other.path_, &URLPattern::MatchesPath, &path)) {
-+    return absl::nullopt;
-+  }
-+
-+  // Only match subdomains if both patterns match subdomains.
-+  base::StringPiece subdomains;
-+  if (match_subdomains_ && other.match_subdomains_) {
-+    // The host may be empty (e.g., in the case of *://*/* - in that case, only
-+    // append '*' instead of '*.'.
-+    subdomains = host.empty() ? "*" : "*.";
-+  }
-+
-+  base::StringPiece scheme_separator =
-+      IsStandardScheme(scheme) ? url::kStandardSchemeSeparator : ":";
-+
-+  std::string pattern_str = base::StrCat(
-+      {scheme, scheme_separator, subdomains, host, ":", port, path});
-+
-+  URLPattern pattern(intersection_schemes);
-+  ParseResult result = pattern.Parse(pattern_str);
-+  // TODO(devlin): I don't think there's any way this should ever fail, but
-+  // use a CHECK() to flush any cases out. If nothing crops up, downgrade this
-+  // to a DCHECK in M72.
-+  CHECK_EQ(ParseResult::kSuccess, result);
-+
-+  return pattern;
-+}
-+
-+bool URLPattern::MatchesAnyScheme(
-+    const std::vector<std::string>& schemes) const {
-+  for (auto i = schemes.cbegin(); i != schemes.cend(); ++i) {
-+    if (MatchesScheme(*i))
-+      return true;
-+  }
-+
-+  return false;
-+}
-+
-+bool URLPattern::MatchesAllSchemes(
-+    const std::vector<std::string>& schemes) const {
-+  for (auto i = schemes.cbegin(); i != schemes.cend(); ++i) {
-+    if (!MatchesScheme(*i))
-+      return false;
-+  }
-+
-+  return true;
-+}
-+
-+bool URLPattern::MatchesSecurityOriginHelper(const GURL& test) const {
-+  // Ignore hostname if scheme is file://.
-+  if (scheme_ != url::kFileScheme && !MatchesHost(test))
-+    return false;
-+
-+  if (!MatchesPortPattern(base::NumberToString(test.EffectiveIntPort())))
-+    return false;
-+
-+  return true;
-+}
-+
-+bool URLPattern::MatchesPortPattern(base::StringPiece port) const {
-+  return port_ == "*" || port_ == port;
-+}
-+
-+std::vector<std::string> URLPattern::GetExplicitSchemes() const {
-+  std::vector<std::string> result;
-+
-+  if (scheme_ != "*" && !match_all_urls_ && IsValidScheme(scheme_)) {
-+    result.push_back(scheme_);
-+    return result;
-+  }
-+
-+  for (size_t i = 0; i < base::size(kValidSchemes); ++i) {
-+    if (MatchesScheme(kValidSchemes[i])) {
-+      result.push_back(kValidSchemes[i]);
-+    }
-+  }
-+
-+  return result;
-+}
-+
-+std::vector<URLPattern> URLPattern::ConvertToExplicitSchemes() const {
-+  std::vector<std::string> explicit_schemes = GetExplicitSchemes();
-+  std::vector<URLPattern> result;
-+
-+  for (std::vector<std::string>::const_iterator i = explicit_schemes.begin();
-+       i != explicit_schemes.end(); ++i) {
-+    URLPattern temp = *this;
-+    temp.SetScheme(*i);
-+    temp.SetMatchAllURLs(false);
-+    result.push_back(temp);
-+  }
-+
-+  return result;
-+}
-+
-+// static
-+const char* URLPattern::GetParseResultString(
-+    URLPattern::ParseResult parse_result) {
-+  return kParseResultMessages[static_cast<int>(parse_result)];
-+}
-diff --git a/components/user_scripts/common/url_pattern.h b/components/user_scripts/common/url_pattern.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/common/url_pattern.h
-@@ -0,0 +1,302 @@
-+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+#ifndef USERSCRIPTS_COMMON_URL_PATTERN_H_
-+#define USERSCRIPTS_COMMON_URL_PATTERN_H_
-+
-+#include <functional>
-+#include <iosfwd>
-+#include <string>
-+#include <vector>
-+
-+#include "base/strings/string_piece.h"
-+#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
-+
-+class GURL;
-+
-+// A pattern that can be used to match URLs. A URLPattern is a very restricted
-+// subset of URL syntax:
-+//
-+// <url-pattern> := <scheme>://<host><port><path> | '<all_urls>'
-+// <scheme> := '*' | 'http' | 'https' | 'file' | 'ftp' | 'chrome' |
-+//             'chrome-extension' | 'filesystem'
-+// <host> := '*' | <IPv4 address> | [<IPv6 address>] |
-+//           '*.' <anychar except '/' and '*'>+
-+// <port> := [':' ('*' | <port number between 0 and 65535>)]
-+// <path> := '/' <any chars>
-+//
-+// * Host is not used when the scheme is 'file'.
-+// * The path can have embedded '*' characters which act as glob wildcards.
-+// * '<all_urls>' is a special pattern that matches any valid URL that contains
-+//   a valid scheme (as specified by valid_schemes_).
-+// * The '*' scheme pattern excludes file URLs.
-+//
-+// Examples of valid patterns:
-+// - http://*/*
-+// - http://*/foo*
-+// - https://*.google.com/foo*bar
-+// - file://monkey*
-+// - http://127.0.0.1/*
-+// - http://[2607:f8b0:4005:805::200e]/*
-+//
-+// Examples of invalid patterns:
-+// - http://* -- path not specified
-+// - http://*foo/bar -- * not allowed as substring of host component
-+// - http://foo.*.bar/baz -- * must be first component
-+// - http:/bar -- scheme separator not found
-+// - foo://* -- invalid scheme
-+// - chrome:// -- we don't support chrome internal URLs
-+class URLPattern {
-+ public:
-+  // A collection of scheme bitmasks for use with valid_schemes.
-+  enum SchemeMasks {
-+    SCHEME_NONE = 0,
-+    SCHEME_HTTP = 1 << 0,
-+    SCHEME_HTTPS = 1 << 1,
-+    SCHEME_FILE = 1 << 2,
-+    SCHEME_FTP = 1 << 3,
-+    SCHEME_CHROMEUI = 1 << 4,
-+    SCHEME_EXTENSION = 1 << 5,
-+    SCHEME_FILESYSTEM = 1 << 6,
-+    SCHEME_WS = 1 << 7,
-+    SCHEME_WSS = 1 << 8,
-+    SCHEME_DATA = 1 << 9,
-+    SCHEME_URN = 1 << 10,
-+
-+    // IMPORTANT!
-+    // SCHEME_ALL will match every scheme, including chrome://, chrome-
-+    // extension://, about:, etc. Because this has lots of security
-+    // implications, third-party extensions should usually not be able to get
-+    // access to URL patterns initialized this way. If there is a reason
-+    // for violating this general rule, document why this it safe.
-+    SCHEME_ALL = -1,
-+  };
-+
-+  // Error codes returned from Parse().
-+  enum class ParseResult {
-+    kSuccess = 0,
-+    kMissingSchemeSeparator,
-+    kInvalidScheme,
-+    kWrongSchemeSeparator,
-+    kEmptyHost,
-+    kInvalidHostWildcard,
-+    kEmptyPath,
-+    kInvalidPort,
-+    kInvalidHost,
-+    kNumParseResults,
-+  };
-+
-+  // The <all_urls> string pattern.
-+  static const char kAllUrlsPattern[];
-+
-+  // Returns true if the given |scheme| is considered valid for extensions.
-+  static bool IsValidSchemeForExtensions(base::StringPiece scheme);
-+
-+  // Returns the mask for all schemes considered valid for extensions.
-+  static int GetValidSchemeMaskForExtensions();
-+
-+  explicit URLPattern(int valid_schemes);
-+
-+  // Convenience to construct a URLPattern from a string. If the string is not
-+  // known ahead of time, use Parse() instead, which returns success or failure.
-+  URLPattern(int valid_schemes, base::StringPiece pattern);
-+
-+  URLPattern();
-+  URLPattern(const URLPattern& other);
-+  URLPattern(URLPattern&& other);
-+  ~URLPattern();
-+
-+  URLPattern& operator=(const URLPattern& other);
-+  URLPattern& operator=(URLPattern&& other);
-+
-+  bool operator<(const URLPattern& other) const;
-+  bool operator>(const URLPattern& other) const;
-+  bool operator==(const URLPattern& other) const;
-+
-+  // Initializes this instance by parsing the provided string. Returns
-+  // URLPattern::ParseResult::kSuccess on success, or an error code otherwise.
-+  // On failure, this instance will have some intermediate values and is in an
-+  // invalid state.
-+  ParseResult Parse(base::StringPiece pattern_str);
-+
-+  // Gets the bitmask of valid schemes.
-+  int valid_schemes() const { return valid_schemes_; }
-+  void SetValidSchemes(int valid_schemes);
-+
-+  // Gets the host the pattern matches. This can be an empty string if the
-+  // pattern matches all hosts (the input was <scheme>://*/<whatever>).
-+  const std::string& host() const { return host_; }
-+  void SetHost(base::StringPiece host);
-+
-+  // Gets whether to match subdomains of host().
-+  bool match_subdomains() const { return match_subdomains_; }
-+  void SetMatchSubdomains(bool val);
-+
-+  // Gets the path the pattern matches with the leading slash. This can have
-+  // embedded asterisks which are interpreted using glob rules.
-+  const std::string& path() const { return path_; }
-+  void SetPath(base::StringPiece path);
-+
-+  // Returns true if this pattern matches all (valid) urls.
-+  bool match_all_urls() const { return match_all_urls_; }
-+  void SetMatchAllURLs(bool val);
-+
-+  // Sets the scheme for pattern matches. This can be a single '*' if the
-+  // pattern matches all valid schemes (as defined by the valid_schemes_
-+  // property). Returns false on failure (if the scheme is not valid).
-+  bool SetScheme(base::StringPiece scheme);
-+  // Note: You should use MatchesScheme() instead of this getter unless you
-+  // absolutely need the exact scheme. This is exposed for testing.
-+  const std::string& scheme() const { return scheme_; }
-+
-+  // Returns true if the specified scheme can be used in this URL pattern, and
-+  // false otherwise. Uses valid_schemes_ to determine validity.
-+  bool IsValidScheme(base::StringPiece scheme) const;
-+
-+  // Returns true if this instance matches the specified URL. Always returns
-+  // false for invalid URLs.
-+  bool MatchesURL(const GURL& test) const;
-+
-+  // Returns true if this instance matches the specified security origin.
-+  bool MatchesSecurityOrigin(const GURL& test) const;
-+
-+  // Returns true if |test| matches our scheme.
-+  // Note that if test is "filesystem", this may fail whereas MatchesURL
-+  // may succeed.  MatchesURL is smart enough to look at the inner_url instead
-+  // of the outer "filesystem:" part.
-+  bool MatchesScheme(base::StringPiece test) const;
-+
-+  // Returns true if |test| matches our host.
-+  bool MatchesHost(base::StringPiece test) const;
-+  bool MatchesHost(const GURL& test) const;
-+
-+  // Returns true if |test| matches our path.
-+  bool MatchesPath(base::StringPiece test) const;
-+
-+  // Returns true if the pattern matches all patterns in an (e)TLD. This
-+  // includes patterns like *://*.com/*, *://*.co.uk/*, etc. A pattern that
-+  // matches all domains (e.g., *://*/*) will return true.
-+  // |private_filter| specifies whether private registries (like appspot.com)
-+  // should be considered; if included, patterns like *://*.appspot.com/* will
-+  // return true. By default, we exclude private registries (so *.appspot.com
-+  // returns false).
-+  // Note: This is an expensive method, and should be used sparingly!
-+  // You should probably use URLPatternSet::ShouldWarnAllHosts(), which is
-+  // cached.
-+  bool MatchesEffectiveTld(
-+      net::registry_controlled_domains::PrivateRegistryFilter private_filter =
-+          net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES,
-+      net::registry_controlled_domains::UnknownRegistryFilter unknown_filter =
-+          net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES) const;
-+
-+  // Returns true if the pattern only matches a single origin. The pattern may
-+  // include a path.
-+  bool MatchesSingleOrigin() const;
-+
-+  // Sets the port. Returns false if the port is invalid.
-+  bool SetPort(base::StringPiece port);
-+  const std::string& port() const { return port_; }
-+
-+  // Returns a string representing this instance.
-+  const std::string& GetAsString() const;
-+
-+  // Determines whether there is a URL that would match this instance and
-+  // another instance. This method is symmetrical: Calling
-+  // other.OverlapsWith(this) would result in the same answer.
-+  bool OverlapsWith(const URLPattern& other) const;
-+
-+  // Returns true if this pattern matches all possible URLs that |other| can
-+  // match. For example, http://*.google.com encompasses http://www.google.com.
-+  bool Contains(const URLPattern& other) const;
-+
-+  // Creates a new URLPattern that represents the intersection of this
-+  // URLPattern with the |other|, or base::nullopt if no intersection exists.
-+  // For instance, given the patterns http://*.google.com/* and
-+  // *://maps.google.com/*, the intersection is http://maps.google.com/*.
-+  // NOTES:
-+  // - Though scheme intersections are supported, the serialization of
-+  //   URLPatternSet does not record them. Be sure that this is safe for your
-+  //   use cases.
-+  // - Path intersection is done on a best-effort basis. If one path clearly
-+  //   contains another, it will be handled correctly, but this method does not
-+  //   deal with cases like /*a* and /*b* (where technically the intersection
-+  //   is /*a*b*|/*b*a*); the intersection returned for that case will be empty.
-+  absl::optional<URLPattern> CreateIntersection(const URLPattern& other) const;
-+
-+  // Converts this URLPattern into an equivalent set of URLPatterns that don't
-+  // use a wildcard in the scheme component. If this URLPattern doesn't use a
-+  // wildcard scheme, then the returned set will contain one element that is
-+  // equivalent to this instance.
-+  std::vector<URLPattern> ConvertToExplicitSchemes() const;
-+
-+  static bool EffectiveHostCompare(const URLPattern& a, const URLPattern& b) {
-+    if (a.match_all_urls_ && b.match_all_urls_)
-+      return false;
-+    return a.host_.compare(b.host_) < 0;
-+  }
-+
-+  // Used for origin comparisons in a std::set.
-+  class EffectiveHostCompareFunctor {
-+   public:
-+    bool operator()(const URLPattern& a, const URLPattern& b) const {
-+      return EffectiveHostCompare(a, b);
-+    }
-+  };
-+
-+  // Get an error string for a ParseResult.
-+  static const char* GetParseResultString(URLPattern::ParseResult parse_result);
-+
-+ private:
-+  // Returns true if any of the |schemes| items matches our scheme.
-+  bool MatchesAnyScheme(const std::vector<std::string>& schemes) const;
-+
-+  // Returns true if all of the |schemes| items matches our scheme.
-+  bool MatchesAllSchemes(const std::vector<std::string>& schemes) const;
-+
-+  bool MatchesSecurityOriginHelper(const GURL& test) const;
-+
-+  // Returns true if our port matches the |port| pattern (it may be "*").
-+  bool MatchesPortPattern(base::StringPiece port) const;
-+
-+  // If the URLPattern contains a wildcard scheme, returns a list of
-+  // equivalent literal schemes, otherwise returns the current scheme.
-+  std::vector<std::string> GetExplicitSchemes() const;
-+
-+  // A bitmask containing the schemes which are considered valid for this
-+  // pattern. Parse() uses this to decide whether a pattern contains a valid
-+  // scheme.
-+  int valid_schemes_;
-+
-+  // True if this is a special-case "<all_urls>" pattern.
-+  bool match_all_urls_;
-+
-+  // The scheme for the pattern.
-+  std::string scheme_;
-+
-+  // The host without any leading "*" components.
-+  std::string host_;
-+
-+  // Whether we should match subdomains of the host. This is true if the first
-+  // component of the pattern's host was "*".
-+  bool match_subdomains_;
-+
-+  // The port.
-+  std::string port_;
-+
-+  // The path to match. This is everything after the host of the URL, or
-+  // everything after the scheme in the case of file:// URLs.
-+  std::string path_;
-+
-+  // The path with "?" and "\" characters escaped for use with the
-+  // MatchPattern() function.
-+  std::string path_escaped_;
-+
-+  // A string representing this URLPattern.
-+  mutable std::string spec_;
-+};
-+
-+std::ostream& operator<<(std::ostream& out, const URLPattern& url_pattern);
-+
-+typedef std::vector<URLPattern> URLPatternList;
-+
-+#endif  // USERSCRIPTS_COMMON_URL_PATTERN_H_
-diff --git a/components/user_scripts/common/url_pattern_set.cc b/components/user_scripts/common/url_pattern_set.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/common/url_pattern_set.cc
-@@ -0,0 +1,334 @@
-+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#include "url_pattern_set.h"
-+
-+#include <iterator>
-+#include <ostream>
-+
-+#include "base/containers/contains.h"
-+#include "base/logging.h"
-+#include "base/stl_util.h"
-+#include "base/values.h"
-+#include "error_utils.h"
-+#include "url_pattern.h"
-+#include "url/gurl.h"
-+#include "url/origin.h"
-+#include "url/url_constants.h"
-+#include "user_scripts_features.h"
-+
-+namespace user_scripts {
-+
-+namespace {
-+
-+const char kInvalidURLPatternError[] = "Invalid url pattern '*'";
-+
-+}  // namespace
-+
-+// static
-+URLPatternSet URLPatternSet::CreateDifference(const URLPatternSet& set1,
-+                                              const URLPatternSet& set2) {
-+  return URLPatternSet(base::STLSetDifference<std::set<URLPattern>>(
-+      set1.patterns_, set2.patterns_));
-+}
-+
-+// static
-+URLPatternSet URLPatternSet::CreateIntersection(
-+    const URLPatternSet& set1,
-+    const URLPatternSet& set2,
-+    IntersectionBehavior intersection_behavior) {
-+  // Note: leverage return value optimization; always return the same object.
-+  URLPatternSet result;
-+
-+  if (intersection_behavior == IntersectionBehavior::kStringComparison) {
-+    // String comparison just relies on STL set behavior, which looks at the
-+    // string representation.
-+    result = URLPatternSet(base::STLSetIntersection<std::set<URLPattern>>(
-+        set1.patterns_, set2.patterns_));
-+    return result;
-+  }
-+
-+  // Look for a semantic intersection.
-+
-+  // Step 1: Iterate over each set. Find any patterns that are completely
-+  // contained by the other (thus being necessarily present in any intersection)
-+  // and add them, collecting the others in a set of unique items.
-+  // Note: Use a collection of pointers for the uniques to avoid excessive
-+  // copies. Since these are owned by the URLPatternSet passed in, which is
-+  // const, this should be safe.
-+  std::vector<const URLPattern*> unique_set1;
-+  for (const URLPattern& pattern : set1) {
-+    if (set2.ContainsPattern(pattern))
-+      result.patterns_.insert(pattern);
-+    else
-+      unique_set1.push_back(&pattern);
-+  }
-+  std::vector<const URLPattern*> unique_set2;
-+  for (const URLPattern& pattern : set2) {
-+    if (set1.ContainsPattern(pattern))
-+      result.patterns_.insert(pattern);
-+    else
-+      unique_set2.push_back(&pattern);
-+  }
-+
-+  // If we're just looking for patterns contained by both, we're done.
-+  if (intersection_behavior == IntersectionBehavior::kPatternsContainedByBoth)
-+    return result;
-+
-+  DCHECK_EQ(IntersectionBehavior::kDetailed, intersection_behavior);
-+
-+  // Step 2: Iterate over all the unique patterns and find the intersections
-+  // they have with the other patterns.
-+  for (const auto* pattern : unique_set1) {
-+    for (const auto* pattern2 : unique_set2) {
-+      absl::optional<URLPattern> intersection =
-+          pattern->CreateIntersection(*pattern2);
-+      if (intersection)
-+        result.patterns_.insert(std::move(*intersection));
-+    }
-+  }
-+
-+  return result;
-+}
-+
-+// static
-+URLPatternSet URLPatternSet::CreateUnion(const URLPatternSet& set1,
-+                                         const URLPatternSet& set2) {
-+  return URLPatternSet(
-+      base::STLSetUnion<std::set<URLPattern>>(set1.patterns_, set2.patterns_));
-+}
-+
-+// static
-+URLPatternSet URLPatternSet::CreateUnion(
-+    const std::vector<URLPatternSet>& sets) {
-+  URLPatternSet result;
-+  if (sets.empty())
-+    return result;
-+
-+  // N-way union algorithm is basic O(nlog(n)) merge algorithm.
-+  //
-+  // Do the first merge step into a working set so that we don't mutate any of
-+  // the input.
-+  // TODO(devlin): Looks like this creates a bunch of copies; we can probably
-+  // clean that up.
-+  std::vector<URLPatternSet> working;
-+  for (size_t i = 0; i < sets.size(); i += 2) {
-+    if (i + 1 < sets.size())
-+      working.push_back(CreateUnion(sets[i], sets[i + 1]));
-+    else
-+      working.push_back(sets[i].Clone());
-+  }
-+
-+  for (size_t skip = 1; skip < working.size(); skip *= 2) {
-+    for (size_t i = 0; i < (working.size() - skip); i += skip) {
-+      URLPatternSet u = CreateUnion(working[i], working[i + skip]);
-+      working[i].patterns_.swap(u.patterns_);
-+    }
-+  }
-+
-+  result.patterns_.swap(working[0].patterns_);
-+  return result;
-+}
-+
-+URLPatternSet::URLPatternSet() = default;
-+
-+URLPatternSet::URLPatternSet(URLPatternSet&& rhs) = default;
-+
-+URLPatternSet::URLPatternSet(const std::set<URLPattern>& patterns)
-+    : patterns_(patterns) {}
-+
-+URLPatternSet::~URLPatternSet() = default;
-+
-+URLPatternSet& URLPatternSet::operator=(URLPatternSet&& rhs) = default;
-+
-+bool URLPatternSet::operator==(const URLPatternSet& other) const {
-+  return patterns_ == other.patterns_;
-+}
-+
-+std::ostream& operator<<(std::ostream& out,
-+                         const URLPatternSet& url_pattern_set) {
-+  out << "{ ";
-+
-+  auto iter = url_pattern_set.patterns().cbegin();
-+  if (!url_pattern_set.patterns().empty()) {
-+    out << *iter;
-+    ++iter;
-+  }
-+
-+  for (;iter != url_pattern_set.patterns().end(); ++iter)
-+    out << ", " << *iter;
-+
-+  if (!url_pattern_set.patterns().empty())
-+    out << " ";
-+
-+  out << "}";
-+  return out;
-+}
-+
-+URLPatternSet URLPatternSet::Clone() const {
-+  return URLPatternSet(patterns_);
-+}
-+
-+bool URLPatternSet::is_empty() const {
-+  return patterns_.empty();
-+}
-+
-+size_t URLPatternSet::size() const {
-+  return patterns_.size();
-+}
-+
-+bool URLPatternSet::AddPattern(const URLPattern& pattern) {
-+  return patterns_.insert(pattern).second;
-+}
-+
-+void URLPatternSet::AddPatterns(const URLPatternSet& set) {
-+  patterns_.insert(set.patterns().begin(),
-+                   set.patterns().end());
-+}
-+
-+void URLPatternSet::ClearPatterns() {
-+  patterns_.clear();
-+}
-+
-+bool URLPatternSet::AddOrigin(int valid_schemes, const GURL& origin) {
-+  if (origin.is_empty())
-+    return false;
-+  const url::Origin real_origin = url::Origin::Create(origin);
-+  DCHECK(real_origin.IsSameOriginWith(url::Origin::Create(origin.GetOrigin())));
-+  URLPattern origin_pattern(valid_schemes);
-+  // Origin adding could fail if |origin| does not match |valid_schemes|.
-+  if (origin_pattern.Parse(origin.spec()) !=
-+      URLPattern::ParseResult::kSuccess) {
-+    return false;
-+  }
-+  origin_pattern.SetPath("/*");
-+  return AddPattern(origin_pattern);
-+}
-+
-+bool URLPatternSet::Contains(const URLPatternSet& other) const {
-+  for (auto it = other.begin(); it != other.end(); ++it) {
-+    if (!ContainsPattern(*it))
-+      return false;
-+  }
-+
-+  return true;
-+}
-+
-+bool URLPatternSet::ContainsPattern(const URLPattern& pattern) const {
-+  for (auto it = begin(); it != end(); ++it) {
-+    if (it->Contains(pattern))
-+      return true;
-+  }
-+  return false;
-+}
-+
-+bool URLPatternSet::MatchesURL(const GURL& url) const {
-+  for (auto pattern = patterns_.cbegin(); pattern != patterns_.cend();
-+       ++pattern) {
-+    if (pattern->MatchesURL(url)) {
-+      if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+        LOG(INFO) << "UserScripts: URLPatternSet::MatchesURL true " << url.spec();
-+
-+      return true;
-+    }
-+  }
-+
-+  if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+    LOG(INFO) << "UserScripts: URLPatternSet::MatchesURL false " << url.spec();
-+
-+  return false;
-+}
-+
-+bool URLPatternSet::MatchesAllURLs() const {
-+  for (auto host = begin(); host != end(); ++host) {
-+    if (host->match_all_urls() ||
-+        (host->match_subdomains() && host->host().empty()))
-+      return true;
-+  }
-+  return false;
-+}
-+
-+bool URLPatternSet::MatchesSecurityOrigin(const GURL& origin) const {
-+  for (auto pattern = patterns_.begin(); pattern != patterns_.end();
-+       ++pattern) {
-+    if (pattern->MatchesSecurityOrigin(origin))
-+      return true;
-+  }
-+
-+  return false;
-+}
-+
-+bool URLPatternSet::OverlapsWith(const URLPatternSet& other) const {
-+  // Two extension extents overlap if there is any one URL that would match at
-+  // least one pattern in each of the extents.
-+  for (auto i = patterns_.cbegin(); i != patterns_.cend(); ++i) {
-+    for (auto j = other.patterns().cbegin(); j != other.patterns().cend();
-+         ++j) {
-+      if (i->OverlapsWith(*j))
-+        return true;
-+    }
-+  }
-+
-+  return false;
-+}
-+
-+std::unique_ptr<base::ListValue> URLPatternSet::ToValue() const {
-+  std::unique_ptr<base::ListValue> value(new base::ListValue);
-+  for (auto i = patterns_.cbegin(); i != patterns_.cend(); ++i) {
-+    base::Value pattern_str_value(i->GetAsString());
-+    if (!base::Contains(value->GetList(), pattern_str_value))
-+      value->Append(std::move(pattern_str_value));
-+  }
-+  return value;
-+}
-+
-+bool URLPatternSet::Populate(const std::vector<std::string>& patterns,
-+                             int valid_schemes,
-+                             bool allow_file_access,
-+                             std::string* error) {
-+  ClearPatterns();
-+  for (size_t i = 0; i < patterns.size(); ++i) {
-+    URLPattern pattern(valid_schemes);
-+    if (pattern.Parse(patterns[i]) != URLPattern::ParseResult::kSuccess) {
-+      if (error) {
-+        *error = ErrorUtils::FormatErrorMessage(kInvalidURLPatternError,
-+                                                patterns[i]);
-+      } else {
-+        LOG(ERROR) << "Invalid url pattern: " << patterns[i];
-+      }
-+      return false;
-+    }
-+    if (!allow_file_access && pattern.MatchesScheme(url::kFileScheme)) {
-+      pattern.SetValidSchemes(
-+          pattern.valid_schemes() & ~URLPattern::SCHEME_FILE);
-+    }
-+    AddPattern(pattern);
-+  }
-+  return true;
-+}
-+
-+std::unique_ptr<std::vector<std::string>> URLPatternSet::ToStringVector()
-+    const {
-+  std::unique_ptr<std::vector<std::string>> value(new std::vector<std::string>);
-+  for (auto i = patterns_.cbegin(); i != patterns_.cend(); ++i) {
-+    value->push_back(i->GetAsString());
-+  }
-+  return value;
-+}
-+
-+bool URLPatternSet::Populate(const base::ListValue& value,
-+                             int valid_schemes,
-+                             bool allow_file_access,
-+                             std::string* error) {
-+  std::vector<std::string> patterns;
-+  for (size_t i = 0; i < value.GetList().size(); ++i) {
-+    std::string item;
-+    if (!value.GetString(i, &item))
-+      return false;
-+    patterns.push_back(item);
-+  }
-+  return Populate(patterns, valid_schemes, allow_file_access, error);
-+}
-+
-+}  // namespace extensions
-diff --git a/components/user_scripts/common/url_pattern_set.h b/components/user_scripts/common/url_pattern_set.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/common/url_pattern_set.h
-@@ -0,0 +1,161 @@
-+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#ifndef USERSCRIPTS_COMMON_URL_PATTERN_SET_H_
-+#define USERSCRIPTS_COMMON_URL_PATTERN_SET_H_
-+
-+#include <stddef.h>
-+
-+#include <iosfwd>
-+#include <memory>
-+#include <set>
-+
-+#include "base/macros.h"
-+#include "url_pattern.h"
-+
-+class GURL;
-+
-+namespace base {
-+class ListValue;
-+class Value;
-+}
-+
-+namespace user_scripts {
-+
-+// Represents the set of URLs an extension uses for web content.
-+class URLPatternSet {
-+ public:
-+  typedef std::set<URLPattern>::const_iterator const_iterator;
-+  typedef std::set<URLPattern>::iterator iterator;
-+
-+  // Returns |set1| - |set2|.
-+  static URLPatternSet CreateDifference(const URLPatternSet& set1,
-+                                        const URLPatternSet& set2);
-+
-+  enum class IntersectionBehavior {
-+    // For the following descriptions, consider the two URLPatternSets:
-+    // Set 1: {"https://example.com/*", "https://*.google.com/*", "http://*/*"}
-+    // Set 2: {"https://example.com/*", "https://google.com/maps",
-+    //         "*://chromium.org/*"}
-+
-+    // Only includes patterns that are exactly in both sets. The intersection of
-+    // the two sets above is {"https://example.com/*"}, since that is the only
-+    // pattern that appears exactly in each.
-+    kStringComparison,
-+
-+    // Includes patterns that are effectively contained by both sets. The
-+    // intersection of the two sets above is
-+    // {
-+    //   "https://example.com/*" (contained exactly by each set)
-+    //   "https://google.com/maps" (contained exactly by set 2 and a strict
-+    //                              subset of https://*.google.com/* in set 1)
-+    // }
-+    kPatternsContainedByBoth,
-+
-+    // Includes patterns that are contained by both sets and creates new
-+    // patterns to represent the intersection of any others. The intersection of
-+    // the two sets above is
-+    // {
-+    //   "https://example.com/*" (contained exactly by each set)
-+    //   "https://google.com/maps" (contained exactly by set 2 and a strict
-+    //                              subset of https://*.google.com/* in set 1)
-+    //   "http://chromium.org/*" (the overlap between "http://*/*" in set 1 and
-+    //                            *://chromium.org/*" in set 2).
-+    // }
-+    // Note that this is the most computationally expensive - potentially
-+    // O(n^2) - since it can require comparing each pattern in one set to every
-+    // pattern in the other set.
-+    kDetailed,
-+  };
-+
-+  // Returns the intersection of |set1| and |set2| according to
-+  // |intersection_behavior|.
-+  static URLPatternSet CreateIntersection(
-+      const URLPatternSet& set1,
-+      const URLPatternSet& set2,
-+      IntersectionBehavior intersection_behavior);
-+
-+  // Returns the union of |set1| and |set2|.
-+  static URLPatternSet CreateUnion(const URLPatternSet& set1,
-+                                   const URLPatternSet& set2);
-+
-+  // Returns the union of all sets in |sets|.
-+  static URLPatternSet CreateUnion(const std::vector<URLPatternSet>& sets);
-+
-+  URLPatternSet();
-+  URLPatternSet(URLPatternSet&& rhs);
-+  explicit URLPatternSet(const std::set<URLPattern>& patterns);
-+  ~URLPatternSet();
-+
-+  URLPatternSet& operator=(URLPatternSet&& rhs);
-+  bool operator==(const URLPatternSet& rhs) const;
-+
-+  bool is_empty() const;
-+  size_t size() const;
-+  const std::set<URLPattern>& patterns() const { return patterns_; }
-+  const_iterator begin() const { return patterns_.begin(); }
-+  const_iterator end() const { return patterns_.end(); }
-+  iterator erase(iterator iter) { return patterns_.erase(iter); }
-+
-+  // Returns a copy of this URLPatternSet; not instrumented as a copy
-+  // constructor to avoid accidental/unnecessary copies.
-+  URLPatternSet Clone() const;
-+
-+  // Adds a pattern to the set. Returns true if a new pattern was inserted,
-+  // false if the pattern was already in the set.
-+  bool AddPattern(const URLPattern& pattern);
-+
-+  // Adds all patterns from |set| into this.
-+  void AddPatterns(const URLPatternSet& set);
-+
-+  void ClearPatterns();
-+
-+  // Adds a pattern based on |origin| to the set.
-+  bool AddOrigin(int valid_schemes, const GURL& origin);
-+
-+  // Returns true if every URL that matches |set| is matched by this. In other
-+  // words, if every pattern in |set| is encompassed by a pattern in this.
-+  bool Contains(const URLPatternSet& set) const;
-+
-+  // Returns true if any pattern in this set encompasses |pattern|.
-+  bool ContainsPattern(const URLPattern& pattern) const;
-+
-+  // Test if the extent contains a URL.
-+  bool MatchesURL(const GURL& url) const;
-+
-+  // Test if the extent matches all URLs (for example, <all_urls>).
-+  bool MatchesAllURLs() const;
-+
-+  bool MatchesSecurityOrigin(const GURL& origin) const;
-+
-+  // Returns true if there is a single URL that would be in two extents.
-+  bool OverlapsWith(const URLPatternSet& other) const;
-+
-+  // Converts to and from Value for serialization to preferences.
-+  std::unique_ptr<base::ListValue> ToValue() const;
-+  bool Populate(const base::ListValue& value,
-+                int valid_schemes,
-+                bool allow_file_access,
-+                std::string* error);
-+
-+  // Converts to and from a vector of strings.
-+  std::unique_ptr<std::vector<std::string>> ToStringVector() const;
-+  bool Populate(const std::vector<std::string>& patterns,
-+                int valid_schemes,
-+                bool allow_file_access,
-+                std::string* error);
-+
-+ private:
-+  // The list of URL patterns that comprise the extent.
-+  std::set<URLPattern> patterns_;
-+
-+  DISALLOW_COPY_AND_ASSIGN(URLPatternSet);
-+};
-+
-+std::ostream& operator<<(std::ostream& out,
-+                         const URLPatternSet& url_pattern_set);
-+
-+}  // namespace extensions
-+
-+#endif  // USERSCRIPTS_COMMON_URL_PATTERN_SET_H_
-diff --git a/components/user_scripts/common/user_script.cc b/components/user_scripts/common/user_script.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/common/user_script.cc
-@@ -0,0 +1,317 @@
-+// Copyright 2013 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#include "user_script.h"
-+
-+#include <stddef.h>
-+#include <stdint.h>
-+
-+#include <memory>
-+#include <utility>
-+
-+#include "base/atomic_sequence_num.h"
-+#include "base/command_line.h"
-+#include "base/pickle.h"
-+#include "base/strings/pattern.h"
-+#include "base/strings/string_util.h"
-+#include "user_scripts_features.h"
-+
-+namespace {
-+
-+// This cannot be a plain int or int64_t because we need to generate unique IDs
-+// from multiple threads.
-+base::AtomicSequenceNumber g_user_script_id_generator;
-+
-+bool UrlMatchesGlobs(const std::vector<std::string>* globs,
-+                     const GURL& url) {
-+  for (auto glob = globs->cbegin(); glob != globs->cend(); ++glob) {
-+    if (base::MatchPattern(url.spec(), *glob))
-+      return true;
-+  }
-+
-+  return false;
-+}
-+
-+}  // namespace
-+
-+namespace user_scripts {
-+
-+// The bitmask for valid user script injectable schemes used by URLPattern.
-+enum {
-+  kValidUserScriptSchemes = //URLPattern::SCHEME_CHROMEUI |
-+                            URLPattern::SCHEME_HTTP |
-+                            URLPattern::SCHEME_HTTPS
-+                            //| URLPattern::SCHEME_FILE |
-+                            //URLPattern::SCHEME_FTP
-+};
-+
-+// static
-+const char UserScript::kFileExtension[] = ".user.js";
-+
-+// static
-+int UserScript::GenerateUserScriptID() {
-+  return g_user_script_id_generator.GetNext();
-+}
-+
-+bool UserScript::IsURLUserScript(const GURL& url,
-+                                 const std::string& mime_type) {
-+  return base::EndsWith(url.ExtractFileName(), kFileExtension,
-+                        base::CompareCase::INSENSITIVE_ASCII) &&
-+         mime_type != "text/html";
-+}
-+
-+// static
-+int UserScript::ValidUserScriptSchemes(bool canExecuteScriptEverywhere) {
-+  if (canExecuteScriptEverywhere)
-+    return URLPattern::SCHEME_ALL;
-+  int valid_schemes = kValidUserScriptSchemes;
-+  // if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
-+  //         switches::kExtensionsOnChromeURLs)) {
-+  //   valid_schemes &= ~URLPattern::SCHEME_CHROMEUI;
-+  // }
-+  return valid_schemes;
-+}
-+
-+UserScript::File::File(const base::FilePath& extension_root,
-+                       const base::FilePath& relative_path,
-+                       const GURL& url)
-+    : extension_root_(extension_root),
-+      relative_path_(relative_path),
-+      url_(url) {
-+}
-+
-+UserScript::File::File() {}
-+
-+UserScript::File::File(const File& other)
-+    : extension_root_(other.extension_root_),
-+      relative_path_(other.relative_path_),
-+      url_(other.url_),
-+      external_content_(other.external_content_),
-+      content_(other.content_),
-+      key_(other.key_) {}
-+
-+UserScript::File::~File() {}
-+
-+UserScript::UserScript() = default;
-+UserScript::~UserScript() = default;
-+
-+void UserScript::add_url_pattern(const URLPattern& pattern) {
-+  url_set_.AddPattern(pattern);
-+}
-+
-+void UserScript::add_exclude_url_pattern(const URLPattern& pattern) {
-+  exclude_url_set_.AddPattern(pattern);
-+}
-+
-+bool UserScript::MatchesURL(const GURL& url) const {
-+  if (!url_set_.is_empty()) {
-+    if (!url_set_.MatchesURL(url)) {
-+      if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+        LOG(INFO) << "UserScripts: No Match for url_set";
-+      return false;
-+    }
-+  }
-+
-+  if (!exclude_url_set_.is_empty()) {
-+    if (exclude_url_set_.MatchesURL(url)) {
-+      if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+        LOG(INFO) << "UserScripts: No Match for exclude_url_set";
-+      return false;
-+    }
-+  }
-+
-+  if (!globs_.empty()) {
-+    if (!UrlMatchesGlobs(&globs_, url)) {
-+      if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+        LOG(INFO) << "UserScripts: No Match for globs";
-+      return false;
-+    }
-+  }
-+
-+  if (!exclude_globs_.empty()) {
-+    if (UrlMatchesGlobs(&exclude_globs_, url)) {
-+      if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+        LOG(INFO) << "UserScripts: No Match for exclude_globs";
-+      return false;
-+    }
-+  }
-+
-+  return true;
-+}
-+
-+bool UserScript::MatchesDocument(const GURL& effective_document_url,
-+                                 bool is_subframe) const {
-+  if (is_subframe && !match_all_frames())
-+    return false;
-+
-+  return MatchesURL(effective_document_url);
-+}
-+
-+void UserScript::File::Pickle(base::Pickle* pickle) const {
-+  pickle->WriteString(url_.spec());
-+  // Do not write path. It's not needed in the renderer.
-+  // Do not write content. It will be serialized by other means.
-+}
-+
-+void UserScript::File::Unpickle(const base::Pickle& pickle,
-+                                base::PickleIterator* iter) {
-+  // Read the url from the pickle.
-+  std::string url;
-+  CHECK(iter->ReadString(&url));
-+  set_url(GURL(url));
-+}
-+
-+void UserScript::Pickle(base::Pickle* pickle) const {
-+  // Write the simple types to the pickle.
-+  pickle->WriteInt(run_location());
-+  pickle->WriteInt(user_script_id_);
-+  pickle->WriteBool(emulate_greasemonkey());
-+  pickle->WriteBool(match_all_frames());
-+  pickle->WriteInt(static_cast<int>(match_origin_as_fallback()));
-+  pickle->WriteBool(is_incognito_enabled());
-+
-+  PickleHostID(pickle, host_id_);
-+  pickle->WriteInt(consumer_instance_type());
-+  PickleGlobs(pickle, globs_);
-+  PickleGlobs(pickle, exclude_globs_);
-+  PickleURLPatternSet(pickle, url_set_);
-+  PickleURLPatternSet(pickle, exclude_url_set_);
-+  PickleScripts(pickle, js_scripts_);
-+  PickleScripts(pickle, css_scripts_);
-+}
-+
-+void UserScript::PickleGlobs(base::Pickle* pickle,
-+                             const std::vector<std::string>& globs) const {
-+  pickle->WriteUInt32(globs.size());
-+  for (auto glob = globs.cbegin(); glob != globs.cend(); ++glob) {
-+    pickle->WriteString(*glob);
-+  }
-+}
-+
-+void UserScript::PickleHostID(base::Pickle* pickle,
-+                              const HostID& host_id) const {
-+  pickle->WriteInt(host_id.type());
-+  pickle->WriteString(host_id.id());
-+}
-+
-+void UserScript::PickleURLPatternSet(base::Pickle* pickle,
-+                                     const URLPatternSet& pattern_list) const {
-+  pickle->WriteUInt32(pattern_list.patterns().size());
-+  for (auto pattern = pattern_list.begin(); pattern != pattern_list.end();
-+       ++pattern) {
-+    pickle->WriteInt(pattern->valid_schemes());
-+    pickle->WriteString(pattern->GetAsString());
-+  }
-+}
-+
-+void UserScript::PickleScripts(base::Pickle* pickle,
-+                               const FileList& scripts) const {
-+  pickle->WriteUInt32(scripts.size());
-+  for (const std::unique_ptr<File>& file : scripts)
-+    file->Pickle(pickle);
-+}
-+
-+void UserScript::Unpickle(const base::Pickle& pickle,
-+                          base::PickleIterator* iter) {
-+  // Read the run location.
-+  int run_location = 0;
-+  CHECK(iter->ReadInt(&run_location));
-+  CHECK(run_location >= 0 && run_location < RUN_LOCATION_LAST);
-+  run_location_ = static_cast<RunLocation>(run_location);
-+
-+  CHECK(iter->ReadInt(&user_script_id_));
-+  CHECK(iter->ReadBool(&emulate_greasemonkey_));
-+  CHECK(iter->ReadBool(&match_all_frames_));
-+  int match_origin_as_fallback_int = 0;
-+  CHECK(iter->ReadInt(&match_origin_as_fallback_int));
-+  match_origin_as_fallback_ =
-+      static_cast<MatchOriginAsFallbackBehavior>(match_origin_as_fallback_int);
-+  CHECK(iter->ReadBool(&incognito_enabled_));
-+
-+  UnpickleHostID(pickle, iter, &host_id_);
-+
-+  int consumer_instance_type = 0;
-+  CHECK(iter->ReadInt(&consumer_instance_type));
-+  consumer_instance_type_ =
-+      static_cast<ConsumerInstanceType>(consumer_instance_type);
-+
-+  UnpickleGlobs(pickle, iter, &globs_);
-+  UnpickleGlobs(pickle, iter, &exclude_globs_);
-+  UnpickleURLPatternSet(pickle, iter, &url_set_);
-+  UnpickleURLPatternSet(pickle, iter, &exclude_url_set_);
-+  UnpickleScripts(pickle, iter, &js_scripts_);
-+  UnpickleScripts(pickle, iter, &css_scripts_);
-+}
-+
-+void UserScript::UnpickleGlobs(const base::Pickle& pickle,
-+                               base::PickleIterator* iter,
-+                               std::vector<std::string>* globs) {
-+  uint32_t num_globs = 0;
-+  CHECK(iter->ReadUInt32(&num_globs));
-+  globs->clear();
-+  for (uint32_t i = 0; i < num_globs; ++i) {
-+    std::string glob;
-+    CHECK(iter->ReadString(&glob));
-+    globs->push_back(glob);
-+  }
-+}
-+
-+void UserScript::UnpickleHostID(const base::Pickle& pickle,
-+                                base::PickleIterator* iter,
-+                                HostID* host_id) {
-+  int type = 0;
-+  std::string id;
-+  CHECK(iter->ReadInt(&type));
-+  CHECK(iter->ReadString(&id));
-+  *host_id = HostID(static_cast<HostID::HostType>(type), id);
-+}
-+
-+void UserScript::UnpickleURLPatternSet(const base::Pickle& pickle,
-+                                       base::PickleIterator* iter,
-+                                       URLPatternSet* pattern_list) {
-+  uint32_t num_patterns = 0;
-+  CHECK(iter->ReadUInt32(&num_patterns));
-+
-+  pattern_list->ClearPatterns();
-+  for (uint32_t i = 0; i < num_patterns; ++i) {
-+    int valid_schemes;
-+    CHECK(iter->ReadInt(&valid_schemes));
-+
-+    std::string pattern_str;
-+    CHECK(iter->ReadString(&pattern_str));
-+
-+    URLPattern pattern(kValidUserScriptSchemes);
-+    URLPattern::ParseResult result = pattern.Parse(pattern_str);
-+    CHECK(URLPattern::ParseResult::kSuccess == result)
-+        << URLPattern::GetParseResultString(result) << " "
-+        << pattern_str.c_str();
-+
-+    pattern.SetValidSchemes(valid_schemes);
-+    pattern_list->AddPattern(pattern);
-+  }
-+}
-+
-+void UserScript::UnpickleScripts(const base::Pickle& pickle,
-+                                 base::PickleIterator* iter,
-+                                 FileList* scripts) {
-+  uint32_t num_files = 0;
-+  CHECK(iter->ReadUInt32(&num_files));
-+  scripts->clear();
-+  for (uint32_t i = 0; i < num_files; ++i) {
-+    std::unique_ptr<File> file(new File());
-+    file->Unpickle(pickle, iter);
-+    scripts->push_back(std::move(file));
-+  }
-+}
-+
-+UserScriptIDPair::UserScriptIDPair(int id, const HostID& host_id)
-+    : id(id), host_id(host_id) {}
-+
-+UserScriptIDPair::UserScriptIDPair(int id) : id(id), host_id(HostID()) {}
-+
-+bool operator<(const UserScriptIDPair& a, const UserScriptIDPair& b) {
-+  return a.id < b.id;
-+}
-+
-+}  // namespace extensions
-diff --git a/components/user_scripts/common/user_script.h b/components/user_scripts/common/user_script.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/common/user_script.h
-@@ -0,0 +1,403 @@
-+// Copyright 2013 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#ifndef USERSCRIPTS_COMMON_USER_SCRIPT_H_
-+#define USERSCRIPTS_COMMON_USER_SCRIPT_H_
-+
-+#include <memory>
-+#include <string>
-+#include <vector>
-+
-+#include "base/files/file_path.h"
-+#include "base/strings/string_piece.h"
-+#include "script_constants.h"
-+#include "host_id.h"
-+#include "url_pattern.h"
-+#include "url_pattern_set.h"
-+#include "url/gurl.h"
-+
-+namespace base {
-+class Pickle;
-+class PickleIterator;
-+}
-+
-+namespace user_scripts {
-+
-+// Represents a user script, either a standalone one, or one that is part of an
-+// extension.
-+class UserScript {
-+ public:
-+  // The file extension for standalone user scripts.
-+  static const char kFileExtension[];
-+
-+  static int GenerateUserScriptID();
-+
-+  // Check if a URL should be treated as a user script and converted to an
-+  // extension.
-+  static bool IsURLUserScript(const GURL& url, const std::string& mime_type);
-+
-+  // Get the valid user script schemes for the current process. If
-+  // canExecuteScriptEverywhere is true, this will return ALL_SCHEMES.
-+  static int ValidUserScriptSchemes(bool canExecuteScriptEverywhere = false);
-+
-+  // TODO(rdevlin.cronin) This and RunLocation don't really belong here, since
-+  // they are used for more than UserScripts (e.g., tabs.executeScript()).
-+  // The type of injected script.
-+  enum InjectionType {
-+    // A content script specified in the extension's manifest.
-+    CONTENT_SCRIPT,
-+    // A script injected via, e.g. tabs.executeScript().
-+    //PROGRAMMATIC_SCRIPT
-+  };
-+  // The last type of injected script; used for enum verification in IPC.
-+  // Update this if you add more injected script types!
-+  static const InjectionType INJECTION_TYPE_LAST = CONTENT_SCRIPT/*PROGRAMMATIC_SCRIPT*/;
-+
-+  // Locations that user scripts can be run inside the document.
-+  // The three run locations must strictly follow each other in both load order
-+  // (i.e., start *always* comes before end) and numerically, as we use
-+  // arithmetic checking (e.g., curr == last + 1). So, no bitmasks here!!
-+  enum RunLocation {
-+    UNDEFINED,
-+    DOCUMENT_START,  // After the documentElement is created, but before
-+                     // anything else happens.
-+    DOCUMENT_END,  // After the entire document is parsed. Same as
-+                   // DOMContentLoaded.
-+    DOCUMENT_IDLE,  // Sometime after DOMContentLoaded, as soon as the document
-+                    // is "idle". Currently this uses the simple heuristic of:
-+                    // min(DOM_CONTENT_LOADED + TIMEOUT, ONLOAD), but no
-+                    // particular injection point is guaranteed.
-+    RUN_DEFERRED,  // The user script's injection was deferred for permissions
-+                   // reasons, and was executed at a later time.
-+    BROWSER_DRIVEN,  // The user script will be injected when triggered by an
-+                     // IPC in the browser process.
-+    RUN_LOCATION_LAST  // Leave this as the last item.
-+  };
-+
-+  // Holds script file info.
-+  class File {
-+   public:
-+    File(const base::FilePath& extension_root,
-+         const base::FilePath& relative_path,
-+         const GURL& url);
-+    File();
-+    File(const File& other);
-+    ~File();
-+
-+    const base::FilePath& extension_root() const { return extension_root_; }
-+    const base::FilePath& relative_path() const { return relative_path_; }
-+
-+    const GURL& url() const { return url_; }
-+    void set_url(const GURL& url) { url_ = url; }
-+
-+    // If external_content_ is set returns it as content otherwise it returns
-+    // content_
-+    const base::StringPiece GetContent() const {
-+      if (external_content_.data())
-+        return external_content_;
-+      else
-+        return content_;
-+    }
-+    void set_external_content(const base::StringPiece& content) {
-+      external_content_ = content;
-+    }
-+    void set_content(const base::StringPiece& content) {
-+      content_.assign(content.begin(), content.end());
-+    }
-+
-+    const std::string& key() const { return key_; }
-+    void set_key(const std::string& key) {
-+      key_ = key;
-+    }
-+
-+    // Serialization support. The content and FilePath members will not be
-+    // serialized!
-+    void Pickle(base::Pickle* pickle) const;
-+    void Unpickle(const base::Pickle& pickle, base::PickleIterator* iter);
-+
-+   private:
-+    // Where the script file lives on the disk. We keep the path split so that
-+    // it can be localized at will.
-+    base::FilePath extension_root_;
-+    base::FilePath relative_path_;
-+
-+    // The url to this script file.
-+    GURL url_;
-+
-+    // The script content. It can be set to either loaded_content_ or
-+    // externally allocated string.
-+    base::StringPiece external_content_;
-+
-+    // Set when the content is loaded by LoadContent
-+    std::string content_;
-+
-+    std::string key_;
-+  };
-+
-+  using FileList = std::vector<std::unique_ptr<File>>;
-+
-+  // Type of a API consumer instance that user scripts will be injected on.
-+  enum ConsumerInstanceType { TAB, WEBVIEW };
-+
-+  // Constructor. Default the run location to document end, which is like
-+  // Greasemonkey and probably more useful for typical scripts.
-+  UserScript();
-+  ~UserScript();
-+
-+  // Performs a copy of all fields except file contents.
-+  // static std::unique_ptr<UserScript> CopyMetadataFrom(const UserScript& other);
-+
-+  const std::string& name_space() const { return name_space_; }
-+  void set_name_space(const std::string& name_space) {
-+    name_space_ = name_space;
-+  }
-+
-+  const std::string& name() const { return name_; }
-+  void set_name(const std::string& name) { name_ = name; }
-+
-+  const std::string& version() const { return version_; }
-+  void set_version(const std::string& version) {
-+    version_ = version;
-+  }
-+
-+  const std::string& key() const { return key_; }
-+  void set_key(const std::string& key) {
-+    key_ = key;
-+  }
-+
-+  const std::string& file_path() const { return file_path_; }
-+  void set_file_path(const std::string& file_path) {
-+    file_path_ = file_path;
-+  }
-+
-+  const std::string& url_source() const { return url_source_; }
-+  void set_url_source(const std::string& url_source) {
-+    url_source_ = url_source;
-+  }
-+
-+  const std::string& description() const { return description_; }
-+  void set_description(const std::string& description) {
-+    description_ = description;
-+  }
-+
-+  const std::string& parser_error() const { return parser_error_; }
-+  void set_parser_error(const std::string& parser_error) {
-+    parser_error_ = parser_error;
-+  }
-+
-+  bool force_disabled() const { return force_disabled_; }
-+  void set_force_disabled() {
-+    force_disabled_ = true;
-+  }
-+
-+  // The place in the document to run the script.
-+  RunLocation run_location() const { return run_location_; }
-+  void set_run_location(RunLocation location) { run_location_ = location; }
-+
-+  // Whether to emulate greasemonkey when running this script.
-+  bool emulate_greasemonkey() const { return emulate_greasemonkey_; }
-+  void set_emulate_greasemonkey(bool val) { emulate_greasemonkey_ = val; }
-+
-+  // Whether to match all frames, or only the top one.
-+  bool match_all_frames() const { return match_all_frames_; }
-+  void set_match_all_frames(bool val) { match_all_frames_ = val; }
-+
-+  // Whether to match the origin as a fallback if the URL cannot be used
-+  // directly.
-+  MatchOriginAsFallbackBehavior match_origin_as_fallback() const {
-+    return match_origin_as_fallback_;
-+  }
-+  void set_match_origin_as_fallback(MatchOriginAsFallbackBehavior val) {
-+    match_origin_as_fallback_ = val;
-+  }
-+
-+  // The globs, if any, that determine which pages this script runs against.
-+  // These are only used with "standalone" Greasemonkey-like user scripts.
-+  const std::vector<std::string>& globs() const { return globs_; }
-+  void add_glob(const std::string& glob) { globs_.push_back(glob); }
-+  void clear_globs() { globs_.clear(); }
-+  const std::vector<std::string>& exclude_globs() const {
-+    return exclude_globs_;
-+  }
-+  void add_exclude_glob(const std::string& glob) {
-+    exclude_globs_.push_back(glob);
-+  }
-+  void clear_exclude_globs() { exclude_globs_.clear(); }
-+
-+  // The URLPatterns, if any, that determine which pages this script runs
-+  // against.
-+  const URLPatternSet& url_patterns() const { return url_set_; }
-+  void add_url_pattern(const URLPattern& pattern);
-+  const URLPatternSet& exclude_url_patterns() const {
-+    return exclude_url_set_;
-+  }
-+  void add_exclude_url_pattern(const URLPattern& pattern);
-+
-+  // List of js scripts for this user script
-+  FileList& js_scripts() { return js_scripts_; }
-+  const FileList& js_scripts() const { return js_scripts_; }
-+
-+  // List of css scripts for this user script
-+  FileList& css_scripts() { return css_scripts_; }
-+  const FileList& css_scripts() const { return css_scripts_; }
-+
-+  const std::string& extension_id() const { return host_id_.id(); }
-+
-+  const HostID& host_id() const { return host_id_; }
-+  void set_host_id(const HostID& host_id) { host_id_ = host_id; }
-+
-+  const ConsumerInstanceType& consumer_instance_type() const {
-+    return consumer_instance_type_;
-+  }
-+  void set_consumer_instance_type(
-+      const ConsumerInstanceType& consumer_instance_type) {
-+    consumer_instance_type_ = consumer_instance_type;
-+  }
-+
-+  int id() const { return user_script_id_; }
-+  void set_id(int id) { user_script_id_ = id; }
-+
-+  // TODO(lazyboy): Incognito information is extension specific, it doesn't
-+  // belong here. We should be able to determine this in the renderer/ where it
-+  // is used.
-+  bool is_incognito_enabled() const { return incognito_enabled_; }
-+  void set_incognito_enabled(bool enabled) { incognito_enabled_ = enabled; }
-+
-+  // Returns true if the script should be applied to the specified URL, false
-+  // otherwise.
-+  bool MatchesURL(const GURL& url) const;
-+
-+  // Returns true if the script should be applied to the given
-+  // |effective_document_url|. It is the caller's responsibility to calculate
-+  // |effective_document_url| based on match_origin_as_fallback().
-+  bool MatchesDocument(const GURL& effective_document_url,
-+                       bool is_subframe) const;
-+
-+  // Serializes the UserScript into a pickle. The content of the scripts and
-+  // paths to UserScript::Files will not be serialized!
-+  void Pickle(base::Pickle* pickle) const;
-+
-+  // Deserializes the script from a pickle. Note that this always succeeds
-+  // because presumably we were the one that pickled it, and we did it
-+  // correctly.
-+  void Unpickle(const base::Pickle& pickle, base::PickleIterator* iter);
-+
-+ private:
-+  // base::Pickle helper functions used to pickle the individual types of
-+  // components.
-+  void PickleGlobs(base::Pickle* pickle,
-+                   const std::vector<std::string>& globs) const;
-+  void PickleHostID(base::Pickle* pickle, const HostID& host_id) const;
-+  void PickleURLPatternSet(base::Pickle* pickle,
-+                           const URLPatternSet& pattern_list) const;
-+  void PickleScripts(base::Pickle* pickle, const FileList& scripts) const;
-+
-+  // Unpickle helper functions used to unpickle individual types of components.
-+  void UnpickleGlobs(const base::Pickle& pickle,
-+                     base::PickleIterator* iter,
-+                     std::vector<std::string>* globs);
-+  void UnpickleHostID(const base::Pickle& pickle,
-+                      base::PickleIterator* iter,
-+                      HostID* host_id);
-+  void UnpickleURLPatternSet(const base::Pickle& pickle,
-+                             base::PickleIterator* iter,
-+                             URLPatternSet* pattern_list);
-+  void UnpickleScripts(const base::Pickle& pickle,
-+                       base::PickleIterator* iter,
-+                       FileList* scripts);
-+
-+  // The location to run the script inside the document.
-+  RunLocation run_location_ = DOCUMENT_IDLE;
-+
-+  // The namespace of the script. This is used by Greasemonkey in the same way
-+  // as XML namespaces. Only used when parsing Greasemonkey-style scripts.
-+  std::string name_space_;
-+
-+  // The script's name. Only used when parsing Greasemonkey-style scripts.
-+  std::string name_;
-+
-+  // A longer description. Only used when parsing Greasemonkey-style scripts.
-+  std::string description_;
-+
-+  // Parser error to show to user
-+  std::string parser_error_;
-+
-+  // A version number of the script. Only used when parsing Greasemonkey-style
-+  // scripts.
-+  std::string version_;
-+
-+  // Greasemonkey-style globs that determine pages to inject the script into.
-+  // These are only used with standalone scripts.
-+  std::vector<std::string> globs_;
-+  std::vector<std::string> exclude_globs_;
-+
-+  // URLPatterns that determine pages to inject the script into. These are
-+  // only used with scripts that are part of extensions.
-+  URLPatternSet url_set_;
-+  URLPatternSet exclude_url_set_;
-+
-+  // List of js scripts defined in content_scripts
-+  FileList js_scripts_;
-+
-+  // List of css scripts defined in content_scripts
-+  FileList css_scripts_;
-+
-+  // internal key of scripts
-+  std::string key_;
-+
-+  std::string file_path_;
-+
-+  // url source of script
-+  std::string url_source_;
-+
-+  // The ID of the host this script is a part of. The |ID| of the
-+  // |host_id| can be empty if the script is a "standlone" user script.
-+  HostID host_id_;
-+
-+  // The type of the consumer instance that the script will be injected.
-+  ConsumerInstanceType consumer_instance_type_ = TAB;
-+
-+  // The globally-unique id associated with this user script. -1 indicates
-+  // "invalid".
-+  int user_script_id_ = -1;
-+
-+  // Whether we should try to emulate Greasemonkey's APIs when running this
-+  // script.
-+  bool emulate_greasemonkey_ = false;
-+
-+  // Whether the user script should run in all frames, or only just the top one.
-+  bool match_all_frames_ = false;
-+
-+  // Whether the user script should run in frames whose initiator / precursor
-+  // origin matches a match pattern, if an appropriate URL cannot be found for
-+  // the frame for matching purposes, such as in the case of about:, data:, and
-+  // other schemes.
-+  MatchOriginAsFallbackBehavior match_origin_as_fallback_ =
-+      MatchOriginAsFallbackBehavior::kNever;
-+
-+  // True if the script should be injected into an incognito tab.
-+  bool incognito_enabled_ = false;
-+
-+  // Script cannot be enabled
-+  bool force_disabled_ = false;
-+
-+  DISALLOW_COPY_AND_ASSIGN(UserScript);
-+};
-+
-+// Information we need while removing scripts from a UserScriptLoader.
-+struct UserScriptIDPair {
-+  UserScriptIDPair(int id, const HostID& host_id);
-+  explicit UserScriptIDPair(int id);
-+
-+  int id;
-+  HostID host_id;
-+};
-+
-+bool operator<(const UserScriptIDPair& a, const UserScriptIDPair& b);
-+
-+using UserScriptList = std::vector<std::unique_ptr<UserScript>>;
-+
-+}  // namespace extensions
-+
-+#endif  // USERSCRIPTS_COMMON_USER_SCRIPT_H_
-diff --git a/components/user_scripts/common/user_scripts_features.cc b/components/user_scripts/common/user_scripts_features.cc
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/common/user_scripts_features.cc
-@@ -0,0 +1,32 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+#include "user_scripts_features.h"
-+
-+#include "build/build_config.h"
-+
-+namespace user_scripts {
-+
-+namespace features {
-+
-+const base::Feature kEnableLoggingUserScripts =
-+                                        {"EnableLoggingUserScripts",
-+                                          base::FEATURE_DISABLED_BY_DEFAULT};
-+
-+}
-+
-+}
-\ No newline at end of file
-diff --git a/components/user_scripts/common/user_scripts_features.h b/components/user_scripts/common/user_scripts_features.h
-new file mode 100644
---- /dev/null
-+++ b/components/user_scripts/common/user_scripts_features.h
-@@ -0,0 +1,34 @@
-+/*
-+    This file is part of Bromite.
-+
-+    Bromite 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.
-+
-+    Bromite 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 Bromite. If not, see <https://www.gnu.org/licenses/>.
-+*/
-+
-+#ifndef USERSCRIPTS_COMMON_USERSCRIPTS_FEATURES_H_
-+#define USERSCRIPTS_COMMON_USERSCRIPTS_FEATURES_H_
-+
-+// This file defines all the base::FeatureList features for the Password Manager
-+// module.
-+
-+#include "base/feature_list.h"
-+
-+namespace user_scripts {
-+
-+namespace features {
-+    extern const base::Feature kEnableLoggingUserScripts;
-+}
-+
-+}
-+
-+#endif
-\ No newline at end of file
-diff --git a/components/user_scripts/common/view_type.cc b/components/user_scripts/common/view_type.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/common/view_type.cc
-@@ -0,0 +1,39 @@
-+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#include "view_type.h"
-+
-+#include "base/strings/string_piece.h"
-+
-+namespace user_scripts {
-+
-+bool GetViewTypeFromString(const std::string& view_type,
-+                           ViewType* view_type_out) {
-+  // TODO(devlin): This map doesn't contain the following values:
-+  // - VIEW_TYPE_BACKGROUND_CONTENTS
-+  // - VIEW_TYPE_COMPONENT
-+  // - VIEW_TYPE_EXTENSION_GUEST
-+  // Why? Is it just because we don't expose those types to JS?
-+  static const struct {
-+    ViewType type;
-+    base::StringPiece name;
-+  } constexpr kTypeMap[] = {
-+      // {VIEW_TYPE_APP_WINDOW, "APP_WINDOW"},
-+      // {VIEW_TYPE_EXTENSION_BACKGROUND_PAGE, "BACKGROUND"},
-+      // {VIEW_TYPE_EXTENSION_DIALOG, "EXTENSION_DIALOG"},
-+      // {VIEW_TYPE_EXTENSION_POPUP, "POPUP"},
-+      {VIEW_TYPE_TAB_CONTENTS, "TAB"},
-+  };
-+
-+  for (const auto& entry : kTypeMap) {
-+    if (entry.name == view_type) {
-+      *view_type_out = entry.type;
-+      return true;
-+    }
-+  }
-+
-+  return false;
-+}
-+
-+}  // namespace extensions
-diff --git a/components/user_scripts/common/view_type.h b/components/user_scripts/common/view_type.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/common/view_type.h
-@@ -0,0 +1,48 @@
-+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#ifndef USERSCRIPTS_COMMON_VIEW_TYPE_H_
-+#define USERSCRIPTS_COMMON_VIEW_TYPE_H_
-+
-+#include <string>
-+
-+namespace user_scripts {
-+
-+// Icky RTTI used by a few systems to distinguish the host type of a given
-+// WebContents.
-+//
-+// Do not change or reuse the the entry values in this list as this is used in
-+// ExtensionViewType enum in tools/metrics/histograms/enums.xml.
-+//
-+// TODO(aa): Remove this and teach those systems to keep track of their own
-+// data.
-+enum ViewType {
-+  VIEW_TYPE_INVALID = 0,
-+  // VIEW_TYPE_APP_WINDOW = 1,
-+  // VIEW_TYPE_BACKGROUND_CONTENTS = 2,
-+
-+  // // For custom parts of Chrome if no other type applies.
-+  // VIEW_TYPE_COMPONENT = 3,
-+
-+  // VIEW_TYPE_EXTENSION_BACKGROUND_PAGE = 4,
-+  // VIEW_TYPE_EXTENSION_DIALOG = 5,
-+  // VIEW_TYPE_EXTENSION_GUEST = 6,
-+  // VIEW_TYPE_EXTENSION_POPUP = 7,
-+
-+  // Panels were removed in https://crbug.com/571511.
-+  // DEPRECATED_VIEW_TYPE_PANEL = 8,
-+
-+  VIEW_TYPE_TAB_CONTENTS = 9,
-+
-+  VIEW_TYPE_LAST = VIEW_TYPE_TAB_CONTENTS
-+};
-+
-+// Matches the |view_type| to the corresponding ViewType, and populates
-+// |view_type_out|. Returns true if a match is found.
-+bool GetViewTypeFromString(const std::string& view_type,
-+                           ViewType* view_type_out);
-+
-+}  // namespace extensions
-+
-+#endif  // USERSCRIPTS_COMMON_VIEW_TYPE_H_
-diff --git a/components/user_scripts/renderer/BUILD.gn b/components/user_scripts/renderer/BUILD.gn
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/BUILD.gn
-@@ -0,0 +1,67 @@
-+# Copyright 2015 The Chromium Authors. All rights reserved.
-+# Use of this source code is governed by a BSD-style license that can be
-+# found in the LICENSE file.
-+
-+import("//tools/grit/grit_rule.gni")
-+import("//tools/grit/repack.gni")
-+
-+group("user_scripts_resources") {
-+  public_deps = [
-+    ":user_scripts_renderer_resources",
-+  ]
-+}
-+
-+grit("user_scripts_renderer_resources") {
-+  source = "resources/user_scripts_renderer_resources.grd"
-+  outputs = [
-+    "grit/user_scripts_renderer_resources.h",
-+    "user_scripts_renderer_resources.pak",
-+  ]
-+  grit_flags = [
-+    "-E",
-+    "mojom_root=" + rebase_path(root_gen_dir, root_build_dir),
-+  ]
-+}
-+
-+static_library("renderer") {
-+  sources = [
-+    "extension_frame_helper.cc",
-+    "extension_frame_helper.h",
-+    "injection_host.cc",
-+    "injection_host.h",
-+    "script_injection_manager.cc",
-+    "script_injection_manager.h",
-+    "script_injection_callback.cc",
-+    "script_injection_callback.h",
-+    "script_injection.cc",
-+    "script_injection.h",
-+    "script_injector.h",
-+    "script_context.cc",
-+    "script_context.h",
-+    "scripts_run_info.cc",
-+    "scripts_run_info.h",
-+    "user_script_injector.cc",
-+    "user_script_injector.h",
-+    "user_script_set_manager.cc",
-+    "user_script_set_manager.h",
-+    "user_script_set.cc",
-+    "user_script_set.h",
-+    "user_scripts_dispatcher.cc",
-+    "user_scripts_dispatcher.h",
-+    "user_scripts_renderer_client.cc",
-+    "user_scripts_renderer_client.h",
-+    "web_ui_injection_host.cc",
-+    "web_ui_injection_host.h",
-+  ]
-+
-+  deps = [
-+    ":user_scripts_resources",
-+    "//base",
-+    "//content/public/common",
-+    "//content/public/renderer",
-+    "//components/user_scripts/common",
-+    "//mojo/public/cpp/bindings",
-+    "//third_party/blink/public:blink_headers",
-+    "//v8",
-+  ]
-+}
-diff --git a/components/user_scripts/renderer/extension_frame_helper.cc b/components/user_scripts/renderer/extension_frame_helper.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/extension_frame_helper.cc
-@@ -0,0 +1,96 @@
-+// Copyright 2013 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#include "extension_frame_helper.h"
-+
-+#include <set>
-+
-+#include "base/metrics/histogram_macros.h"
-+#include "base/strings/string_util.h"
-+#include "base/timer/elapsed_timer.h"
-+#include "content/public/renderer/render_frame.h"
-+#include "content/public/renderer/render_view.h"
-+#include "../common/constants.h"
-+#include "third_party/blink/public/platform/web_security_origin.h"
-+#include "third_party/blink/public/web/web_console_message.h"
-+#include "third_party/blink/public/web/web_document.h"
-+#include "third_party/blink/public/web/web_document_loader.h"
-+#include "third_party/blink/public/web/web_local_frame.h"
-+#include "third_party/blink/public/web/web_settings.h"
-+#include "third_party/blink/public/web/web_view.h"
-+
-+namespace user_scripts {
-+
-+namespace {
-+
-+base::LazyInstance<std::set<const ExtensionFrameHelper*>>::DestructorAtExit
-+    g_frame_helpers = LAZY_INSTANCE_INITIALIZER;
-+
-+// Runs every callback in |callbacks_to_be_run_and_cleared| while |frame_helper|
-+// is valid, and clears |callbacks_to_be_run_and_cleared|.
-+void RunCallbacksWhileFrameIsValid(
-+    base::WeakPtr<ExtensionFrameHelper> frame_helper,
-+    std::vector<base::OnceClosure>* callbacks_to_be_run_and_cleared) {
-+  // The JavaScript code can cause re-entrancy. To avoid a deadlock, don't run
-+  // callbacks that are added during the iteration.
-+  std::vector<base::OnceClosure> callbacks;
-+  callbacks_to_be_run_and_cleared->swap(callbacks);
-+  for (auto& callback : callbacks) {
-+    std::move(callback).Run();
-+    if (!frame_helper.get())
-+      return;  // Frame and ExtensionFrameHelper invalidated by callback.
-+  }
-+}
-+
-+}  // namespace
-+
-+ExtensionFrameHelper::ExtensionFrameHelper(content::RenderFrame* render_frame)
-+    : content::RenderFrameObserver(render_frame),
-+      content::RenderFrameObserverTracker<ExtensionFrameHelper>(render_frame),
-+      tab_id_(-1) {
-+  g_frame_helpers.Get().insert(this);
-+}
-+
-+ExtensionFrameHelper::~ExtensionFrameHelper() {
-+  g_frame_helpers.Get().erase(this);
-+}
-+
-+void ExtensionFrameHelper::ScheduleAtDocumentStart(
-+    base::OnceClosure callback) {
-+  document_element_created_callbacks_.push_back(std::move(callback));
-+}
-+
-+void ExtensionFrameHelper::ScheduleAtDocumentEnd(
-+    base::OnceClosure callback) {
-+  document_load_finished_callbacks_.push_back(std::move(callback));
-+}
-+
-+void ExtensionFrameHelper::ScheduleAtDocumentIdle(
-+    base::OnceClosure callback) {
-+  document_idle_callbacks_.push_back(std::move(callback));
-+}
-+
-+void ExtensionFrameHelper::RunScriptsAtDocumentStart() {
-+  RunCallbacksWhileFrameIsValid(weak_ptr_factory_.GetWeakPtr(),
-+                                &document_element_created_callbacks_);
-+  // |this| might be dead by now.
-+}
-+
-+void ExtensionFrameHelper::RunScriptsAtDocumentEnd() {
-+  RunCallbacksWhileFrameIsValid(weak_ptr_factory_.GetWeakPtr(),
-+                                &document_load_finished_callbacks_);
-+  // |this| might be dead by now.
-+}
-+
-+void ExtensionFrameHelper::RunScriptsAtDocumentIdle() {
-+  RunCallbacksWhileFrameIsValid(weak_ptr_factory_.GetWeakPtr(),
-+                                &document_idle_callbacks_);
-+  // |this| might be dead by now.
-+}
-+
-+void ExtensionFrameHelper::OnDestruct() {
-+  delete this;
-+}
-+
-+}  // namespace user_scripts
-diff --git a/components/user_scripts/renderer/extension_frame_helper.h b/components/user_scripts/renderer/extension_frame_helper.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/extension_frame_helper.h
-@@ -0,0 +1,92 @@
-+// Copyright 2013 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#ifndef USERSCRIPTS_RENDERER_EXTENSION_FRAME_HELPER_H_
-+#define USERSCRIPTS_RENDERER_EXTENSION_FRAME_HELPER_H_
-+
-+#include <string>
-+#include <vector>
-+
-+#include "base/callback_forward.h"
-+#include "base/macros.h"
-+#include "base/memory/weak_ptr.h"
-+#include "content/public/renderer/render_frame_observer.h"
-+#include "content/public/renderer/render_frame_observer_tracker.h"
-+#include "../common/view_type.h"
-+#include "third_party/blink/public/mojom/devtools/console_message.mojom.h"
-+#include "v8/include/v8.h"
-+
-+struct ExtensionMsg_ExternalConnectionInfo;
-+struct ExtensionMsg_TabConnectionInfo;
-+
-+namespace base {
-+class ListValue;
-+}
-+
-+namespace user_scripts {
-+
-+class Dispatcher;
-+struct Message;
-+struct PortId;
-+class ScriptContext;
-+
-+// RenderFrame-level plumbing for extension features.
-+class ExtensionFrameHelper
-+    : public content::RenderFrameObserver,
-+      public content::RenderFrameObserverTracker<ExtensionFrameHelper> {
-+ public:
-+  ExtensionFrameHelper(content::RenderFrame* render_frame /*,
-+                       Dispatcher* extension_dispatcher*/);
-+  ~ExtensionFrameHelper() override;
-+
-+  int tab_id() const { return tab_id_; }
-+
-+  // Called when the document element has been inserted in this frame. This
-+  // method may invoke untrusted JavaScript code that invalidate the frame and
-+  // this ExtensionFrameHelper.
-+  void RunScriptsAtDocumentStart();
-+
-+  // Called after the DOMContentLoaded event has fired.
-+  void RunScriptsAtDocumentEnd();
-+
-+  // Called before the window.onload event is fired.
-+  void RunScriptsAtDocumentIdle();
-+
-+  // Schedule a callback, to be run at the next RunScriptsAtDocumentStart
-+  // notification. Only call this when you are certain that there will be such a
-+  // notification, e.g. from RenderFrameObserver::DidCreateDocumentElement.
-+  // Otherwise the callback is never invoked, or invoked for a document that you
-+  // were not expecting.
-+  void ScheduleAtDocumentStart(base::OnceClosure callback);
-+
-+  // Schedule a callback, to be run at the next RunScriptsAtDocumentEnd call.
-+  void ScheduleAtDocumentEnd(base::OnceClosure callback);
-+
-+  // Schedule a callback, to be run at the next RunScriptsAtDocumentIdle call.
-+  void ScheduleAtDocumentIdle(base::OnceClosure callback);
-+
-+ private:
-+
-+  void OnDestruct() override;
-+
-+  // The id of the tab the render frame is attached to.
-+  int tab_id_;
-+
-+  // Callbacks to be run at the next RunScriptsAtDocumentStart notification.
-+  std::vector<base::OnceClosure> document_element_created_callbacks_;
-+
-+  // Callbacks to be run at the next RunScriptsAtDocumentEnd notification.
-+  std::vector<base::OnceClosure> document_load_finished_callbacks_;
-+
-+  // Callbacks to be run at the next RunScriptsAtDocumentIdle notification.
-+  std::vector<base::OnceClosure> document_idle_callbacks_;
-+
-+  base::WeakPtrFactory<ExtensionFrameHelper> weak_ptr_factory_{this};
-+
-+  DISALLOW_COPY_AND_ASSIGN(ExtensionFrameHelper);
-+};
-+
-+}  // namespace extensions
-+
-+#endif  // USERSCRIPTS_RENDERER_EXTENSION_FRAME_HELPER_H_
-diff --git a/components/user_scripts/renderer/injection_host.cc b/components/user_scripts/renderer/injection_host.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/injection_host.cc
-@@ -0,0 +1,12 @@
-+// Copyright 2015 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#include "injection_host.h"
-+
-+InjectionHost::InjectionHost(const HostID& host_id) :
-+    id_(host_id) {
-+}
-+
-+InjectionHost::~InjectionHost() {
-+}
-diff --git a/components/user_scripts/renderer/injection_host.h b/components/user_scripts/renderer/injection_host.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/injection_host.h
-@@ -0,0 +1,42 @@
-+// Copyright 2015 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#ifndef USERSCRIPTS_RENDERER_INJECTION_HOST_H_
-+#define USERSCRIPTS_RENDERER_INJECTION_HOST_H_
-+
-+#include "base/macros.h"
-+#include "../common/host_id.h"
-+#include "url/gurl.h"
-+
-+namespace content {
-+class RenderFrame;
-+}
-+
-+// An interface for all kinds of hosts who own user scripts.
-+class InjectionHost {
-+ public:
-+  InjectionHost(const HostID& host_id);
-+  virtual ~InjectionHost();
-+
-+  // Returns the CSP to be used for the isolated world. Currently this only
-+  // bypasses the main world CSP. If null is returned, the main world CSP is not
-+  // bypassed.
-+  virtual const std::string* GetContentSecurityPolicy() const = 0;
-+
-+  // The base url for the host.
-+  virtual const GURL& url() const = 0;
-+
-+  // The human-readable name of the host.
-+  virtual const std::string& name() const = 0;
-+
-+  const HostID& id() const { return id_; }
-+
-+ private:
-+  // The ID of the host.
-+  HostID id_;
-+
-+  DISALLOW_COPY_AND_ASSIGN(InjectionHost);
-+};
-+
-+#endif  // USERSCRIPTS_RENDERER_INJECTION_HOST_H_
-diff --git a/components/user_scripts/renderer/resources/greasemonkey_api.js b/components/user_scripts/renderer/resources/greasemonkey_api.js
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/resources/greasemonkey_api.js
-@@ -0,0 +1,82 @@
-+// Copyright 2014 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+// -----------------------------------------------------------------------------
-+// NOTE: If you change this file you need to touch renderer_resources.grd to
-+// have your change take effect.
-+// -----------------------------------------------------------------------------
-+
-+// Partial implementation of the Greasemonkey API, see:
-+// http://wiki.greasespot.net/Greasemonkey_Manual:APIs
-+
-+function GM_addStyle(css) {
-+  var parent = document.getElementsByTagName("head")[0];
-+  if (!parent) {
-+    parent = document.documentElement;
-+  }
-+  var style = document.createElement("style");
-+  style.type = "text/css";
-+  var textNode = document.createTextNode(css);
-+  style.appendChild(textNode);
-+  parent.appendChild(style);
-+}
-+
-+function GM_xmlhttpRequest(details) {
-+  function setupEvent(xhr, url, eventName, callback) {
-+    xhr[eventName] = function () {
-+      var isComplete = xhr.readyState == 4;
-+      var responseState = {
-+        responseText: xhr.responseText,
-+        readyState: xhr.readyState,
-+        responseHeaders: isComplete ? xhr.getAllResponseHeaders() : "",
-+        status: isComplete ? xhr.status : 0,
-+        statusText: isComplete ? xhr.statusText : "",
-+        finalUrl: isComplete ? url : ""
-+      };
-+      callback(responseState);
-+    };
-+  }
-+
-+  var xhr = new XMLHttpRequest();
-+  var eventNames = ["onload", "onerror", "onreadystatechange"];
-+  for (var i = 0; i < eventNames.length; i++ ) {
-+    var eventName = eventNames[i];
-+    if (eventName in details) {
-+      setupEvent(xhr, details.url, eventName, details[eventName]);
-+    }
-+  }
-+
-+  xhr.open(details.method, details.url);
-+
-+  if (details.overrideMimeType) {
-+    xhr.overrideMimeType(details.overrideMimeType);
-+  }
-+  if (details.headers) {
-+    for (var header in details.headers) {
-+      xhr.setRequestHeader(header, details.headers[header]);
-+    }
-+  }
-+  xhr.send(details.data ? details.data : null);
-+}
-+
-+function GM_openInTab(url) {
-+  window.open(url, "");
-+}
-+
-+function GM_log(message) {
-+  window.console.log(message);
-+}
-+
-+(function() {
-+  function generateGreasemonkeyStub(name) {
-+    return function() {
-+      console.log("%s is not supported.", name);
-+    };
-+  }
-+
-+  var apis = ["GM_getValue", "GM_setValue", "GM_registerMenuCommand"];
-+  for (var i = 0, api; api = apis[i]; i++) {
-+    window[api] = generateGreasemonkeyStub(api);
-+  }
-+})();
-diff --git a/components/user_scripts/renderer/resources/user_scripts_renderer_resources.grd b/components/user_scripts/renderer/resources/user_scripts_renderer_resources.grd
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/resources/user_scripts_renderer_resources.grd
-@@ -0,0 +1,14 @@
-+<?xml version="1.0" encoding="UTF-8"?>
-+<grit latest_public_release="0" current_release="1" output_all_resource_defines="false">
-+  <outputs>
-+    <output filename="grit/user_scripts_renderer_resources.h" type="rc_header">
-+      <emit emit_type='prepend'></emit>
-+    </output>
-+    <output filename="user_scripts_renderer_resources.pak" type="data_package" />
-+  </outputs>
-+  <release seq="1">
-+    <includes>
-+      <include name="IDR_GREASEMONKEY_API_JS" file="greasemonkey_api.js" type="BINDATA" />
-+    </includes>
-+  </release>
-+</grit>
-diff --git a/components/user_scripts/renderer/script_context.cc b/components/user_scripts/renderer/script_context.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/script_context.cc
-@@ -0,0 +1,215 @@
-+// Copyright 2014 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#include "script_context.h"
-+
-+#include "base/command_line.h"
-+#include "base/containers/flat_set.h"
-+#include "base/containers/contains.h"
-+#include "base/logging.h"
-+#include "base/no_destructor.h"
-+#include "base/stl_util.h"
-+#include "base/strings/string_util.h"
-+#include "base/strings/stringprintf.h"
-+#include "base/values.h"
-+#include "content/public/common/content_switches.h"
-+#include "content/public/common/url_constants.h"
-+#include "content/public/renderer/render_frame.h"
-+#include "../common/constants.h"
-+#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
-+#include "third_party/blink/public/platform/web_security_origin.h"
-+#include "third_party/blink/public/web/web_document.h"
-+#include "third_party/blink/public/web/web_document_loader.h"
-+#include "third_party/blink/public/web/web_local_frame.h"
-+#include "third_party/blink/public/web/web_navigation_params.h"
-+#include "v8/include/v8.h"
-+
-+namespace user_scripts {
-+
-+namespace {
-+
-+GURL GetEffectiveDocumentURL(
-+    blink::WebLocalFrame* frame,
-+    const GURL& document_url,
-+    MatchOriginAsFallbackBehavior match_origin_as_fallback,
-+    bool allow_inaccessible_parents) {
-+  auto should_consider_origin = [document_url, match_origin_as_fallback]() {
-+    switch (match_origin_as_fallback) {
-+      case MatchOriginAsFallbackBehavior::kNever:
-+        return false;
-+      case MatchOriginAsFallbackBehavior::kMatchForAboutSchemeAndClimbTree:
-+        return document_url.SchemeIs(url::kAboutScheme);
-+      case MatchOriginAsFallbackBehavior::kAlways:
-+        // TODO(devlin): Add more schemes here - blob, filesystem, etc.
-+        return document_url.SchemeIs(url::kAboutScheme) ||
-+               document_url.SchemeIs(url::kDataScheme);
-+    }
-+
-+    NOTREACHED();
-+  };
-+
-+  // If we don't need to consider the origin, we're done.
-+  if (!should_consider_origin())
-+    return document_url;
-+
-+  // Get the "security origin" for the frame. For about: frames, this is the
-+  // origin of that of the controlling frame - e.g., an about:blank frame on
-+  // https://example.com will have the security origin of https://example.com.
-+  // Other frames, like data: frames, will have an opaque origin. For these,
-+  // we can get the precursor origin.
-+  const blink::WebSecurityOrigin web_frame_origin = frame->GetSecurityOrigin();
-+  const url::Origin frame_origin = web_frame_origin;
-+  const url::SchemeHostPort& tuple_or_precursor_tuple =
-+      frame_origin.GetTupleOrPrecursorTupleIfOpaque();
-+
-+  // When there's no valid tuple (which can happen in the case of e.g. a
-+  // browser-initiated navigation to an opaque URL), there's no origin to
-+  // fallback to. Bail.
-+  if (!tuple_or_precursor_tuple.IsValid())
-+    return document_url;
-+
-+  const url::Origin origin_or_precursor_origin =
-+      url::Origin::Create(tuple_or_precursor_tuple.GetURL());
-+
-+  if (!allow_inaccessible_parents &&
-+      !web_frame_origin.CanAccess(
-+          blink::WebSecurityOrigin(origin_or_precursor_origin))) {
-+    // The frame can't access its precursor. Bail.
-+    return document_url;
-+  }
-+
-+  // Looks like the initiator origin is an appropriate fallback!
-+
-+  if (match_origin_as_fallback == MatchOriginAsFallbackBehavior::kAlways) {
-+    // The easy case! We use the origin directly. We're done.
-+    return origin_or_precursor_origin.GetURL();
-+  }
-+
-+  DCHECK_EQ(MatchOriginAsFallbackBehavior::kMatchForAboutSchemeAndClimbTree,
-+            match_origin_as_fallback);
-+
-+  // Unfortunately, in this case, we have to climb the frame tree. This is for
-+  // match patterns that are associated with paths as well, not just origins.
-+  // For instance, if an extension wants to run on google.com/maps/* with
-+  // match_about_blank true, then it should run on about:-scheme frames created
-+  // by google.com/maps, but not about:-scheme frames created by google.com
-+  // (which is what the precursor tuple origin would be).
-+
-+  // Traverse the frame/window hierarchy to find the closest non-about:-page
-+  // with the same origin as the precursor and return its URL.
-+  // Note: This can return the incorrect result, e.g. if a parent frame
-+  // navigates a grandchild frame.
-+  blink::WebFrame* parent = frame;
-+  GURL parent_url;
-+  blink::WebDocument parent_document;
-+  base::flat_set<blink::WebFrame*> already_visited_frames;
-+  do {
-+    already_visited_frames.insert(parent);
-+    if (parent->Parent())
-+      parent = parent->Parent();
-+    else
-+      parent = parent->Opener();
-+
-+    // Avoid an infinite loop - see https://crbug.com/568432 and
-+    // https://crbug.com/883526.
-+    if (base::Contains(already_visited_frames, parent))
-+      return document_url;
-+
-+    parent_document = parent && parent->IsWebLocalFrame()
-+                          ? parent->ToWebLocalFrame()->GetDocument()
-+                          : blink::WebDocument();
-+
-+    // We reached the end of the ancestral chain without finding a valid parent,
-+    // or found a remote web frame (in which case, it's a different origin).
-+    // Bail and use the original URL.
-+    if (parent_document.IsNull())
-+      return document_url;
-+
-+    url::SchemeHostPort parent_tuple_or_precursor_tuple =
-+        url::Origin(parent->GetSecurityOrigin())
-+            .GetTupleOrPrecursorTupleIfOpaque();
-+    if (!parent_tuple_or_precursor_tuple.IsValid() ||
-+        parent_tuple_or_precursor_tuple != tuple_or_precursor_tuple) {
-+      // The parent has a different tuple origin than frame; this could happen
-+      // in edge cases where a parent navigates an iframe or popup of a child
-+      // frame at a different origin. [1] In this case, bail, since we can't
-+      // find a full URL (i.e., one including the path) with the same security
-+      // origin to use for the frame in question.
-+      // [1] Consider a frame tree like:
-+      // <html> <!--example.com-->
-+      //   <iframe id="a" src="a.com">
-+      //     <iframe id="b" src="b.com"></iframe>
-+      //   </iframe>
-+      // </html>
-+      // Frame "a" is cross-origin from the top-level frame, and so the
-+      // example.com top-level frame can't directly access frame "b". However,
-+      // it can navigate it through
-+      // window.frames[0].frames[0].location.href = 'about:blank';
-+      // In that case, the precursor origin tuple origin of frame "b" would be
-+      // example.com, but the parent tuple origin is a.com.
-+      // Note that usually, this would have bailed earlier with a remote frame,
-+      // but it may not if we're at the process limit.
-+      return document_url;
-+    }
-+
-+    parent_url = GURL(parent_document.Url());
-+  } while (parent_url.SchemeIs(url::kAboutScheme));
-+
-+  DCHECK(!parent_url.is_empty());
-+  DCHECK(!parent_document.IsNull());
-+
-+  // We should know that the frame can access the parent document (unless we
-+  // explicitly allow it not to), since it has the same tuple origin as the
-+  // frame, and we checked the frame access above.
-+  DCHECK(allow_inaccessible_parents ||
-+         web_frame_origin.CanAccess(parent_document.GetSecurityOrigin()));
-+  return parent_url;
-+}
-+
-+using FrameToDocumentLoader =
-+    base::flat_map<blink::WebLocalFrame*, blink::WebDocumentLoader*>;
-+
-+FrameToDocumentLoader& FrameDocumentLoaderMap() {
-+  static base::NoDestructor<FrameToDocumentLoader> map;
-+  return *map;
-+}
-+
-+blink::WebDocumentLoader* CurrentDocumentLoader(
-+    const blink::WebLocalFrame* frame) {
-+  auto& map = FrameDocumentLoaderMap();
-+  auto it = map.find(frame);
-+  return it == map.end() ? frame->GetDocumentLoader() : it->second;
-+}
-+
-+}  // namespace
-+
-+// static
-+GURL ScriptContext::GetDocumentLoaderURLForFrame(
-+    const blink::WebLocalFrame* frame) {
-+  // Normally we would use frame->document().url() to determine the document's
-+  // URL, but to decide whether to inject a content script, we use the URL from
-+  // the data source. This "quirk" helps prevents content scripts from
-+  // inadvertently adding DOM elements to the compose iframe in Gmail because
-+  // the compose iframe's dataSource URL is about:blank, but the document URL
-+  // changes to match the parent document after Gmail document.writes into
-+  // it to create the editor.
-+  // http://code.google.com/p/chromium/issues/detail?id=86742
-+  blink::WebDocumentLoader* document_loader = CurrentDocumentLoader(frame);
-+  return document_loader ? GURL(document_loader->GetUrl()) : GURL();
-+}
-+
-+// static
-+GURL ScriptContext::GetEffectiveDocumentURLForInjection(
-+    blink::WebLocalFrame* frame,
-+    const GURL& document_url,
-+    MatchOriginAsFallbackBehavior match_origin_as_fallback) {
-+  // We explicitly allow inaccessible parents here. Extensions should still be
-+  // able to inject into a sandboxed iframe if it has access to the embedding
-+  // origin.
-+  constexpr bool allow_inaccessible_parents = true;
-+  return GetEffectiveDocumentURL(frame, document_url, match_origin_as_fallback,
-+                                 allow_inaccessible_parents);
-+}
-+
-+}  // namespace extensions
-diff --git a/components/user_scripts/renderer/script_context.h b/components/user_scripts/renderer/script_context.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/script_context.h
-@@ -0,0 +1,70 @@
-+// Copyright 2014 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#ifndef USERSCRIPTS_RENDERER_SCRIPT_CONTEXT_H_
-+#define USERSCRIPTS_RENDERER_SCRIPT_CONTEXT_H_
-+
-+#include <memory>
-+#include <string>
-+#include <utility>
-+#include <vector>
-+
-+#include "base/callback.h"
-+#include "base/compiler_specific.h"
-+#include "base/macros.h"
-+#include "base/threading/thread_checker.h"
-+#include "base/unguessable_token.h"
-+#include "../common/script_constants.h"
-+#include "script_injection_callback.h"
-+#include "url/gurl.h"
-+#include "v8/include/v8.h"
-+
-+namespace blink {
-+class WebDocumentLoader;
-+class WebLocalFrame;
-+}
-+
-+namespace content {
-+class RenderFrame;
-+}
-+
-+namespace user_scripts {
-+
-+// Extensions wrapper for a v8::Context.
-+//
-+// v8::Contexts can be constructed on any thread, and must only be accessed or
-+// destroyed that thread.
-+//
-+// Note that ScriptContexts bound to worker threads will not have the full
-+// functionality as those bound to the main RenderThread.
-+class ScriptContext {
-+ public:
-+  // TODO(devlin): Move all these Get*URL*() methods out of here? While they are
-+  // vaguely ScriptContext related, there's enough here that they probably
-+  // warrant another class or utility file.
-+
-+  // Utility to get the URL we will match against for a frame. If the frame has
-+  // committed, this is the commited URL. Otherwise it is the provisional URL.
-+  // The returned URL may be invalid.
-+  static GURL GetDocumentLoaderURLForFrame(const blink::WebLocalFrame* frame);
-+
-+  // Used to determine the "effective" URL for extension script injection.
-+  // If |document_url| is an about: or data: URL, returns the URL of the first
-+  // frame without an about: or data: URL that matches the initiator origin.
-+  // This may not be the immediate parent. Returns |document_url| if it is not
-+  // an about: or data: URL, if |match_origin_as_fallback| is set to not match,
-+  // or if a suitable parent cannot be found.
-+  // Considers parent contexts that cannot be accessed (as is the case for
-+  // sandboxed frames).
-+  static GURL GetEffectiveDocumentURLForInjection(
-+      blink::WebLocalFrame* frame,
-+      const GURL& document_url,
-+      MatchOriginAsFallbackBehavior match_origin_as_fallback);
-+
-+//   DISALLOW_COPY_AND_ASSIGN(ScriptContext);
-+};
-+
-+}  // namespace extensions
-+
-+#endif  // USERSCRIPTS_RENDERER_SCRIPT_CONTEXT_H_
-diff --git a/components/user_scripts/renderer/script_injection.cc b/components/user_scripts/renderer/script_injection.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/script_injection.cc
-@@ -0,0 +1,343 @@
-+// Copyright 2014 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#include "script_injection.h"
-+
-+#include <map>
-+#include <utility>
-+
-+#include "base/bind.h"
-+#include "base/feature_list.h"
-+#include "base/lazy_instance.h"
-+#include "base/macros.h"
-+#include "base/metrics/histogram_macros.h"
-+#include "base/timer/elapsed_timer.h"
-+#include "base/values.h"
-+#include "base/logging.h"
-+#include "content/public/renderer/render_frame.h"
-+#include "content/public/renderer/render_frame_observer.h"
-+#include "content/public/renderer/v8_value_converter.h"
-+#include "../common/host_id.h"
-+#include "script_injection_callback.h"
-+#include "scripts_run_info.h"
-+#include "third_party/blink/public/platform/web_isolated_world_info.h"
-+#include "third_party/blink/public/platform/web_security_origin.h"
-+#include "third_party/blink/public/platform/web_string.h"
-+#include "third_party/blink/public/web/web_document.h"
-+#include "third_party/blink/public/web/web_local_frame.h"
-+#include "third_party/blink/public/web/web_script_source.h"
-+#include "url/gurl.h"
-+
-+namespace user_scripts {
-+
-+namespace {
-+
-+using IsolatedWorldMap = std::map<std::string, int>;
-+base::LazyInstance<IsolatedWorldMap>::DestructorAtExit g_isolated_worlds =
-+    LAZY_INSTANCE_INITIALIZER;
-+
-+const int64_t kInvalidRequestId = -1;
-+
-+// Gets the isolated world ID to use for the given |injection_host|. If no
-+// isolated world has been created for that |injection_host| one will be created
-+// and initialized.
-+int GetIsolatedWorldIdForInstance(const InjectionHost* injection_host) {
-+  static int g_next_isolated_world_id = 1; // Embedder isolated worlds can use IDs in [1, 1<<29).
-+
-+  IsolatedWorldMap& isolated_worlds = g_isolated_worlds.Get();
-+
-+  int id = 0;
-+  const std::string& key = injection_host->id().id();
-+  auto iter = isolated_worlds.find(key);
-+  if (iter != isolated_worlds.end()) {
-+    id = iter->second;
-+  } else {
-+    id = g_next_isolated_world_id++;
-+    // This map will tend to pile up over time, but realistically, you're never
-+    // going to have enough injection hosts for it to matter.
-+    isolated_worlds[key] = id;
-+  }
-+
-+  blink::WebIsolatedWorldInfo info;
-+  info.security_origin =
-+      blink::WebSecurityOrigin::Create(injection_host->url());
-+  info.human_readable_name = blink::WebString::FromUTF8(injection_host->name());
-+  info.stable_id = blink::WebString::FromUTF8(key);
-+
-+  const std::string* csp = injection_host->GetContentSecurityPolicy();
-+  if (csp)
-+    info.content_security_policy = blink::WebString::FromUTF8(*csp);
-+
-+  // Even though there may be an existing world for this |injection_host|'s key,
-+  // the properties may have changed (e.g. due to an extension update).
-+  // Overwrite any existing entries.
-+  blink::SetIsolatedWorldInfo(id, info);
-+
-+  return id;
-+}
-+
-+// This class manages its own lifetime.
-+class TimedScriptInjectionCallback : public ScriptInjectionCallback {
-+ public:
-+  TimedScriptInjectionCallback(base::WeakPtr<ScriptInjection> injection)
-+      : ScriptInjectionCallback(
-+            base::BindOnce(&TimedScriptInjectionCallback::OnCompleted,
-+                       base::Unretained(this))),
-+        injection_(injection) {}
-+  ~TimedScriptInjectionCallback() override {}
-+
-+  void OnCompleted(const std::vector<v8::Local<v8::Value>>& result) {
-+    if (injection_) {
-+      base::TimeTicks timestamp(base::TimeTicks::Now());
-+      absl::optional<base::TimeDelta> elapsed;
-+      // If the script will never execute (such as if the context is destroyed),
-+      // willExecute() will not be called, but OnCompleted() will. Only log a
-+      // time for execution if the script, in fact, executed.
-+      if (!start_time_.is_null())
-+        elapsed = timestamp - start_time_;
-+      injection_->OnJsInjectionCompleted(result, elapsed);
-+    }
-+  }
-+
-+  void WillExecute() override {
-+    start_time_ = base::TimeTicks::Now();
-+  }
-+
-+ private:
-+  base::WeakPtr<ScriptInjection> injection_;
-+  base::TimeTicks start_time_;
-+};
-+
-+}  // namespace
-+
-+// Watches for the deletion of a RenderFrame, after which is_valid will return
-+// false.
-+class ScriptInjection::FrameWatcher : public content::RenderFrameObserver {
-+ public:
-+  FrameWatcher(content::RenderFrame* render_frame,
-+               ScriptInjection* injection)
-+      : content::RenderFrameObserver(render_frame),
-+        injection_(injection) {}
-+  ~FrameWatcher() override {}
-+
-+ private:
-+  void WillDetach() override { injection_->invalidate_render_frame(); }
-+  void OnDestruct() override { injection_->invalidate_render_frame(); }
-+
-+  ScriptInjection* injection_;
-+
-+  DISALLOW_COPY_AND_ASSIGN(FrameWatcher);
-+};
-+
-+// static
-+std::string ScriptInjection::GetHostIdForIsolatedWorld(int isolated_world_id) {
-+  const IsolatedWorldMap& isolated_worlds = g_isolated_worlds.Get();
-+
-+  for (const auto& iter : isolated_worlds) {
-+    if (iter.second == isolated_world_id)
-+      return iter.first;
-+  }
-+  return std::string();
-+}
-+
-+// static
-+void ScriptInjection::RemoveIsolatedWorld(const std::string& host_id) {
-+  g_isolated_worlds.Get().erase(host_id);
-+}
-+
-+ScriptInjection::ScriptInjection(
-+    std::unique_ptr<ScriptInjector> injector,
-+    content::RenderFrame* render_frame,
-+    std::unique_ptr<const InjectionHost> injection_host,
-+    UserScript::RunLocation run_location,
-+    bool log_activity)
-+    : injector_(std::move(injector)),
-+      render_frame_(render_frame),
-+      injection_host_(std::move(injection_host)),
-+      run_location_(run_location),
-+      request_id_(kInvalidRequestId),
-+      complete_(false),
-+      did_inject_js_(false),
-+      log_activity_(log_activity),
-+      frame_watcher_(new FrameWatcher(render_frame, this)) {
-+  CHECK(injection_host_.get());
-+}
-+
-+ScriptInjection::~ScriptInjection() {
-+  if (!complete_)
-+    NotifyWillNotInject(ScriptInjector::WONT_INJECT);
-+}
-+
-+ScriptInjection::InjectionResult ScriptInjection::TryToInject(
-+    UserScript::RunLocation current_location,
-+    ScriptsRunInfo* scripts_run_info,
-+    CompletionCallback async_completion_callback) {
-+  if (current_location < run_location_)
-+    return INJECTION_WAITING;  // Wait for the right location.
-+
-+  if (request_id_ != kInvalidRequestId) {
-+    // We're waiting for permission right now, try again later.
-+    return INJECTION_WAITING;
-+  }
-+
-+  if (!injection_host_) {
-+    NotifyWillNotInject(ScriptInjector::EXTENSION_REMOVED);
-+    return INJECTION_FINISHED;  // We're done.
-+  }
-+
-+  InjectionResult result = Inject(scripts_run_info);
-+  // If the injection is blocked, we need to set the manager so we can
-+  // notify it upon completion.
-+  if (result == INJECTION_BLOCKED)
-+    async_completion_callback_ = std::move(async_completion_callback);
-+  return result;
-+}
-+
-+ScriptInjection::InjectionResult ScriptInjection::OnPermissionGranted(
-+    ScriptsRunInfo* scripts_run_info) {
-+  if (!injection_host_) {
-+    NotifyWillNotInject(ScriptInjector::EXTENSION_REMOVED);
-+    return INJECTION_FINISHED;
-+  }
-+
-+  return Inject(scripts_run_info);
-+}
-+
-+void ScriptInjection::OnHostRemoved() {
-+  injection_host_.reset(nullptr);
-+}
-+
-+void ScriptInjection::NotifyWillNotInject(
-+    ScriptInjector::InjectFailureReason reason) {
-+  complete_ = true;
-+  injector_->OnWillNotInject(reason, render_frame_);
-+}
-+
-+ScriptInjection::InjectionResult ScriptInjection::Inject(
-+    ScriptsRunInfo* scripts_run_info) {
-+  DCHECK(injection_host_);
-+  //DCHECK(scripts_run_info);
-+  DCHECK(!complete_);
-+  bool should_inject_js = injector_->ShouldInjectJs(
-+      run_location_, scripts_run_info->executing_scripts[host_id().id()]);
-+  bool should_inject_css = injector_->ShouldInjectCss(
-+      run_location_, scripts_run_info->injected_stylesheets[host_id().id()]);
-+
-+  // This can happen if the extension specified a script to
-+  // be run in multiple rules, and the script has already run.
-+  // See crbug.com/631247.
-+  if (!should_inject_js && !should_inject_css) {
-+    return INJECTION_FINISHED;
-+  }
-+
-+  if (should_inject_js)
-+    InjectJs(&(scripts_run_info->executing_scripts[host_id().id()]),
-+             &(scripts_run_info->num_js));
-+  if (should_inject_css)
-+    InjectCss(&(scripts_run_info->injected_stylesheets[host_id().id()]),
-+              &(scripts_run_info->num_css));
-+
-+  complete_ = did_inject_js_ || !should_inject_js;
-+
-+  if (complete_) {
-+    injector_->OnInjectionComplete(std::move(execution_result_), run_location_,
-+                                   render_frame_);
-+  } else {
-+    ++scripts_run_info->num_blocking_js;
-+  }
-+
-+  return complete_ ? INJECTION_FINISHED : INJECTION_BLOCKED;
-+}
-+
-+void ScriptInjection::InjectJs(std::set<std::string>* executing_scripts,
-+                               size_t* num_injected_js_scripts) {
-+  DCHECK(!did_inject_js_);
-+  std::vector<blink::WebScriptSource> sources = injector_->GetJsSources(
-+      run_location_, executing_scripts, num_injected_js_scripts);
-+  DCHECK(!sources.empty());
-+  int world_id = GetIsolatedWorldIdForInstance(injection_host_.get());
-+  bool is_user_gesture = injector_->IsUserGesture();
-+
-+  std::unique_ptr<blink::WebScriptExecutionCallback> callback(
-+      new TimedScriptInjectionCallback(weak_ptr_factory_.GetWeakPtr()));
-+
-+  base::ElapsedTimer exec_timer;
-+
-+  // For content scripts executing during page load, we run them asynchronously
-+  // in order to reduce UI jank experienced by the user. (We don't do this for
-+  // DOCUMENT_START scripts, because there's no UI to jank until after those
-+  // run, so we run them as soon as we can.)
-+  // Note: We could potentially also run deferred and browser-driven scripts
-+  // asynchronously; however, these are rare enough that there probably isn't
-+  // UI jank. If this changes, we can update this.
-+  bool should_execute_asynchronously =
-+      injector_->script_type() == UserScript::CONTENT_SCRIPT &&
-+      (run_location_ == UserScript::DOCUMENT_END ||
-+       run_location_ == UserScript::DOCUMENT_IDLE);
-+  blink::WebLocalFrame::ScriptExecutionType execution_option =
-+      should_execute_asynchronously
-+          ? blink::WebLocalFrame::kAsynchronousBlockingOnload
-+          : blink::WebLocalFrame::kSynchronous;
-+
-+  render_frame_->GetWebFrame()->RequestExecuteScriptInIsolatedWorld(
-+      world_id, &sources.front(), sources.size(), is_user_gesture,
-+      execution_option, callback.release(),
-+      blink::BackForwardCacheAware::kPossiblyDisallow);
-+}
-+
-+void ScriptInjection::OnJsInjectionCompleted(
-+    const std::vector<v8::Local<v8::Value>>& results,
-+    absl::optional<base::TimeDelta> elapsed) {
-+  DCHECK(!did_inject_js_);
-+
-+  bool expects_results = injector_->ExpectsResults();
-+  if (expects_results) {
-+    if (!results.empty() && !results[0].IsEmpty()) {
-+      // Right now, we only support returning single results (per frame).
-+      // It's safe to always use the main world context when converting
-+      // here. V8ValueConverterImpl shouldn't actually care about the
-+      // context scope, and it switches to v8::Object's creation context
-+      // when encountered.
-+      v8::Local<v8::Context> context =
-+          render_frame_->GetWebFrame()->MainWorldScriptContext();
-+      execution_result_ =
-+          content::V8ValueConverter::Create()->FromV8Value(results[0], context);
-+    }
-+    if (!execution_result_.get())
-+      execution_result_ = std::make_unique<base::Value>();
-+  }
-+  did_inject_js_ = true;
-+
-+  // If |async_completion_callback_| is set, it means the script finished
-+  // asynchronously, and we should run it.
-+  if (!async_completion_callback_.is_null()) {
-+    complete_ = true;
-+    injector_->OnInjectionComplete(std::move(execution_result_), run_location_,
-+                                   render_frame_);
-+    // Warning: this object can be destroyed after this line!
-+    std::move(async_completion_callback_).Run(this);
-+  }
-+}
-+
-+void ScriptInjection::InjectCss(std::set<std::string>* injected_stylesheets,
-+                                size_t* num_injected_stylesheets) {
-+  std::vector<blink::WebString> css_sources = injector_->GetCssSources(
-+      run_location_, injected_stylesheets, num_injected_stylesheets);
-+  blink::WebLocalFrame* web_frame = render_frame_->GetWebFrame();
-+  // Default CSS origin is "author", but can be overridden to "user" by scripts.
-+  absl::optional<CSSOrigin> css_origin = injector_->GetCssOrigin();
-+  blink::WebDocument::CSSOrigin blink_css_origin =
-+      css_origin && *css_origin == CSS_ORIGIN_USER
-+          ? blink::WebDocument::kUserOrigin
-+          : blink::WebDocument::kAuthorOrigin;
-+  blink::WebStyleSheetKey style_sheet_key;
-+  if (const absl::optional<std::string>& injection_key =
-+          injector_->GetInjectionKey())
-+    style_sheet_key = blink::WebString::FromASCII(*injection_key);
-+  for (const blink::WebString& css : css_sources)
-+    web_frame->GetDocument().InsertStyleSheet(css, &style_sheet_key,
-+                                              blink_css_origin);
-+}
-+
-+}  // namespace extensions
-diff --git a/components/user_scripts/renderer/script_injection.h b/components/user_scripts/renderer/script_injection.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/script_injection.h
-@@ -0,0 +1,155 @@
-+// Copyright 2014 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#ifndef USERSCRIPTS_RENDERER_SCRIPT_INJECTION_H_
-+#define USERSCRIPTS_RENDERER_SCRIPT_INJECTION_H_
-+
-+#include <stdint.h>
-+
-+#include <memory>
-+#include <vector>
-+
-+#include "base/callback.h"
-+#include "base/macros.h"
-+#include "base/memory/weak_ptr.h"
-+#include "../common/user_script.h"
-+#include "injection_host.h"
-+#include "script_injector.h"
-+
-+struct HostID;
-+
-+namespace content {
-+class RenderFrame;
-+}
-+
-+namespace v8 {
-+class Value;
-+template <class T> class Local;
-+}
-+
-+namespace user_scripts {
-+struct ScriptsRunInfo;
-+
-+// A script wrapper which is aware of whether or not it is allowed to execute,
-+// and contains the implementation to do so.
-+class ScriptInjection {
-+ public:
-+  enum InjectionResult {
-+    INJECTION_FINISHED,
-+    INJECTION_BLOCKED,
-+    INJECTION_WAITING
-+  };
-+
-+  using CompletionCallback = base::OnceCallback<void(ScriptInjection*)>;
-+
-+  // Return the id of the injection host associated with the given world.
-+  static std::string GetHostIdForIsolatedWorld(int world_id);
-+
-+  // Remove the isolated world associated with the given injection host.
-+  static void RemoveIsolatedWorld(const std::string& host_id);
-+
-+  ScriptInjection(std::unique_ptr<ScriptInjector> injector,
-+                  content::RenderFrame* render_frame,
-+                  std::unique_ptr<const InjectionHost> injection_host,
-+                  UserScript::RunLocation run_location,
-+                  bool log_activity);
-+  ~ScriptInjection();
-+
-+  // Try to inject the script at the |current_location|. This returns
-+  // INJECTION_FINISHED if injection has injected or will never inject, returns
-+  // INJECTION_BLOCKED if injection is running asynchronously and has not
-+  // finished yet, returns INJECTION_WAITING if injections is delayed (either
-+  // for permission purposes or because |current_location| is not the designated
-+  // |run_location_|).
-+  // If INJECTION_BLOCKED is returned, |async_completion_callback| will be
-+  // called upon completion.
-+  InjectionResult TryToInject(
-+      UserScript::RunLocation current_location,
-+      ScriptsRunInfo* scripts_run_info,
-+      CompletionCallback async_completion_callback);
-+
-+  // Called when permission for the given injection has been granted.
-+  // Returns INJECTION_FINISHED if injection has injected or will never inject,
-+  // returns INJECTION_BLOCKED if injection is ran asynchronously.
-+  InjectionResult OnPermissionGranted(ScriptsRunInfo* scripts_run_info);
-+
-+  // Resets the pointer of the injection host when the host is gone.
-+  void OnHostRemoved();
-+
-+  void invalidate_render_frame() { render_frame_ = nullptr; }
-+
-+  // Accessors.
-+  content::RenderFrame* render_frame() const { return render_frame_; }
-+  const HostID& host_id() const { return injection_host_->id(); }
-+  int64_t request_id() const { return request_id_; }
-+
-+  // Called when JS injection for the given frame has been completed or
-+  // cancelled.
-+  void OnJsInjectionCompleted(const std::vector<v8::Local<v8::Value>>& results,
-+                              absl::optional<base::TimeDelta> elapsed);
-+
-+ private:
-+  class FrameWatcher;
-+
-+  // Sends a message to the browser to request permission to inject.
-+  void RequestPermissionFromBrowser();
-+
-+  // Injects the script. Returns INJECTION_FINISHED if injection has finished,
-+  // otherwise INJECTION_BLOCKED.
-+  InjectionResult Inject(ScriptsRunInfo* scripts_run_info);
-+
-+  // Inject any JS scripts into the frame for the injection.
-+  void InjectJs(std::set<std::string>* executing_scripts,
-+                size_t* num_injected_js_scripts);
-+
-+  // Inject any CSS source into the frame for the injection.
-+  void InjectCss(std::set<std::string>* injected_stylesheets,
-+                 size_t* num_injected_stylesheets);
-+
-+  // Notify that we will not inject, and mark it as acknowledged.
-+  void NotifyWillNotInject(ScriptInjector::InjectFailureReason reason);
-+
-+  // The injector for this injection.
-+  std::unique_ptr<ScriptInjector> injector_;
-+
-+  // The RenderFrame into which this should inject the script.
-+  content::RenderFrame* render_frame_;
-+
-+  // The associated injection host.
-+  std::unique_ptr<const InjectionHost> injection_host_;
-+
-+  // The location in the document load at which we inject the script.
-+  UserScript::RunLocation run_location_;
-+
-+  // This injection's request id. This will be -1 unless the injection is
-+  // currently waiting on permission.
-+  int64_t request_id_;
-+
-+  // Whether or not the injection is complete, either via injecting the script
-+  // or because it will never complete.
-+  bool complete_;
-+
-+  // Whether or not the injection successfully injected JS.
-+  bool did_inject_js_;
-+
-+  // Whether or not we should log dom activity for this injection.
-+  bool log_activity_;
-+
-+  // Results storage.
-+  std::unique_ptr<base::Value> execution_result_;
-+
-+  // The callback to run upon completing asynchronously.
-+  CompletionCallback async_completion_callback_;
-+
-+  // A helper class to hold the render frame and watch for its deletion.
-+  std::unique_ptr<FrameWatcher> frame_watcher_;
-+
-+  base::WeakPtrFactory<ScriptInjection> weak_ptr_factory_{this};
-+
-+  DISALLOW_COPY_AND_ASSIGN(ScriptInjection);
-+};
-+
-+}  // namespace extensions
-+
-+#endif  // USERSCRIPTS_RENDERER_SCRIPT_INJECTION_H_
-diff --git a/components/user_scripts/renderer/script_injection_callback.cc b/components/user_scripts/renderer/script_injection_callback.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/script_injection_callback.cc
-@@ -0,0 +1,25 @@
-+// Copyright 2015 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#include "script_injection_callback.h"
-+
-+#include "third_party/blink/public/platform/web_vector.h"
-+
-+namespace user_scripts {
-+
-+ScriptInjectionCallback::ScriptInjectionCallback(
-+    CompleteCallback injection_completed_callback)
-+    : injection_completed_callback_(std::move(injection_completed_callback)) {}
-+
-+ScriptInjectionCallback::~ScriptInjectionCallback() {
-+}
-+
-+void ScriptInjectionCallback::Completed(
-+    const blink::WebVector<v8::Local<v8::Value>>& result) {
-+  std::vector<v8::Local<v8::Value>> stl_result(result.begin(), result.end());
-+  std::move(injection_completed_callback_).Run(stl_result);
-+  delete this;
-+}
-+
-+}  // namespace extensions
-diff --git a/components/user_scripts/renderer/script_injection_callback.h b/components/user_scripts/renderer/script_injection_callback.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/script_injection_callback.h
-@@ -0,0 +1,39 @@
-+// Copyright 2015 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#ifndef USERSCRIPTS_RENDERER_SCRIPT_INJECTION_CALLBACK_H_
-+#define USERSCRIPTS_RENDERER_SCRIPT_INJECTION_CALLBACK_H_
-+
-+#include <vector>
-+
-+#include "base/callback.h"
-+#include "base/macros.h"
-+#include "third_party/blink/public/web/web_script_execution_callback.h"
-+#include "v8/include/v8.h"
-+
-+namespace user_scripts {
-+
-+// A wrapper around a callback to notify a script injection when injection
-+// completes.
-+// This class manages its own lifetime.
-+class ScriptInjectionCallback : public blink::WebScriptExecutionCallback {
-+ public:
-+  using CompleteCallback =
-+      base::OnceCallback<void(const std::vector<v8::Local<v8::Value>>& result)>;
-+
-+  explicit ScriptInjectionCallback(
-+      CompleteCallback injection_completed_callback);
-+  ~ScriptInjectionCallback() override;
-+
-+  void Completed(const blink::WebVector<v8::Local<v8::Value>>& result) override;
-+
-+ private:
-+  CompleteCallback injection_completed_callback_;
-+
-+  DISALLOW_COPY_AND_ASSIGN(ScriptInjectionCallback);
-+};
-+
-+}  // namespace extensions
-+
-+#endif  // USERSCRIPTS_RENDERER_SCRIPT_INJECTION_CALLBACK_H_
-diff --git a/components/user_scripts/renderer/script_injection_manager.cc b/components/user_scripts/renderer/script_injection_manager.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/script_injection_manager.cc
-@@ -0,0 +1,417 @@
-+// Copyright 2014 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#include "script_injection_manager.h"
-+
-+#include <memory>
-+#include <utility>
-+
-+#include "base/auto_reset.h"
-+#include "base/bind.h"
-+#include "base/feature_list.h"
-+#include "base/memory/weak_ptr.h"
-+#include "base/threading/thread_task_runner_handle.h"
-+#include "base/values.h"
-+#include "base/logging.h"
-+#include "content/public/renderer/render_frame.h"
-+#include "content/public/renderer/render_frame_observer.h"
-+#include "content/public/renderer/render_thread.h"
-+#include "extension_frame_helper.h"
-+#include "../common/host_id.h"
-+#include "script_injection.h"
-+#include "scripts_run_info.h"
-+#include "web_ui_injection_host.h"
-+#include "ipc/ipc_message_macros.h"
-+#include "third_party/blink/public/platform/web_url_error.h"
-+#include "third_party/blink/public/web/web_document.h"
-+#include "third_party/blink/public/web/web_frame.h"
-+#include "third_party/blink/public/web/web_local_frame.h"
-+#include "third_party/blink/public/web/web_view.h"
-+#include "url/gurl.h"
-+#include "../common/user_scripts_features.h"
-+
-+namespace user_scripts {
-+
-+namespace {
-+
-+// The length of time to wait after the DOM is complete to try and run user
-+// scripts.
-+const int kScriptIdleTimeoutInMs = 200;
-+
-+// Returns the RunLocation that follows |run_location|.
-+UserScript::RunLocation NextRunLocation(UserScript::RunLocation run_location) {
-+  switch (run_location) {
-+    case UserScript::DOCUMENT_START:
-+      return UserScript::DOCUMENT_END;
-+    case UserScript::DOCUMENT_END:
-+      return UserScript::DOCUMENT_IDLE;
-+    case UserScript::DOCUMENT_IDLE:
-+      return UserScript::RUN_LOCATION_LAST;
-+    case UserScript::UNDEFINED:
-+    case UserScript::RUN_DEFERRED:
-+    case UserScript::BROWSER_DRIVEN:
-+    case UserScript::RUN_LOCATION_LAST:
-+      break;
-+  }
-+  NOTREACHED();
-+  return UserScript::RUN_LOCATION_LAST;
-+}
-+
-+}  // namespace
-+
-+class ScriptInjectionManager::RFOHelper : public content::RenderFrameObserver {
-+ public:
-+  RFOHelper(content::RenderFrame* render_frame,
-+            ScriptInjectionManager* manager);
-+  ~RFOHelper() override;
-+
-+  // commit @9f2aac4
-+  void Initialize();
-+
-+ private:
-+  // RenderFrameObserver implementation.
-+  void DidCreateNewDocument() override;
-+  void DidCreateDocumentElement() override;
-+  void DidFailProvisionalLoad() override;
-+  void DidDispatchDOMContentLoadedEvent() override;
-+  void WillDetach() override;
-+  void OnDestruct() override;
-+  void OnStop() override;
-+
-+  // Tells the ScriptInjectionManager to run tasks associated with
-+  // document_idle.
-+  void RunIdle();
-+
-+  void StartInjectScripts(UserScript::RunLocation run_location);
-+
-+  // Indicate that the frame is no longer valid because it is starting
-+  // a new load or closing.
-+  void InvalidateAndResetFrame(bool force_reset);
-+
-+  // The owning ScriptInjectionManager.
-+  ScriptInjectionManager* manager_;
-+
-+  bool should_run_idle_ = true; // commit @9f2aac4
-+
-+  base::WeakPtrFactory<RFOHelper> weak_factory_{this};
-+};
-+
-+ScriptInjectionManager::RFOHelper::RFOHelper(content::RenderFrame* render_frame,
-+                                             ScriptInjectionManager* manager)
-+    : content::RenderFrameObserver(render_frame),
-+      manager_(manager),
-+      should_run_idle_(true) {}
-+
-+ScriptInjectionManager::RFOHelper::~RFOHelper() {
-+}
-+
-+
-+void ScriptInjectionManager::RFOHelper::Initialize() {
-+  // Set up for the initial empty document, for which the Document created
-+  // events do not happen as it's already present.
-+  DidCreateNewDocument();
-+  // The initial empty document for a main frame may have scripts attached to it
-+  // but we do not want to invalidate the frame and lose them when the next
-+  // document loads. For example the IncognitoApiTest.IncognitoSplitMode test
-+  // does `chrome.tabs.create()` with a script to be run, which is added to the
-+  // frame before it navigates, so it needs to be preserved. However scripts in
-+  // child frames are expected to be run inside the initial empty document. For
-+  // example the ExecuteScriptApiTest.FrameWithHttp204 test creates a child
-+  // frame at about:blank and expects to run injected scripts inside it.
-+  // This is all quite inconsistent however tests both depend on us queuing and
-+  // not queueing the DOCUMENT_START events in the initial empty document.
-+  if (!render_frame()->IsMainFrame()) {
-+    DidCreateDocumentElement();
-+  }
-+}
-+
-+void ScriptInjectionManager::RFOHelper::DidCreateNewDocument() {
-+  // A new document is going to be shown, so invalidate the old document state.
-+  // Don't force-reset the frame, because it is possible that a script injection
-+  // was scheduled before the page was loaded, e.g. by navigating to a
-+  // javascript: URL before the page has loaded.
-+  constexpr bool kForceReset = false;
-+  InvalidateAndResetFrame(kForceReset);
-+}
-+
-+void ScriptInjectionManager::RFOHelper::DidCreateDocumentElement() {
-+  if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+    LOG(INFO) << "UserScripts: DidCreateDocumentElement -> DOCUMENT_START";
-+
-+  ExtensionFrameHelper::Get(render_frame())
-+      ->ScheduleAtDocumentStart(
-+          base::BindOnce(&ScriptInjectionManager::RFOHelper::StartInjectScripts,
-+                     weak_factory_.GetWeakPtr(), UserScript::DOCUMENT_START));
-+}
-+
-+void ScriptInjectionManager::RFOHelper::DidFailProvisionalLoad() {
-+  auto it = manager_->frame_statuses_.find(render_frame());
-+  if (it != manager_->frame_statuses_.end() &&
-+      it->second == UserScript::DOCUMENT_START) {
-+    // Since the provisional load failed, the frame stays at its previous loaded
-+    // state and origin (or the parent's origin for new/about:blank frames).
-+    // Reset the frame to DOCUMENT_IDLE in order to reflect that the frame is
-+    // done loading, and avoid any deadlock in the system.
-+    //
-+    // We skip injection of DOCUMENT_END and DOCUMENT_IDLE scripts, because the
-+    // injections closely follow the DOMContentLoaded (and onload) events, which
-+    // are not triggered after a failed provisional load.
-+    // This assumption is verified in the checkDOMContentLoadedEvent subtest of
-+    // ExecuteScriptApiTest.FrameWithHttp204 (browser_tests).
-+    constexpr bool kForceReset = true;
-+    InvalidateAndResetFrame(kForceReset);
-+    should_run_idle_ = false;
-+    manager_->frame_statuses_[render_frame()] = UserScript::DOCUMENT_IDLE;
-+  }
-+}
-+
-+void ScriptInjectionManager::RFOHelper::DidDispatchDOMContentLoadedEvent() {
-+  if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+    LOG(INFO) << "UserScripts: DidDispatchDOMContentLoadedEvent -> DOCUMENT_END";
-+
-+  DCHECK(content::RenderThread::Get());
-+  ExtensionFrameHelper::Get(render_frame())
-+      ->ScheduleAtDocumentEnd(
-+          base::BindOnce(&ScriptInjectionManager::RFOHelper::StartInjectScripts,
-+                     weak_factory_.GetWeakPtr(), UserScript::DOCUMENT_END));
-+
-+  // We try to run idle in two places: a delayed task here and in response to
-+  // ContentRendererClient::RunScriptsAtDocumentIdle(). DidDispatchDOMContentLoadedEvent()
-+  // corresponds to completing the document's load, whereas
-+  // RunScriptsAtDocumentIdle() corresponds to completing the document and all
-+  // subresources' load (but before the window.onload event). We don't want to
-+  // hold up script injection for a particularly slow subresource, so we set a
-+  // delayed task from here - but if we finish everything before that point
-+  // (i.e., RunScriptsAtDocumentIdle() is triggered), then there's no reason to
-+  // keep waiting.
-+  render_frame()
-+      ->GetTaskRunner(blink::TaskType::kInternalDefault)
-+      ->PostDelayedTask(
-+          FROM_HERE,
-+          base::BindOnce(&ScriptInjectionManager::RFOHelper::RunIdle,
-+                         weak_factory_.GetWeakPtr()),
-+          base::TimeDelta::FromMilliseconds(kScriptIdleTimeoutInMs));
-+
-+  ExtensionFrameHelper::Get(render_frame())
-+      ->ScheduleAtDocumentIdle(
-+          base::BindOnce(&ScriptInjectionManager::RFOHelper::RunIdle,
-+                     weak_factory_.GetWeakPtr()));
-+}
-+
-+void ScriptInjectionManager::RFOHelper::WillDetach() {
-+  // The frame is closing - invalidate.
-+  constexpr bool kForceReset = true;
-+  InvalidateAndResetFrame(kForceReset);
-+}
-+
-+void ScriptInjectionManager::RFOHelper::OnDestruct() {
-+  manager_->RemoveObserver(this);
-+}
-+
-+void ScriptInjectionManager::RFOHelper::OnStop() {
-+  // If the navigation request fails (e.g. 204/205/downloads), notify the
-+  // extension to avoid keeping the frame in a START state indefinitely which
-+  // leads to deadlocks.
-+  DidFailProvisionalLoad();
-+}
-+
-+void ScriptInjectionManager::RFOHelper::RunIdle() {
-+  // Only notify the manager if the frame hasn't already had idle run since the
-+  // task to RunIdle() was posted.
-+  if (should_run_idle_) {
-+    should_run_idle_ = false;
-+    if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+      LOG(INFO) << "UserScripts: RunIdle -> DOCUMENT_IDLE";
-+    manager_->StartInjectScripts(render_frame(), UserScript::DOCUMENT_IDLE);
-+  }
-+}
-+
-+void ScriptInjectionManager::RFOHelper::StartInjectScripts(
-+    UserScript::RunLocation run_location) {
-+  manager_->StartInjectScripts(render_frame(), run_location);
-+}
-+
-+void ScriptInjectionManager::RFOHelper::InvalidateAndResetFrame(
-+    bool force_reset) {
-+  // Invalidate any pending idle injections, and reset the frame inject on idle.
-+  weak_factory_.InvalidateWeakPtrs();
-+  // We reset to inject on idle, because the frame can be reused (in the case of
-+  // navigation).
-+  should_run_idle_ = true;
-+
-+  // Reset the frame if either |force_reset| is true, or if the manager is
-+  // keeping track of the state of the frame (in which case we need to clean it
-+  // up).
-+  if (force_reset || manager_->frame_statuses_.count(render_frame()) != 0)
-+    manager_->InvalidateForFrame(render_frame());
-+}
-+
-+ScriptInjectionManager::ScriptInjectionManager(
-+    UserScriptSetManager* user_script_set_manager)
-+    : user_script_set_manager_(user_script_set_manager),
-+      user_script_set_manager_observation_(this) {
-+  user_script_set_manager_observation_.Observe(user_script_set_manager_);
-+}
-+
-+ScriptInjectionManager::~ScriptInjectionManager() {
-+  for (const auto& injection : pending_injections_)
-+    injection->invalidate_render_frame();
-+  for (const auto& injection : running_injections_)
-+    injection->invalidate_render_frame();
-+}
-+
-+void ScriptInjectionManager::OnRenderFrameCreated(
-+    content::RenderFrame* render_frame) {
-+  rfo_helpers_.push_back(std::make_unique<RFOHelper>(render_frame, this));
-+  rfo_helpers_.back()->Initialize(); // commit @9f2aac4
-+}
-+
-+void ScriptInjectionManager::OnInjectionFinished(
-+    ScriptInjection* injection) {
-+  auto iter =
-+      std::find_if(running_injections_.begin(), running_injections_.end(),
-+                   [injection](const std::unique_ptr<ScriptInjection>& mode) {
-+                     return injection == mode.get();
-+                   });
-+  if (iter != running_injections_.end())
-+    running_injections_.erase(iter);
-+}
-+
-+void ScriptInjectionManager::OnUserScriptsUpdated(
-+    const std::set<HostID>& changed_hosts) {
-+  for (auto iter = pending_injections_.begin();
-+       iter != pending_injections_.end();) {
-+    if (changed_hosts.count((*iter)->host_id()) > 0)
-+      iter = pending_injections_.erase(iter);
-+    else
-+      ++iter;
-+  }
-+}
-+
-+void ScriptInjectionManager::RemoveObserver(RFOHelper* helper) {
-+  for (auto iter = rfo_helpers_.begin(); iter != rfo_helpers_.end(); ++iter) {
-+    if (iter->get() == helper) {
-+      rfo_helpers_.erase(iter);
-+      break;
-+    }
-+  }
-+}
-+
-+void ScriptInjectionManager::InvalidateForFrame(content::RenderFrame* frame) {
-+  // If the frame invalidated is the frame being injected into, we need to
-+  // note it.
-+  active_injection_frames_.erase(frame);
-+
-+  for (auto iter = pending_injections_.begin();
-+       iter != pending_injections_.end();) {
-+    if ((*iter)->render_frame() == frame)
-+      iter = pending_injections_.erase(iter);
-+    else
-+      ++iter;
-+  }
-+
-+  frame_statuses_.erase(frame);
-+}
-+
-+void ScriptInjectionManager::StartInjectScripts(
-+    content::RenderFrame* frame,
-+    UserScript::RunLocation run_location) {
-+  auto iter = frame_statuses_.find(frame);
-+  // We also don't execute if we detect that the run location is somehow out of
-+  // order. This can happen if:
-+  // - The first run location reported for the frame isn't DOCUMENT_START, or
-+  // - The run location reported doesn't immediately follow the previous
-+  //   reported run location.
-+  // We don't want to run because extensions may have requirements that scripts
-+  // running in an earlier run location have run by the time a later script
-+  // runs. Better to just not run.
-+  // Note that we check run_location > NextRunLocation() in the second clause
-+  // (as opposed to !=) because earlier signals (like DidCreateDocumentElement)
-+  // can happen multiple times, so we can receive earlier/equal run locations.
-+  if ((iter == frame_statuses_.end() &&
-+           run_location != UserScript::DOCUMENT_START) ||
-+      (iter != frame_statuses_.end() &&
-+           run_location > NextRunLocation(iter->second))) {
-+    // We also invalidate the frame, because the run order of pending injections
-+    // may also be bad.
-+    InvalidateForFrame(frame);
-+    return;
-+  } else if (iter != frame_statuses_.end() && iter->second >= run_location) {
-+    // Certain run location signals (like DidCreateDocumentElement) can happen
-+    // multiple times. Ignore the subsequent signals.
-+    return;
-+  }
-+
-+  // Otherwise, all is right in the world, and we can get on with the
-+  // injections!
-+  frame_statuses_[frame] = run_location;
-+  InjectScripts(frame, run_location);
-+}
-+
-+void ScriptInjectionManager::InjectScripts(
-+    content::RenderFrame* frame,
-+    UserScript::RunLocation run_location) {
-+  // Find any injections that want to run on the given frame.
-+  ScriptInjectionVector frame_injections;
-+  for (auto iter = pending_injections_.begin();
-+       iter != pending_injections_.end();) {
-+    if ((*iter)->render_frame() == frame) {
-+      frame_injections.push_back(std::move(*iter));
-+      iter = pending_injections_.erase(iter);
-+    } else {
-+      ++iter;
-+    }
-+  }
-+
-+  // Add any injections for user scripts.
-+  int tab_id = ExtensionFrameHelper::Get(frame)->tab_id();
-+  user_script_set_manager_->GetAllInjections(&frame_injections, frame, tab_id,
-+                                             run_location);
-+
-+  // Note that we are running in |frame|.
-+  active_injection_frames_.insert(frame);
-+
-+  ScriptsRunInfo scripts_run_info(frame, run_location);
-+
-+  for (auto iter = frame_injections.begin(); iter != frame_injections.end();) {
-+    // It's possible for thScriptsRunInfoe frame to be invalidated in the course of injection
-+    // (if a script removes its own frame, for example). If this happens, abort.
-+    if (!active_injection_frames_.count(frame))
-+      break;
-+    std::unique_ptr<ScriptInjection> injection(std::move(*iter));
-+    iter = frame_injections.erase(iter);
-+    TryToInject(std::move(injection), run_location, &scripts_run_info);
-+  }
-+
-+  // We are done running in the frame.
-+  active_injection_frames_.erase(frame);
-+
-+  scripts_run_info.LogRun(activity_logging_enabled_);
-+}
-+
-+void ScriptInjectionManager::TryToInject(
-+    std::unique_ptr<ScriptInjection> injection,
-+    UserScript::RunLocation run_location,
-+    ScriptsRunInfo* scripts_run_info) {
-+  // Try to inject the script. If the injection is waiting (i.e., for
-+  // permission), add it to the list of pending injections. If the injection
-+  // has blocked, add it to the list of running injections.
-+  // The Unretained below is safe because this object owns all the
-+  // ScriptInjections, so is guaranteed to outlive them.
-+  switch (injection->TryToInject(
-+      run_location, scripts_run_info,
-+      base::BindOnce(&ScriptInjectionManager::OnInjectionFinished,
-+                 base::Unretained(this)))) {
-+    case ScriptInjection::INJECTION_WAITING:
-+      pending_injections_.push_back(std::move(injection));
-+      break;
-+    case ScriptInjection::INJECTION_BLOCKED:
-+      running_injections_.push_back(std::move(injection));
-+      break;
-+    case ScriptInjection::INJECTION_FINISHED:
-+      break;
-+  }
-+}
-+
-+}  // namespace extensions
-diff --git a/components/user_scripts/renderer/script_injection_manager.h b/components/user_scripts/renderer/script_injection_manager.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/script_injection_manager.h
-@@ -0,0 +1,102 @@
-+#include <stdint.h>
-+
-+#include <map>
-+#include <set>
-+#include <string>
-+#include <vector>
-+
-+#include "base/callback.h"
-+#include "base/macros.h"
-+#include "base/scoped_observation.h"
-+#include "../common/user_script.h"
-+#include "script_injection.h"
-+#include "user_script_set_manager.h"
-+
-+namespace user_scripts {
-+
-+// The ScriptInjectionManager manages extensions injecting scripts into frames
-+// via both content/user scripts and tabs.executeScript(). It is responsible for
-+// maintaining any pending injections awaiting permission or the appropriate
-+// load point, and injecting them when ready.
-+class ScriptInjectionManager : public UserScriptSetManager::Observer {
-+ public:
-+  explicit ScriptInjectionManager(
-+      UserScriptSetManager* user_script_set_manager);
-+  virtual ~ScriptInjectionManager();
-+
-+  // Notifies that a new render view has been created.
-+  void OnRenderFrameCreated(content::RenderFrame* render_frame);
-+
-+  // Removes pending injections of the unloaded extension.
-+  //void OnExtensionUnloaded(const std::string& extension_id);
-+
-+  void set_activity_logging_enabled(bool enabled) {
-+    activity_logging_enabled_ = enabled;
-+  }
-+
-+ private:
-+  // A RenderFrameObserver implementation which watches the various render
-+  // frames in order to notify the ScriptInjectionManager of different
-+  // document load states and IPCs.
-+  class RFOHelper;
-+
-+  using FrameStatusMap =
-+      std::map<content::RenderFrame*, UserScript::RunLocation>;
-+
-+  using ScriptInjectionVector = std::vector<std::unique_ptr<ScriptInjection>>;
-+
-+  // Notifies that an injection has been finished.
-+  void OnInjectionFinished(ScriptInjection* injection);
-+
-+  // UserScriptSetManager::Observer implementation.
-+  void OnUserScriptsUpdated(const std::set<HostID>& changed_hosts) override;
-+
-+  // Notifies that an RFOHelper should be removed.
-+  void RemoveObserver(RFOHelper* helper);
-+
-+  // Invalidate any pending tasks associated with |frame|.
-+  void InvalidateForFrame(content::RenderFrame* frame);
-+
-+  // Starts the process to inject appropriate scripts into |frame|.
-+  void StartInjectScripts(content::RenderFrame* frame,
-+                          UserScript::RunLocation run_location);
-+
-+  // Actually injects the scripts into |frame|.
-+  void InjectScripts(content::RenderFrame* frame,
-+                     UserScript::RunLocation run_location);
-+
-+  // Try to inject and store injection if it has not finished.
-+  void TryToInject(std::unique_ptr<ScriptInjection> injection,
-+                   UserScript::RunLocation run_location,
-+                   ScriptsRunInfo* scripts_run_info);
-+
-+  // The map of active web frames to their corresponding statuses. The
-+  // RunLocation of the frame corresponds to the last location that has ran.
-+  FrameStatusMap frame_statuses_;
-+
-+  // The frames currently being injected into, so long as that frame is valid.
-+  std::set<content::RenderFrame*> active_injection_frames_;
-+
-+  // The collection of RFOHelpers.
-+  std::vector<std::unique_ptr<RFOHelper>> rfo_helpers_;
-+
-+  // The set of UserScripts associated with extensions. Owned by the Dispatcher.
-+  UserScriptSetManager* user_script_set_manager_;
-+
-+  // Pending injections which are waiting for either the proper run location or
-+  // user consent.
-+  ScriptInjectionVector pending_injections_;
-+
-+  // Running injections which are waiting for async callbacks from blink.
-+  ScriptInjectionVector running_injections_;
-+
-+  // Whether or not dom activity should be logged for scripts injected.
-+  bool activity_logging_enabled_ = false;
-+
-+  base::ScopedObservation<UserScriptSetManager, UserScriptSetManager::Observer>
-+      user_script_set_manager_observation_{this};
-+
-+  DISALLOW_COPY_AND_ASSIGN(ScriptInjectionManager);
-+};
-+
-+}
-diff --git a/components/user_scripts/renderer/script_injector.h b/components/user_scripts/renderer/script_injector.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/script_injector.h
-@@ -0,0 +1,96 @@
-+// Copyright 2014 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#ifndef USERSCRIPTS_RENDERER_SCRIPT_INJECTOR_H_
-+#define USERSCRIPTS_RENDERER_SCRIPT_INJECTOR_H_
-+
-+#include <memory>
-+#include <vector>
-+
-+#include "../common/constants.h"
-+#include "../common/user_script.h"
-+#include "third_party/blink/public/web/web_script_source.h"
-+
-+class InjectionHost;
-+
-+namespace blink {
-+class WebLocalFrame;
-+}
-+
-+namespace user_scripts {
-+
-+// The pseudo-delegate class for a ScriptInjection that provides all necessary
-+// information about how to inject the script, including what code to inject and
-+// when (run location), but without any injection logic.
-+class ScriptInjector {
-+ public:
-+  // The possible reasons for not injecting the script.
-+  enum InjectFailureReason {
-+    EXTENSION_REMOVED,  // The extension was removed before injection.
-+    NOT_ALLOWED,        // The script is not allowed to inject.
-+    WONT_INJECT         // The injection won't inject because the user rejected
-+                        // (or just did not accept) the injection.
-+  };
-+
-+  virtual ~ScriptInjector() {}
-+
-+  // Returns the script type of this particular injection.
-+  virtual UserScript::InjectionType script_type() const = 0;
-+
-+  // Returns true if the script is running inside a user gesture.
-+  virtual bool IsUserGesture() const = 0;
-+
-+  // Returns the CSS origin of this injection.
-+  virtual absl::optional<CSSOrigin> GetCssOrigin() const = 0;
-+
-+  // Returns the key for this injection, if it's a CSS injection.
-+  virtual const absl::optional<std::string> GetInjectionKey() const = 0;
-+
-+  // Returns true if the script expects results.
-+  virtual bool ExpectsResults() const = 0;
-+
-+  // Returns true if the script should inject JS source at the given
-+  // |run_location|.
-+  virtual bool ShouldInjectJs(
-+      UserScript::RunLocation run_location,
-+      const std::set<std::string>& executing_scripts) const = 0;
-+
-+  // Returns true if the script should inject CSS at the given |run_location|.
-+  virtual bool ShouldInjectCss(
-+      UserScript::RunLocation run_location,
-+      const std::set<std::string>& injected_stylesheets) const = 0;
-+
-+  // Returns the javascript sources to inject at the given |run_location|.
-+  // Only called if ShouldInjectJs() is true.
-+  virtual std::vector<blink::WebScriptSource> GetJsSources(
-+      UserScript::RunLocation run_location,
-+      std::set<std::string>* executing_scripts,
-+      size_t* num_injected_js_scripts) const = 0;
-+
-+  // Returns the css to inject at the given |run_location|.
-+  // Only called if ShouldInjectCss() is true.
-+  virtual std::vector<blink::WebString> GetCssSources(
-+      UserScript::RunLocation run_location,
-+      std::set<std::string>* injected_stylesheets,
-+      size_t* num_injected_stylesheets) const = 0;
-+
-+  // Notifies the script that injection has completed, with a possibly-populated
-+  // list of results (depending on whether or not ExpectsResults() was true).
-+  // |render_frame| contains the render frame, or null if the frame was
-+  // invalidated.
-+  virtual void OnInjectionComplete(
-+      std::unique_ptr<base::Value> execution_result,
-+      UserScript::RunLocation run_location,
-+      content::RenderFrame* render_frame) = 0;
-+
-+  // Notifies the script that injection will never occur.
-+  // |render_frame| contains the render frame, or null if the frame was
-+  // invalidated.
-+  virtual void OnWillNotInject(InjectFailureReason reason,
-+                               content::RenderFrame* render_frame) = 0;
-+};
-+
-+}  // namespace extensions
-+
-+#endif  // USERSCRIPTS_RENDERER_SCRIPT_INJECTOR_H_
-diff --git a/components/user_scripts/renderer/scripts_run_info.cc b/components/user_scripts/renderer/scripts_run_info.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/scripts_run_info.cc
-@@ -0,0 +1,31 @@
-+// Copyright 2014 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#include "scripts_run_info.h"
-+
-+#include "base/metrics/histogram_macros.h"
-+#include "content/public/renderer/render_frame.h"
-+#include "content/public/renderer/render_thread.h"
-+#include "script_context.h"
-+#include "third_party/blink/public/web/web_local_frame.h"
-+
-+namespace user_scripts {
-+
-+ScriptsRunInfo::ScriptsRunInfo(content::RenderFrame* render_frame,
-+                               UserScript::RunLocation location)
-+    : num_css(0u),
-+      num_js(0u),
-+      num_blocking_js(0u),
-+      routing_id_(render_frame->GetRoutingID()),
-+      run_location_(location),
-+      frame_url_(ScriptContext::GetDocumentLoaderURLForFrame(
-+          render_frame->GetWebFrame())) {}
-+
-+ScriptsRunInfo::~ScriptsRunInfo() {
-+}
-+
-+void ScriptsRunInfo::LogRun(bool send_script_activity) {
-+}
-+
-+}  // namespace extensions
-diff --git a/components/user_scripts/renderer/scripts_run_info.h b/components/user_scripts/renderer/scripts_run_info.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/scripts_run_info.h
-@@ -0,0 +1,70 @@
-+// Copyright 2014 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#ifndef USERSCRIPTS_RENDERER_SCRIPTS_RUN_INFO_H_
-+#define USERSCRIPTS_RENDERER_SCRIPTS_RUN_INFO_H_
-+
-+#include <stddef.h>
-+
-+#include <map>
-+#include <set>
-+#include <string>
-+
-+#include "base/macros.h"
-+#include "base/timer/elapsed_timer.h"
-+#include "../common/user_script.h"
-+
-+namespace content {
-+class RenderFrame;
-+}
-+
-+namespace user_scripts {
-+
-+// A struct containing information about a script run.
-+struct ScriptsRunInfo {
-+  // Map of extensions IDs to the executing script paths.
-+  typedef std::map<std::string, std::set<std::string> > ExecutingScriptsMap;
-+
-+  ScriptsRunInfo(content::RenderFrame* render_frame,
-+                 UserScript::RunLocation location);
-+  ~ScriptsRunInfo();
-+
-+  // The number of CSS scripts injected.
-+  size_t num_css;
-+  // The number of JS scripts injected.
-+  size_t num_js;
-+  // The number of blocked JS scripts injected.
-+  size_t num_blocking_js;
-+  // A map of extension ids to executing script paths.
-+  ExecutingScriptsMap executing_scripts;
-+  // A map of extension ids to injected stylesheet paths.
-+  ExecutingScriptsMap injected_stylesheets;
-+  // The elapsed time since the ScriptsRunInfo was constructed.
-+  base::ElapsedTimer timer;
-+
-+  // Log information about a given script run. If |send_script_activity| is
-+  // true, this also informs the browser of the script run.
-+  void LogRun(bool send_script_activity);
-+
-+  static void LogLongInjectionTaskTime(UserScript::RunLocation run_location,
-+                                       const base::TimeDelta& elapsed);
-+
-+ private:
-+  // The routinig id to use to notify the browser of any injections. Since the
-+  // frame may be deleted in injection, we don't hold on to a reference to it
-+  // directly.
-+  int routing_id_;
-+
-+  // The run location at which injection is happening.
-+  UserScript::RunLocation run_location_;
-+
-+  // The url of the frame, preserved for the same reason as the routing id.
-+  GURL frame_url_;
-+
-+  DISALLOW_COPY_AND_ASSIGN(ScriptsRunInfo);
-+};
-+
-+}  // namespace extensions
-+
-+#endif  // USERSCRIPTS_RENDERER_SCRIPTS_RUN_INFO_H_
-diff --git a/components/user_scripts/renderer/user_script_injector.cc b/components/user_scripts/renderer/user_script_injector.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/user_script_injector.cc
-@@ -0,0 +1,228 @@
-+// Copyright 2014 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#include "user_script_injector.h"
-+
-+#include <tuple>
-+#include <vector>
-+
-+#include "base/logging.h"
-+#include "base/lazy_instance.h"
-+#include "content/public/common/url_constants.h"
-+#include "content/public/renderer/render_frame.h"
-+#include "content/public/renderer/render_thread.h"
-+#include "content/public/renderer/render_view.h"
-+#include "components/user_scripts/renderer/grit/user_scripts_renderer_resources.h"
-+#include "injection_host.h"
-+#include "script_context.h"
-+#include "scripts_run_info.h"
-+#include "third_party/blink/public/web/web_document.h"
-+#include "third_party/blink/public/web/web_local_frame.h"
-+#include "third_party/blink/public/web/web_script_source.h"
-+#include "ui/base/resource/resource_bundle.h"
-+#include "url/gurl.h"
-+
-+namespace user_scripts {
-+
-+namespace {
-+
-+struct RoutingInfoKey {
-+  int routing_id;
-+  int script_id;
-+
-+  RoutingInfoKey(int routing_id, int script_id)
-+      : routing_id(routing_id), script_id(script_id) {}
-+
-+  bool operator<(const RoutingInfoKey& other) const {
-+    return std::tie(routing_id, script_id) <
-+           std::tie(other.routing_id, other.script_id);
-+  }
-+};
-+
-+using RoutingInfoMap = std::map<RoutingInfoKey, bool>;
-+
-+// A map records whether a given |script_id| from a webview-added user script
-+// is allowed to inject on the render of given |routing_id|.
-+// Once a script is added, the decision of whether or not allowed to inject
-+// won't be changed.
-+// After removed by the webview, the user scipt will also be removed
-+// from the render. Therefore, there won't be any query from the same
-+// |script_id| and |routing_id| pair.
-+// base::LazyInstance<RoutingInfoMap>::DestructorAtExit g_routing_info_map =
-+//    LAZY_INSTANCE_INITIALIZER;
-+
-+// Greasemonkey API source that is injected with the scripts.
-+struct GreasemonkeyApiJsString {
-+  GreasemonkeyApiJsString();
-+  blink::WebScriptSource GetSource() const;
-+
-+ private:
-+  blink::WebString source_;
-+};
-+
-+// The below constructor, monstrous as it is, just makes a WebScriptSource from
-+// the GreasemonkeyApiJs resource.
-+GreasemonkeyApiJsString::GreasemonkeyApiJsString() {
-+  std::string greasemonky_api_js(
-+      ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
-+          IDR_GREASEMONKEY_API_JS));
-+  source_ = blink::WebString::FromUTF8(greasemonky_api_js);
-+}
-+
-+blink::WebScriptSource GreasemonkeyApiJsString::GetSource() const {
-+  return blink::WebScriptSource(source_);
-+}
-+
-+base::LazyInstance<GreasemonkeyApiJsString>::Leaky g_greasemonkey_api =
-+    LAZY_INSTANCE_INITIALIZER;
-+
-+bool ShouldInjectScripts(const UserScript::FileList& scripts,
-+                         const std::set<std::string>& injected_files) {
-+  for (const std::unique_ptr<UserScript::File>& file : scripts) {
-+    // Check if the script is already injected.
-+    if (injected_files.count(file->url().path()) == 0) {
-+      return true;
-+    }
-+  }
-+  return false;
-+}
-+
-+}  // namespace
-+
-+UserScriptInjector::UserScriptInjector(const UserScript* script,
-+                                       UserScriptSet* script_list)
-+    : script_(script),
-+      user_script_set_(script_list),
-+      script_id_(script_->id()),
-+      user_script_set_observer_(this) {
-+  user_script_set_observer_.Observe(script_list);
-+}
-+
-+UserScriptInjector::~UserScriptInjector() {
-+}
-+
-+void UserScriptInjector::OnUserScriptsUpdated(
-+    const std::set<HostID>& changed_hosts,
-+    const UserScriptList& scripts) {
-+  // When user scripts are updated, all the old script pointers are invalidated.
-+  script_ = nullptr;
-+  // If the host causing this injection changed, then this injection
-+  // will be removed, and there's no guarantee the backing script still exists.
-+  // if (changed_hosts.count(host_id_) > 0)
-+  //   return;
-+
-+  for (const std::unique_ptr<UserScript>& script : scripts) {
-+    if (script->id() == script_id_) {
-+      script_ = script.get();
-+      break;
-+    }
-+  }
-+  // If |host_id_| wasn't in |changed_hosts|, then the script for this injection
-+  // should be guaranteed to exist.
-+  DCHECK(script_);
-+}
-+
-+UserScript::InjectionType UserScriptInjector::script_type() const {
-+  return UserScript::CONTENT_SCRIPT;
-+}
-+
-+bool UserScriptInjector::IsUserGesture() const {
-+  return false;
-+}
-+
-+bool UserScriptInjector::ExpectsResults() const {
-+  return false;
-+}
-+
-+absl::optional<CSSOrigin> UserScriptInjector::GetCssOrigin() const {
-+  return absl::nullopt;
-+}
-+
-+const absl::optional<std::string> UserScriptInjector::GetInjectionKey() const {
-+  return absl::nullopt;
-+}
-+
-+bool UserScriptInjector::ShouldInjectJs(
-+    UserScript::RunLocation run_location,
-+    const std::set<std::string>& executing_scripts) const {
-+  return script_ && script_->run_location() == run_location &&
-+         !script_->js_scripts().empty() &&
-+         ShouldInjectScripts(script_->js_scripts(), executing_scripts);
-+}
-+
-+bool UserScriptInjector::ShouldInjectCss(
-+    UserScript::RunLocation run_location,
-+    const std::set<std::string>& injected_stylesheets) const {
-+  return script_ && run_location == UserScript::DOCUMENT_START &&
-+         !script_->css_scripts().empty() &&
-+         ShouldInjectScripts(script_->css_scripts(), injected_stylesheets);
-+}
-+
-+std::vector<blink::WebScriptSource> UserScriptInjector::GetJsSources(
-+    UserScript::RunLocation run_location,
-+    std::set<std::string>* executing_scripts,
-+    size_t* num_injected_js_scripts) const {
-+  DCHECK(script_);
-+  std::vector<blink::WebScriptSource> sources;
-+
-+  DCHECK_EQ(script_->run_location(), run_location);
-+
-+  const UserScript::FileList& js_scripts = script_->js_scripts();
-+  sources.reserve(js_scripts.size() +
-+                  (script_->emulate_greasemonkey() ? 1 : 0));
-+  // Emulate Greasemonkey API for scripts that were converted to extension
-+  // user scripts.
-+  if (script_->emulate_greasemonkey())
-+    sources.push_back(g_greasemonkey_api.Get().GetSource());
-+  for (const std::unique_ptr<UserScript::File>& file : js_scripts) {
-+    const GURL& script_url = file->url();
-+    // Check if the script is already injected.
-+    if (executing_scripts->count(script_url.path()) != 0)
-+      continue;
-+
-+    sources.push_back(blink::WebScriptSource(
-+        user_script_set_->GetJsSource(*file, script_->emulate_greasemonkey()),
-+        script_url));
-+
-+    (*num_injected_js_scripts) += 1;
-+    executing_scripts->insert(script_url.path());
-+  }
-+
-+  return sources;
-+}
-+
-+std::vector<blink::WebString> UserScriptInjector::GetCssSources(
-+    UserScript::RunLocation run_location,
-+    std::set<std::string>* injected_stylesheets,
-+    size_t* num_injected_stylesheets) const {
-+  DCHECK(script_);
-+  DCHECK_EQ(UserScript::DOCUMENT_START, run_location);
-+
-+  std::vector<blink::WebString> sources;
-+
-+  const UserScript::FileList& css_scripts = script_->css_scripts();
-+  sources.reserve(css_scripts.size());
-+  for (const std::unique_ptr<UserScript::File>& file : script_->css_scripts()) {
-+    const std::string& stylesheet_path = file->url().path();
-+    // Check if the stylesheet is already injected.
-+    if (injected_stylesheets->count(stylesheet_path) != 0)
-+      continue;
-+
-+    sources.push_back(user_script_set_->GetCssSource(*file));
-+    (*num_injected_stylesheets) += 1;
-+    injected_stylesheets->insert(stylesheet_path);
-+  }
-+  return sources;
-+}
-+
-+void UserScriptInjector::OnInjectionComplete(
-+    std::unique_ptr<base::Value> execution_result,
-+    UserScript::RunLocation run_location,
-+    content::RenderFrame* render_frame) {}
-+
-+void UserScriptInjector::OnWillNotInject(InjectFailureReason reason,
-+                                         content::RenderFrame* render_frame) {
-+}
-+
-+}  // namespace extensions
-diff --git a/components/user_scripts/renderer/user_script_injector.h b/components/user_scripts/renderer/user_script_injector.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/user_script_injector.h
-@@ -0,0 +1,87 @@
-+// Copyright 2014 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#ifndef USERSCRIPTS_RENDERER_USER_SCRIPT_INJECTOR_H_
-+#define USERSCRIPTS_RENDERER_USER_SCRIPT_INJECTOR_H_
-+
-+#include <memory>
-+#include <string>
-+
-+#include "base/macros.h"
-+#include "base/values.h"
-+#include "base/scoped_observation.h"
-+#include "../common/user_script.h"
-+#include "script_injection.h"
-+#include "user_script_set.h"
-+
-+class InjectionHost;
-+
-+namespace blink {
-+class WebLocalFrame;
-+}
-+
-+namespace user_scripts {
-+
-+// A ScriptInjector for UserScripts.
-+class UserScriptInjector : public ScriptInjector,
-+                           public UserScriptSet::Observer {
-+ public:
-+  UserScriptInjector(const UserScript* user_script,
-+                     UserScriptSet* user_script_set);
-+  ~UserScriptInjector() override;
-+
-+ private:
-+  // UserScriptSet::Observer implementation.
-+  void OnUserScriptsUpdated(const std::set<HostID>& changed_hosts,
-+                            const UserScriptList& scripts) override;
-+
-+  // ScriptInjector implementation.
-+  UserScript::InjectionType script_type() const override;
-+  bool IsUserGesture() const override;
-+  absl::optional<CSSOrigin> GetCssOrigin() const override;
-+  const absl::optional<std::string> GetInjectionKey() const override;
-+  bool ExpectsResults() const override;
-+  bool ShouldInjectJs(
-+      UserScript::RunLocation run_location,
-+      const std::set<std::string>& executing_scripts) const override;
-+  bool ShouldInjectCss(
-+      UserScript::RunLocation run_location,
-+      const std::set<std::string>& injected_stylesheets) const override;
-+  std::vector<blink::WebScriptSource> GetJsSources(
-+      UserScript::RunLocation run_location,
-+      std::set<std::string>* executing_scripts,
-+      size_t* num_injected_js_scripts) const override;
-+  std::vector<blink::WebString> GetCssSources(
-+      UserScript::RunLocation run_location,
-+      std::set<std::string>* injected_stylesheets,
-+      size_t* num_injected_stylesheets) const override;
-+  void OnInjectionComplete(std::unique_ptr<base::Value> execution_result,
-+                           UserScript::RunLocation run_location,
-+                           content::RenderFrame* render_frame) override;
-+  void OnWillNotInject(InjectFailureReason reason,
-+                       content::RenderFrame* render_frame) override;
-+
-+  // The associated user script. Owned by the UserScriptInjector that created
-+  // this object.
-+  const UserScript* script_;
-+
-+  // The UserScriptSet that eventually owns the UserScript this
-+  // UserScriptInjector points to.
-+  // Outlives |this|.
-+  UserScriptSet* const user_script_set_;
-+
-+  // The id of the associated user script. We cache this because when we update
-+  // the |script_| associated with this injection, the old referance may be
-+  // deleted.
-+  int script_id_;
-+
-+  base::ScopedObservation<UserScriptSet, UserScriptSet::Observer>
-+      user_script_set_observer_{this};
-+
-+  DISALLOW_COPY_AND_ASSIGN(UserScriptInjector);
-+};
-+
-+}  // namespace extensions
-+
-+#endif  // USERSCRIPTS_RENDERER_USER_SCRIPT_INJECTOR_H_
-diff --git a/components/user_scripts/renderer/user_script_set.cc b/components/user_scripts/renderer/user_script_set.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/user_script_set.cc
-@@ -0,0 +1,259 @@
-+// Copyright 2014 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#include "user_script_set.h"
-+
-+#include <stddef.h>
-+
-+#include <utility>
-+
-+#include "base/logging.h"
-+#include "base/debug/alias.h"
-+#include "base/memory/ref_counted.h"
-+#include "base/strings/strcat.h"
-+#include "content/public/common/url_constants.h"
-+#include "content/public/renderer/render_frame.h"
-+#include "content/public/renderer/render_thread.h"
-+#include "injection_host.h"
-+#include "script_context.h"
-+#include "script_injection.h"
-+#include "user_script_injector.h"
-+#include "web_ui_injection_host.h"
-+#include "third_party/blink/public/web/web_document.h"
-+#include "third_party/blink/public/web/web_local_frame.h"
-+#include "url/gurl.h"
-+#include "../common/user_scripts_features.h"
-+
-+namespace user_scripts {
-+
-+namespace {
-+
-+// These two strings are injected before and after the Greasemonkey API and
-+// user script to wrap it in an anonymous scope.
-+const char kUserScriptHead[] = "(function (unsafeWindow) {\n";
-+const char kUserScriptTail[] = "\n})(window);";
-+// Maximum number of total content scripts we allow (across all extensions).
-+// The limit exists to diagnose https://crbug.com/723381. The number is
-+// arbitrarily chosen.
-+// TODO(lazyboy): Remove when the bug is fixed.
-+const uint32_t kNumScriptsArbitraryMax = 100000u;
-+
-+GURL GetDocumentUrlForFrame(blink::WebLocalFrame* frame) {
-+  GURL data_source_url = ScriptContext::GetDocumentLoaderURLForFrame(frame);
-+  if (!data_source_url.is_empty() && frame->IsViewSourceModeEnabled()) {
-+    data_source_url = GURL(content::kViewSourceScheme + std::string(":") +
-+                           data_source_url.spec());
-+  }
-+
-+  return data_source_url;
-+}
-+
-+}  // namespace
-+
-+UserScriptSet::UserScriptSet() {}
-+
-+UserScriptSet::~UserScriptSet() {
-+}
-+
-+void UserScriptSet::AddObserver(Observer* observer) {
-+  observers_.AddObserver(observer);
-+}
-+
-+void UserScriptSet::RemoveObserver(Observer* observer) {
-+  observers_.RemoveObserver(observer);
-+}
-+
-+void UserScriptSet::GetInjections(
-+    std::vector<std::unique_ptr<ScriptInjection>>* injections,
-+    content::RenderFrame* render_frame,
-+    int tab_id,
-+    UserScript::RunLocation run_location,
-+    bool log_activity) {
-+  GURL document_url = GetDocumentUrlForFrame(render_frame->GetWebFrame());
-+  for (const std::unique_ptr<UserScript>& script : scripts_) {
-+    std::unique_ptr<ScriptInjection> injection = GetInjectionForScript(
-+        script.get(), render_frame, tab_id, run_location, document_url,
-+        /* is_declarative, */ log_activity);
-+    if (injection.get())
-+      injections->push_back(std::move(injection));
-+  }
-+}
-+
-+bool UserScriptSet::UpdateUserScripts(
-+    base::ReadOnlySharedMemoryRegion shared_memory,
-+    const std::set<HostID>& changed_hosts,
-+    bool whitelisted_only) {
-+  bool only_inject_incognito = false;
-+  //ExtensionsRendererClient::Get()->IsIncognitoProcess();
-+
-+  // Create the shared memory mapping.
-+  shared_memory_mapping_ = shared_memory.Map();
-+  if (!shared_memory.IsValid())
-+    return false;
-+
-+  // First get the size of the memory block.
-+  const base::Pickle::Header* pickle_header =
-+      shared_memory_mapping_.GetMemoryAs<base::Pickle::Header>();
-+  if (!pickle_header)
-+    return false;
-+
-+  // Now read in the rest of the block.
-+  size_t pickle_size =
-+      sizeof(base::Pickle::Header) + pickle_header->payload_size;
-+
-+  // Unpickle scripts.
-+  uint32_t num_scripts = 0;
-+  auto memory = shared_memory_mapping_.GetMemoryAsSpan<char>(pickle_size);
-+  if (!memory.size())
-+    return false;
-+
-+  base::Pickle pickle(memory.data(), pickle_size);
-+  base::PickleIterator iter(pickle);
-+  base::debug::Alias(&pickle_size);
-+  CHECK(iter.ReadUInt32(&num_scripts));
-+
-+  // Sometimes the shared memory contents seem to be corrupted
-+  // (https://crbug.com/723381). Set an arbitrary max limit to the number of
-+  // scripts so that we don't add OOM noise to crash reports.
-+  CHECK_LT(num_scripts, kNumScriptsArbitraryMax);
-+
-+  scripts_.clear();
-+  script_sources_.clear();
-+  scripts_.reserve(num_scripts);
-+  for (uint32_t i = 0; i < num_scripts; ++i) {
-+    std::unique_ptr<UserScript> script(new UserScript());
-+    script->Unpickle(pickle, &iter);
-+
-+    // Note that this is a pointer into shared memory. We don't own it. It gets
-+    // cleared up when the last renderer or browser process drops their
-+    // reference to the shared memory.
-+    for (size_t j = 0; j < script->js_scripts().size(); ++j) {
-+      const char* body = NULL;
-+      int body_length = 0;
-+      CHECK(iter.ReadData(&body, &body_length));
-+      script->js_scripts()[j]->set_external_content(
-+          base::StringPiece(body, body_length));
-+    }
-+    for (size_t j = 0; j < script->css_scripts().size(); ++j) {
-+      const char* body = NULL;
-+      int body_length = 0;
-+      CHECK(iter.ReadData(&body, &body_length));
-+      script->css_scripts()[j]->set_external_content(
-+          base::StringPiece(body, body_length));
-+    }
-+
-+    if (only_inject_incognito && !script->is_incognito_enabled())
-+      continue;  // This script shouldn't run in an incognito tab.
-+
-+    scripts_.push_back(std::move(script));
-+  }
-+
-+  for (auto& observer : observers_)
-+    observer.OnUserScriptsUpdated(changed_hosts, scripts_);
-+  return true;
-+}
-+
-+void UserScriptSet::AddScript(std::unique_ptr<UserScript> script) {
-+  scripts_.push_back(std::move(script));
-+}
-+
-+std::unique_ptr<ScriptInjection> UserScriptSet::GetInjectionForScript(
-+    const UserScript* script,
-+    content::RenderFrame* render_frame,
-+    int tab_id,
-+    UserScript::RunLocation run_location,
-+    const GURL& document_url,
-+    //bool is_declarative,
-+    bool log_activity) {
-+  std::unique_ptr<ScriptInjection> injection;
-+  std::unique_ptr<const InjectionHost> injection_host;
-+  blink::WebLocalFrame* web_frame = render_frame->GetWebFrame();
-+
-+  const HostID& host_id = script->host_id();
-+  injection_host.reset(new WebUIInjectionHost(host_id));
-+
-+  GURL effective_document_url =
-+      ScriptContext::GetEffectiveDocumentURLForInjection(
-+          web_frame, document_url, script->match_origin_as_fallback());
-+
-+  bool is_subframe = web_frame->Parent();
-+  if (!script->MatchesDocument(effective_document_url, is_subframe)) {
-+    if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+      LOG(INFO) << "UserScripts: No Match name=" << script->name() << " " <<
-+                                         "url=" << effective_document_url.spec();
-+    return injection;
-+  }
-+
-+  std::unique_ptr<ScriptInjector> injector(
-+      new UserScriptInjector(script, this));
-+
-+  bool inject_css = !script->css_scripts().empty() &&
-+                    run_location == UserScript::DOCUMENT_START;
-+  bool inject_js =
-+      !script->js_scripts().empty() && script->run_location() == run_location;
-+  if (inject_css || inject_js) {
-+    injection.reset(new ScriptInjection(std::move(injector), render_frame,
-+                                        std::move(injection_host), run_location,
-+                                        log_activity));
-+    if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+      LOG(INFO) << "UserScripts: Match name=" << script->name() << " " <<
-+                                         "url=" << effective_document_url.spec();
-+  } else {
-+    if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts)) {
-+      if (script->run_location() != run_location)
-+        LOG(INFO) << "UserScripts: run location for name=" << script->name() <<
-+                                        "current " << run_location << " " <<
-+                                        "need " << script->run_location();
-+      else
-+        LOG(INFO) << "UserScripts: Match but no run name=" << script->name() << " " <<
-+                                        "url=" << effective_document_url.spec();
-+    }
-+  }
-+  return injection;
-+}
-+
-+blink::WebString UserScriptSet::GetJsSource(const UserScript::File& file,
-+                                            bool emulate_greasemonkey) {
-+  const GURL& url = file.url();
-+  auto iter = script_sources_.find(url);
-+  if (iter != script_sources_.end()) {
-+    return iter->second;
-+  }
-+
-+  base::StringPiece script_content = file.GetContent();
-+  blink::WebString source;
-+  if (emulate_greasemonkey) {
-+    // We add this dumb function wrapper for user scripts to emulate what
-+    // Greasemonkey does. |script_content| becomes:
-+    // concat(kUserScriptHead, script_content, kUserScriptTail).
-+    std::string content =
-+        base::StrCat({kUserScriptHead, script_content, kUserScriptTail});
-+    source = blink::WebString::FromUTF8(content);
-+    if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+      LOG(INFO) << "UserScripts: Injecting w/greasemonkey " << file.url();
-+  } else {
-+    source = blink::WebString::FromUTF8(script_content.data(),
-+                                        script_content.length());
-+    if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+      LOG(INFO) << "UserScripts: Injecting " << file.url();
-+  }
-+  script_sources_[url] = source;
-+  return source;
-+}
-+
-+blink::WebString UserScriptSet::GetCssSource(const UserScript::File& file) {
-+  const GURL& url = file.url();
-+  auto iter = script_sources_.find(url);
-+  if (iter != script_sources_.end())
-+    return iter->second;
-+
-+  base::StringPiece script_content = file.GetContent();
-+  return script_sources_
-+      .insert(std::make_pair(
-+          url, blink::WebString::FromUTF8(script_content.data(),
-+                                          script_content.length())))
-+      .first->second;
-+}
-+
-+}  // namespace extensions
-diff --git a/components/user_scripts/renderer/user_script_set.h b/components/user_scripts/renderer/user_script_set.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/user_script_set.h
-@@ -0,0 +1,102 @@
-+// Copyright 2014 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#ifndef USERSCRIPTS_RENDERER_USER_SCRIPT_SET_H_
-+#define USERSCRIPTS_RENDERER_USER_SCRIPT_SET_H_
-+
-+#include <map>
-+#include <memory>
-+#include <set>
-+#include <string>
-+#include <vector>
-+
-+#include "base/macros.h"
-+#include "base/memory/read_only_shared_memory_region.h"
-+#include "base/observer_list.h"
-+#include "../common/user_script.h"
-+#include "third_party/blink/public/platform/web_string.h"
-+
-+class GURL;
-+
-+namespace content {
-+class RenderFrame;
-+}
-+
-+namespace user_scripts {
-+class ScriptInjection;
-+
-+// The UserScriptSet is a collection of UserScripts which knows how to update
-+// itself from SharedMemory and create ScriptInjections for UserScripts to
-+// inject on a page.
-+class UserScriptSet {
-+ public:
-+  class Observer {
-+   public:
-+    // Called when the set of user scripts is updated. |changed_hosts| contains
-+    // the hosts whose scripts have been altered. Note that *all* script objects
-+    // are invalidated, even if they aren't in |changed_hosts|.
-+    virtual void OnUserScriptsUpdated(const std::set<HostID>& changed_hosts,
-+                                      const UserScriptList& scripts) = 0;
-+  };
-+
-+  UserScriptSet();
-+  ~UserScriptSet();
-+
-+  // Adds or removes observers.
-+  void AddObserver(Observer* observer);
-+  void RemoveObserver(Observer* observer);
-+  void AddScript(std::unique_ptr<UserScript> script);
-+
-+  // Append any ScriptInjections that should run on the given |render_frame| and
-+  // |tab_id|, at the given |run_location|, to |injections|.
-+  // |extensions| is passed in to verify the corresponding extension is still
-+  // valid.
-+  void GetInjections(std::vector<std::unique_ptr<ScriptInjection>>* injections,
-+                     content::RenderFrame* render_frame,
-+                     int tab_id,
-+                     UserScript::RunLocation run_location,
-+                     bool log_activity);
-+
-+  // Updates scripts given the shared memory region containing user scripts.
-+  // Returns true if the scripts were successfully updated.
-+  bool UpdateUserScripts(base::ReadOnlySharedMemoryRegion shared_memory,
-+                         const std::set<HostID>& changed_hosts,
-+                         bool whitelisted_only);
-+
-+  // Returns the contents of a script file.
-+  // Note that copying is cheap as this uses WebString.
-+  blink::WebString GetJsSource(const UserScript::File& file,
-+                               bool emulate_greasemonkey);
-+  blink::WebString GetCssSource(const UserScript::File& file);
-+
-+ private:
-+  // Returns a new ScriptInjection for the given |script| to execute in the
-+  // |render_frame|, or NULL if the script should not execute.
-+  std::unique_ptr<ScriptInjection> GetInjectionForScript(
-+      const UserScript* script,
-+      content::RenderFrame* render_frame,
-+      int tab_id,
-+      UserScript::RunLocation run_location,
-+      const GURL& document_url,
-+      //bool is_declarative,
-+      bool log_activity);
-+
-+  // Shared memory mapping containing raw script data.
-+  base::ReadOnlySharedMemoryMapping shared_memory_mapping_;
-+
-+  // The UserScripts this injector manages.
-+  UserScriptList scripts_;
-+
-+  // Map of user script file url -> source.
-+  std::map<GURL, blink::WebString> script_sources_;
-+
-+  // The associated observers.
-+  base::ObserverList<Observer>::Unchecked observers_;
-+
-+  DISALLOW_COPY_AND_ASSIGN(UserScriptSet);
-+};
-+
-+}  // namespace extensions
-+
-+#endif  // USERSCRIPTS_RENDERER_USER_SCRIPT_SET_H_
-diff --git a/components/user_scripts/renderer/user_script_set_manager.cc b/components/user_scripts/renderer/user_script_set_manager.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/user_script_set_manager.cc
-@@ -0,0 +1,77 @@
-+#include "user_script_set_manager.h"
-+
-+#include "base/logging.h"
-+#include "content/public/renderer/render_thread.h"
-+#include "../common/host_id.h"
-+#include "../common/extension_messages.h"
-+#include "../common/user_scripts_features.h"
-+#include "user_script_set.h"
-+
-+namespace user_scripts {
-+
-+UserScriptSetManager::UserScriptSetManager() {
-+  content::RenderThread::Get()->AddObserver(this);
-+}
-+
-+UserScriptSetManager::~UserScriptSetManager() {
-+}
-+
-+void UserScriptSetManager::AddObserver(Observer* observer) {
-+  observers_.AddObserver(observer);
-+}
-+
-+void UserScriptSetManager::RemoveObserver(Observer* observer) {
-+  observers_.RemoveObserver(observer);
-+}
-+
-+bool UserScriptSetManager::OnControlMessageReceived(
-+    const IPC::Message& message) {
-+  bool handled = true;
-+  IPC_BEGIN_MESSAGE_MAP(UserScriptSetManager, message)
-+    IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateUserScripts, OnUpdateUserScripts)
-+    IPC_MESSAGE_UNHANDLED(handled = false)
-+  IPC_END_MESSAGE_MAP()
-+  return handled;
-+}
-+
-+void UserScriptSetManager::GetAllInjections(
-+    std::vector<std::unique_ptr<ScriptInjection>>* injections,
-+    content::RenderFrame* render_frame,
-+    int tab_id,
-+    UserScript::RunLocation run_location) {
-+
-+  if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+    LOG(INFO) << "UserScripts: GetAllInjections";
-+
-+  // static_scripts_ is UserScriptSet
-+  static_scripts_.GetInjections(injections, render_frame, tab_id, run_location,
-+                                activity_logging_enabled_);
-+}
-+
-+void UserScriptSetManager::OnUpdateUserScripts(
-+    base::ReadOnlySharedMemoryRegion shared_memory) {
-+  if (!shared_memory.IsValid()) {
-+    NOTREACHED() << "Bad scripts handle";
-+    return;
-+  }
-+
-+  UserScriptSet* scripts = NULL;
-+  scripts = &static_scripts_;
-+
-+  DCHECK(scripts);
-+
-+  // If no hosts are included in the set, that indicates that all
-+  // hosts were updated. Add them all to the set so that observers and
-+  // individual UserScriptSets don't need to know this detail.
-+  //const std::set<HostID>* effective_hosts = &changed_hosts;
-+  std::set<HostID> all_hosts;
-+  const std::set<HostID>* effective_hosts = &all_hosts;
-+
-+  if (scripts->UpdateUserScripts(std::move(shared_memory), *effective_hosts,
-+                                 false /*whitelisted_only*/)) {
-+    for (auto& observer : observers_)
-+      observer.OnUserScriptsUpdated(all_hosts /* *effective_hosts*/);
-+  }
-+}
-+
-+}
-\ No newline at end of file
-diff --git a/components/user_scripts/renderer/user_script_set_manager.h b/components/user_scripts/renderer/user_script_set_manager.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/user_script_set_manager.h
-@@ -0,0 +1,62 @@
-+#ifndef USERSCRIPTS_RENDER_SET_MANAGER_H_
-+#define USERSCRIPTS_RENDER_SET_MANAGER_H_
-+
-+#include <map>
-+#include <set>
-+#include <string>
-+#include <vector>
-+
-+#include "base/macros.h"
-+#include "base/memory/read_only_shared_memory_region.h"
-+#include "base/observer_list.h"
-+#include "content/public/renderer/render_thread_observer.h"
-+#include "../common/host_id.h"
-+#include "user_script_set.h"
-+#include "script_injection.h"
-+
-+namespace user_scripts {
-+
-+class UserScriptSetManager : public content::RenderThreadObserver {
-+ public:
-+  class Observer {
-+   public:
-+    virtual void OnUserScriptsUpdated(const std::set<HostID>& changed_hosts) = 0;
-+  };
-+
-+  UserScriptSetManager();
-+
-+  ~UserScriptSetManager() override;
-+
-+  void AddObserver(Observer* observer);
-+  void RemoveObserver(Observer* observer);
-+
-+  // Append all injections from |static_scripts| and each of
-+  // |programmatic_scripts_| to |injections|.
-+  void GetAllInjections(
-+      std::vector<std::unique_ptr<ScriptInjection>>* injections,
-+      content::RenderFrame* render_frame,
-+      int tab_id,
-+      UserScript::RunLocation run_location);
-+
-+private:
-+  // content::RenderThreadObserver implementation.
-+  bool OnControlMessageReceived(const IPC::Message& message) override;
-+
-+  base::ObserverList<Observer>::Unchecked observers_;
-+
-+  // Handle the UpdateUserScripts extension message.
-+  void OnUpdateUserScripts(base::ReadOnlySharedMemoryRegion shared_memory);
-+                           //, const HostID& host_id,
-+                           //const std::set<HostID>& changed_hosts,
-+                           //bool whitelisted_only);
-+
-+  // Scripts statically defined in extension manifests.
-+  UserScriptSet static_scripts_;
-+
-+  // Whether or not dom activity should be logged for scripts injected.
-+  bool activity_logging_enabled_ = false;
-+};
-+
-+}
-+
-+#endif
-\ No newline at end of file
-diff --git a/components/user_scripts/renderer/user_scripts_dispatcher.cc b/components/user_scripts/renderer/user_scripts_dispatcher.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/user_scripts_dispatcher.cc
-@@ -0,0 +1,36 @@
-+#include "user_scripts_dispatcher.h"
-+
-+#include <stddef.h>
-+
-+#include <algorithm>
-+#include <memory>
-+#include <utility>
-+
-+#include "content/public/renderer/render_thread.h"
-+#include "extension_frame_helper.h"
-+
-+namespace user_scripts {
-+
-+// ex ChromeExtensionsDispatcherDelegate
-+UserScriptsDispatcher::UserScriptsDispatcher()
-+    : user_script_set_manager_observer_(this) {
-+      user_script_set_manager_.reset(new UserScriptSetManager());
-+      script_injection_manager_.reset(
-+          new ScriptInjectionManager(user_script_set_manager_.get()));
-+      user_script_set_manager_observer_.Observe(user_script_set_manager_.get());
-+}
-+
-+UserScriptsDispatcher::~UserScriptsDispatcher() {
-+}
-+
-+void UserScriptsDispatcher::OnRenderThreadStarted(content::RenderThread* thread) {
-+}
-+
-+void UserScriptsDispatcher::OnUserScriptsUpdated(const std::set<HostID>& changed_hosts) {
-+}
-+
-+void UserScriptsDispatcher::OnRenderFrameCreated(content::RenderFrame* render_frame) {
-+  script_injection_manager_->OnRenderFrameCreated(render_frame);
-+}
-+
-+}
-\ No newline at end of file
-diff --git a/components/user_scripts/renderer/user_scripts_dispatcher.h b/components/user_scripts/renderer/user_scripts_dispatcher.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/user_scripts_dispatcher.h
-@@ -0,0 +1,48 @@
-+#ifndef USERSCRIPTS_RENDER_DISPATCHER_H_
-+#define USERSCRIPTS_RENDER_DISPATCHER_H_
-+
-+#include "user_script_set_manager.h"
-+#include "script_injection_manager.h"
-+
-+#include <stdint.h>
-+
-+#include <map>
-+#include <memory>
-+#include <set>
-+#include <string>
-+#include <utility>
-+#include <vector>
-+
-+#include "base/macros.h"
-+#include "base/scoped_observation.h"
-+#include "content/public/renderer/render_thread_observer.h"
-+#include "content/public/renderer/render_thread.h"
-+#include "../common/host_id.h"
-+#include "user_script_set_manager.h"
-+#include "script_injection.h"
-+
-+namespace user_scripts {
-+
-+class UserScriptsDispatcher : public content::RenderThreadObserver,
-+                              public UserScriptSetManager::Observer {
-+
-+ public:
-+  explicit UserScriptsDispatcher();
-+  ~UserScriptsDispatcher() override;
-+
-+  void OnRenderThreadStarted(content::RenderThread* thread);
-+  void OnUserScriptsUpdated(const std::set<HostID>& changed_hosts) override;
-+  void OnRenderFrameCreated(content::RenderFrame* render_frame);
-+
-+ private:
-+  std::unique_ptr<UserScriptSetManager> user_script_set_manager_;
-+
-+  std::unique_ptr<ScriptInjectionManager> script_injection_manager_;
-+
-+  base::ScopedObservation<UserScriptSetManager, UserScriptSetManager::Observer>
-+      user_script_set_manager_observer_{this};
-+};
-+
-+}
-+
-+#endif
-\ No newline at end of file
-diff --git a/components/user_scripts/renderer/user_scripts_renderer_client.cc b/components/user_scripts/renderer/user_scripts_renderer_client.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/user_scripts_renderer_client.cc
-@@ -0,0 +1,105 @@
-+#include "user_scripts_renderer_client.h"
-+
-+#include <memory>
-+#include <utility>
-+
-+#include "base/logging.h"
-+#include "base/lazy_instance.h"
-+#include "content/public/renderer/render_frame.h"
-+#include "content/public/renderer/render_thread.h"
-+#include "content/public/renderer/render_frame_visitor.h"
-+#include "chrome/renderer/chrome_render_thread_observer.h"
-+
-+#include "../common/user_scripts_features.h"
-+#include "user_scripts_dispatcher.h"
-+#include "extension_frame_helper.h"
-+
-+namespace user_scripts {
-+
-+// was ChromeExtensionsRendererClient
-+UserScriptsRendererClient::UserScriptsRendererClient() {}
-+
-+UserScriptsRendererClient::~UserScriptsRendererClient() {}
-+
-+// static
-+UserScriptsRendererClient* UserScriptsRendererClient::GetInstance() {
-+  static base::LazyInstance<UserScriptsRendererClient>::Leaky client =
-+      LAZY_INSTANCE_INITIALIZER;
-+  return client.Pointer();
-+}
-+
-+void UserScriptsRendererClient::RenderThreadStarted() {
-+  if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+    LOG(INFO) << "UserScripts: RenderThreadStarted";
-+
-+  content::RenderThread* thread = content::RenderThread::Get();
-+  dispatcher_ = std::make_unique<UserScriptsDispatcher>();
-+
-+  dispatcher_->OnRenderThreadStarted(thread);
-+  thread->AddObserver(dispatcher_.get());
-+}
-+
-+void UserScriptsRendererClient::ConfigurationUpdated() {
-+  if (base::FeatureList::IsEnabled(features::kEnableLoggingUserScripts))
-+    LOG(INFO) << "UserScripts: Configuration Updated";
-+
-+  struct WatchFrame : public content::RenderFrameVisitor {
-+    bool Visit(content::RenderFrame* frame) override {
-+      if (frame)
-+        UserScriptsRendererClient::GetInstance()->RenderFrameCreated(frame, NULL);
-+      return true;  // Continue visiting.
-+    }
-+  };
-+  WatchFrame visitor = {};
-+  content::RenderFrame::ForEach(&visitor);
-+}
-+
-+void UserScriptsRendererClient::RenderFrameCreated(
-+    content::RenderFrame* render_frame,
-+    service_manager::BinderRegistry* registry) {
-+
-+  auto params = ChromeRenderThreadObserver::GetDynamicParams();
-+  enabled_ = params.allow_userscript;
-+  if (!enabled_) return;
-+
-+  if (loaded_ == false) {
-+    loaded_ = true;
-+    new user_scripts::ExtensionFrameHelper(render_frame);
-+    dispatcher_->OnRenderFrameCreated(render_frame);
-+  }
-+}
-+
-+void UserScriptsRendererClient::RunScriptsAtDocumentStart(content::RenderFrame* render_frame) {
-+  if (!enabled_ || !loaded_) return;
-+
-+  ExtensionFrameHelper* frame_helper = ExtensionFrameHelper::Get(render_frame);
-+  if (!frame_helper)
-+    return;  // The frame is invisible to user scripts.
-+
-+  frame_helper->RunScriptsAtDocumentStart();
-+  // |frame_helper| and |render_frame| might be dead by now.
-+}
-+
-+void UserScriptsRendererClient::RunScriptsAtDocumentEnd(content::RenderFrame* render_frame) {
-+  if (!enabled_ || !loaded_) return;
-+
-+  ExtensionFrameHelper* frame_helper = ExtensionFrameHelper::Get(render_frame);
-+  if (!frame_helper)
-+    return;  // The frame is invisible to user scripts.
-+
-+  frame_helper->RunScriptsAtDocumentEnd();
-+  // |frame_helper| and |render_frame| might be dead by now.
-+}
-+
-+void UserScriptsRendererClient::RunScriptsAtDocumentIdle(content::RenderFrame* render_frame) {
-+  if (!enabled_ || !loaded_) return;
-+
-+  ExtensionFrameHelper* frame_helper = ExtensionFrameHelper::Get(render_frame);
-+  if (!frame_helper)
-+    return;  // The frame is invisible to user scripts.
-+
-+  frame_helper->RunScriptsAtDocumentIdle();
-+  // |frame_helper| and |render_frame| might be dead by now.
-+}
-+
-+}
-\ No newline at end of file
-diff --git a/components/user_scripts/renderer/user_scripts_renderer_client.h b/components/user_scripts/renderer/user_scripts_renderer_client.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/user_scripts_renderer_client.h
-@@ -0,0 +1,36 @@
-+#ifndef USERSCRIPTS_RENDER_CLIENT_H_
-+#define USERSCRIPTS_RENDER_CLIENT_H_
-+
-+#include <memory>
-+#include <string>
-+
-+#include "base/macros.h"
-+#include "user_scripts_dispatcher.h"
-+#include "services/service_manager/public/cpp/binder_registry.h"
-+
-+namespace user_scripts {
-+
-+class UserScriptsRendererClient {
-+ public:
-+  UserScriptsRendererClient();
-+  ~UserScriptsRendererClient();
-+
-+  static UserScriptsRendererClient* GetInstance();
-+
-+  void RenderThreadStarted();
-+  void ConfigurationUpdated();
-+  void RenderFrameCreated(content::RenderFrame* render_frame,
-+    service_manager::BinderRegistry* registry);
-+  void RunScriptsAtDocumentStart(content::RenderFrame* render_frame);
-+  void RunScriptsAtDocumentEnd(content::RenderFrame* render_frame);
-+  void RunScriptsAtDocumentIdle(content::RenderFrame* render_frame);
-+
-+ private:
-+  std::unique_ptr<UserScriptsDispatcher> dispatcher_;
-+  bool enabled_ = false;
-+  bool loaded_ = false;
-+};
-+
-+}
-+
-+#endif
-\ No newline at end of file
-diff --git a/components/user_scripts/renderer/web_ui_injection_host.cc b/components/user_scripts/renderer/web_ui_injection_host.cc
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/web_ui_injection_host.cc
-@@ -0,0 +1,40 @@
-+// Copyright 2015 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#include "web_ui_injection_host.h"
-+#include "base/no_destructor.h"
-+
-+namespace {
-+
-+// The default secure CSP to be used in order to prevent remote scripts.
-+const char kDefaultSecureCSP[] = "script-src 'self'; object-src 'self';";
-+
-+}
-+
-+WebUIInjectionHost::WebUIInjectionHost(const HostID& host_id)
-+  : InjectionHost(host_id),
-+    url_(host_id.id()) {
-+}
-+
-+WebUIInjectionHost::~WebUIInjectionHost() {
-+}
-+
-+const std::string* WebUIInjectionHost::GetContentSecurityPolicy() const {
-+  // Use the main world CSP.
-+  // return nullptr;
-+
-+  // The isolated world will use its own CSP which blocks remotely hosted
-+  // code.
-+  static const base::NoDestructor<std::string> default_isolated_world_csp(
-+      kDefaultSecureCSP);
-+  return default_isolated_world_csp.get();
-+}
-+
-+const GURL& WebUIInjectionHost::url() const {
-+  return url_;
-+}
-+
-+const std::string& WebUIInjectionHost::name() const {
-+  return id().id();
-+}
-diff --git a/components/user_scripts/renderer/web_ui_injection_host.h b/components/user_scripts/renderer/web_ui_injection_host.h
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/renderer/web_ui_injection_host.h
-@@ -0,0 +1,28 @@
-+// Copyright 2015 The Chromium Authors. All rights reserved.
-+// Use of this source code is governed by a BSD-style license that can be
-+// found in the LICENSE file.
-+
-+#ifndef USERSCRIPTS_RENDERER_WEB_UI_INJECTION_HOST_H_
-+#define USERSCRIPTS_RENDERER_WEB_UI_INJECTION_HOST_H_
-+
-+#include "base/macros.h"
-+#include "injection_host.h"
-+
-+class WebUIInjectionHost : public InjectionHost {
-+ public:
-+  WebUIInjectionHost(const HostID& host_id);
-+  ~WebUIInjectionHost() override;
-+
-+ private:
-+  // InjectionHost:
-+  const std::string* GetContentSecurityPolicy() const override;
-+  const GURL& url() const override;
-+  const std::string& name() const override;
-+
-+ private:
-+  GURL url_;
-+
-+  DISALLOW_COPY_AND_ASSIGN(WebUIInjectionHost);
-+};
-+
-+#endif  // USERSCRIPTS_RENDERER_WEB_UI_INJECTION_HOST_H_
-diff --git a/components/user_scripts/strings/userscripts_strings.grdp b/components/user_scripts/strings/userscripts_strings.grdp
-new file mode 100755
---- /dev/null
-+++ b/components/user_scripts/strings/userscripts_strings.grdp
-@@ -0,0 +1,55 @@
-+<?xml version="1.0" encoding="utf-8"?>
-+<grit-part>
-+
-+  <!-- Preferences -->
-+  <message name="IDS_PREFS_USERSCRIPTS_SETTINGS"
-+           desc="."
-+           formatter_data="android_java">
-+    User Scripts
-+  </message>
-+
-+  <message name="IDS_OPTION_USERSCRIPT_FLAG" desc="." formatter_data="android_java">
-+    Activate User Scripts
-+  </message>
-+
-+  <message name="IDS_OPTION_USERSCRIPT_FLAG_ON" desc=". [CHAR-LIMIT=32]" formatter_data="android_java">
-+    ON
-+  </message>
-+  <message name="IDS_OPTION_USERSCRIPT_FLAG_OFF" desc=". [CHAR-LIMIT=32]" formatter_data="android_java">
-+    OFF
-+  </message>
-+
-+  <message name="IDS_ADD_SCRIPT" desc=". [CHAR-LIMIT=32]" formatter_data="android_java">
-+    Add script
-+  </message>
-+  <message name="IDS_SCRIPTS_LIST_DESCRIPTION" desc="." formatter_data="android_java">
-+    Experimental support for Greasemonkey-style user scripts.
-+  </message>
-+
-+  <message name="IDS_SCRIPTS_ITEM_VERSION" desc="." formatter_data="android_java">
-+    Version:
-+  </message>
-+  <message name="IDS_SCRIPTS_ITEM_FILENAME" desc="." formatter_data="android_java">
-+    File:
-+  </message>
-+  <message name="IDS_SCRIPTS_ITEM_URL" desc="." formatter_data="android_java">
-+    Url:
-+  </message>
-+
-+  <message name="IDS_SCRIPTS_VIEW_SOURCE" desc=". [CHAR-LIMIT=32]" formatter_data="android_java">
-+    View source
-+  </message>
-+
-+  <message name="IDS_ASK_TO_INSTALL" desc=". [CHAR-LIMIT=32]" formatter_data="android_java">
-+    Only install user scripts that you have verified are secure, user scripts can steal your credentials and data.
-+
-+Do you want to install <ph name="FILE">%s</ph>?
-+  </message>
-+  <message name="IDS_YES" desc=". [CHAR-LIMIT=32]" formatter_data="android_java">
-+    Yes
-+  </message>
-+  <message name="IDS_NO" desc=". [CHAR-LIMIT=32]" formatter_data="android_java">
-+    No
-+  </message>
-+
-+</grit-part>
-\ No newline at end of file
-diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec
---- a/tools/gritsettings/resource_ids.spec
-+++ b/tools/gritsettings/resource_ids.spec
-@@ -567,6 +567,12 @@
-   "components/autofill/core/browser/autofill_address_rewriter_resources.grd":{
-     "includes": [2880]
-   },
-+  "components/user_scripts/renderer/resources/user_scripts_renderer_resources.grd": {
-+    "includes": [6000],
-+  },
-+  "components/user_scripts/browser/resources/browser_resources.grd": {
-+    "includes": [6020],
-+  },
-   # END components/ section.
- 
-   # START ios/ section.
--- 
-2.20.1
-

+ 2 - 2
build/patches/Hide-passwords-manager-link.patch

@@ -9,7 +9,7 @@ Subject: Hide passwords manager link
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java
-@@ -326,7 +326,7 @@ public class PasswordSettings extends PreferenceFragmentCompat
+@@ -319,7 +319,7 @@ public class PasswordSettings extends PreferenceFragmentCompat
              return;
          }
  
@@ -18,7 +18,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manage
  
          PreferenceGroup passwordParent;
          if (mSearchQuery == null) {
-@@ -406,7 +406,7 @@ public class PasswordSettings extends PreferenceFragmentCompat
+@@ -399,7 +399,7 @@ public class PasswordSettings extends PreferenceFragmentCompat
              return;
          }
  

+ 2 - 2
build/patches/Increase-number-of-autocomplete-matches-from-5-to-10.patch

@@ -11,16 +11,16 @@ Patch from https://github.com/Eloston/ungoogled-chromium/issues/814#issuecomment
 diff --git a/components/omnibox/browser/autocomplete_result.cc b/components/omnibox/browser/autocomplete_result.cc
 --- a/components/omnibox/browser/autocomplete_result.cc
 +++ b/components/omnibox/browser/autocomplete_result.cc
-@@ -67,7 +67,8 @@ struct MatchGURLHash {
+@@ -68,7 +68,8 @@ struct MatchGURLHash {
  // static
  size_t AutocompleteResult::GetMaxMatches(bool is_zero_suggest) {
  #if (defined(OS_ANDROID))
 -  constexpr size_t kDefaultMaxAutocompleteMatches = 5;
 +  // changed from 6, this needs to be double the value of default_max_matches_per_provider from components/omnibox/browser/omnibox_field_trial.cc
 +  constexpr size_t kDefaultMaxAutocompleteMatches = 10;
+   constexpr size_t kDefaultMaxZeroSuggestMatches = 15;
  #elif defined(OS_IOS)  // !defined(OS_ANDROID)
    constexpr size_t kDefaultMaxAutocompleteMatches = 6;
- #else                  // !defined(OS_ANDROID) && !defined(OS_IOS)
 diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc
 --- a/components/omnibox/browser/omnibox_field_trial.cc
 +++ b/components/omnibox/browser/omnibox_field_trial.cc

+ 8 - 8
build/patches/Inject-scripts-for-AMP-tracking-ads-and-video.patch

@@ -33,7 +33,7 @@ diff --git a/third_party/blink/renderer/core/dom/build.gni b/third_party/blink/r
 diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
 --- a/third_party/blink/renderer/core/dom/document.cc
 +++ b/third_party/blink/renderer/core/dom/document.cc
-@@ -275,6 +275,7 @@
+@@ -274,6 +274,7 @@
  #include "third_party/blink/renderer/core/page/scrolling/root_scroller_controller.h"
  #include "third_party/blink/renderer/core/page/scrolling/scroll_state_callback.h"
  #include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.h"
@@ -41,7 +41,7 @@ diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink
  #include "third_party/blink/renderer/core/page/scrolling/snap_coordinator.h"
  #include "third_party/blink/renderer/core/page/scrolling/text_fragment_anchor.h"
  #include "third_party/blink/renderer/core/page/scrolling/text_fragment_handler.h"
-@@ -343,6 +344,8 @@
+@@ -342,6 +343,8 @@
  #include "third_party/blink/renderer/platform/wtf/text/string_buffer.h"
  #include "third_party/blink/renderer/platform/wtf/text/text_encoding_registry.h"
  
@@ -49,8 +49,8 @@ diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink
 +
  #ifndef NDEBUG
  using WeakDocumentSet = blink::HeapHashSet<blink::WeakMember<blink::Document>>;
- static WeakDocumentSet& liveDocumentSet();
-@@ -6532,6 +6535,61 @@ void Document::setAllowDeclarativeShadowRoots(bool val) {
+ static WeakDocumentSet& LiveDocumentSet();
+@@ -6521,6 +6524,61 @@ void Document::setAllowDeclarativeShadowRoots(bool val) {
        val ? AllowState::kAllow : AllowState::kDeny;
  }
  
@@ -112,9 +112,9 @@ diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink
  void Document::FinishedParsing() {
    DCHECK(!GetScriptableDocumentParser() || !parser_->IsParsing());
    DCHECK(!GetScriptableDocumentParser() || ready_state_ != kLoading);
-@@ -6587,6 +6645,10 @@ void Document::FinishedParsing() {
-     if (frame->GetFrameScheduler())
-       frame->GetFrameScheduler()->OnDomContentLoaded();
+@@ -6579,6 +6637,10 @@ void Document::FinishedParsing() {
+     if (frame->IsMainFrame() && ShouldMarkFontPerformance())
+       FontPerformance::MarkDomContentLoaded();
  
 +    if (!IsPrefetchOnly()) {
 +       injectScripts();
@@ -126,7 +126,7 @@ diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink
 diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h
 --- a/third_party/blink/renderer/core/dom/document.h
 +++ b/third_party/blink/renderer/core/dom/document.h
-@@ -1772,6 +1772,9 @@ class CORE_EXPORT Document : public ContainerNode,
+@@ -1776,6 +1776,9 @@ class CORE_EXPORT Document : public ContainerNode,
    void AddAXContext(AXContext*);
    void RemoveAXContext(AXContext*);
  

+ 13 - 14
build/patches/JIT-less-toggle.patch

@@ -3,17 +3,17 @@ Date: Fri, 18 Jun 2021 03:34:20 +0000
 Subject: JIT-less toggle
 
 ---
- chrome/android/java/res/xml/privacy_preferences.xml  |  5 +++++
- .../browser/privacy/settings/PrivacySettings.java    | 12 ++++++++++++
- .../ui/android/strings/android_chrome_strings.grd    |  7 +++++++
- .../browser/BrowserStartupControllerImpl.java        |  1 +
- .../chromium/content/browser/DeviceUtilsImpl.java    |  8 ++++++++
- 5 files changed, 33 insertions(+)
+ chrome/android/java/res/xml/privacy_preferences.xml   |  5 +++++
+ .../browser/privacy/settings/PrivacySettings.java     | 11 +++++++++++
+ .../ui/android/strings/android_chrome_strings.grd     |  7 +++++++
+ .../content/browser/BrowserStartupControllerImpl.java |  1 +
+ .../org/chromium/content/browser/DeviceUtilsImpl.java |  8 ++++++++
+ 5 files changed, 32 insertions(+)
 
 diff --git a/chrome/android/java/res/xml/privacy_preferences.xml b/chrome/android/java/res/xml/privacy_preferences.xml
 --- a/chrome/android/java/res/xml/privacy_preferences.xml
 +++ b/chrome/android/java/res/xml/privacy_preferences.xml
-@@ -32,6 +32,11 @@
+@@ -37,6 +37,11 @@
          android:title="@string/preload_pages_title"
          android:summary="@string/preload_pages_summary"
          android:persistent="false"/>
@@ -36,7 +36,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
  import android.os.Build;
  import android.content.SharedPreferences;
  import android.os.Bundle;
-@@ -79,6 +80,7 @@ public class PrivacySettings
+@@ -83,6 +84,7 @@ public class PrivacySettings
      private static final String PREF_SEARCH_SUGGESTIONS = "search_suggestions";
      private static final String PREF_CONTEXTUAL_SEARCH = "contextual_search";
      public static final String PREF_AUTOFILL_ASSISTANT = "autofill_assistant";
@@ -44,7 +44,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
      private ChromeSwitchPreference mSearchSuggestions;
      private @Nullable ChromeSwitchPreference mAutofillAssistant;
      private @Nullable Preference mContextualSearch;
-@@ -200,6 +202,10 @@ public class PrivacySettings
+@@ -242,6 +244,10 @@ public class PrivacySettings
                      .setBoolean(Pref.CAN_MAKE_PAYMENT_ENABLED, (boolean) newValue);
          } else if (PREF_SEARCH_SUGGESTIONS.equals(key)) {
              prefService.setBoolean(Pref.SEARCH_SUGGEST_ENABLED, (boolean) newValue);
@@ -55,23 +55,22 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
          } else if (PREF_AUTOFILL_ASSISTANT.equals(key)) {
              mSharedPreferencesManager.writeBoolean(
                  ChromePreferenceKeys.AUTOFILL_ASSISTANT_ENABLED, (boolean) newValue);
-@@ -279,6 +285,12 @@ public class PrivacySettings
-             historyInIncognitoPref.setChecked(
+@@ -325,6 +331,11 @@ public class PrivacySettings
                      prefService.getBoolean(Pref.INCOGNITO_TAB_HISTORY_ENABLED));
          }
-+
+ 
 +        ChromeSwitchPreference forceNoJit =
 +                (ChromeSwitchPreference) findPreference(PREF_FORCE_NO_JIT);
 +        forceNoJit.setOnPreferenceChangeListener(this);
 +        forceNoJit.setManagedPreferenceDelegate(mManagedPreferenceDelegate);
 +
+         updateIncognitoReauthPreference();
      }
  
-     private ChromeManagedPreferenceDelegate createManagedPreferenceDelegate() {
 diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
 +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
-@@ -944,6 +944,13 @@ Privacy Sandbox trials are still in active development and are available in sele
+@@ -952,6 +952,13 @@ Privacy Sandbox trials are still in active development and are available in sele
          Please verify that this is a valid provider or try again later
        </message>
  

+ 2 - 2
build/patches/Keep-empty-tabs-between-sessions.patch

@@ -10,7 +10,7 @@ Subject: Keep empty tabs between sessions
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPersistentStore.java
-@@ -701,15 +701,6 @@ public class TabPersistentStore {
+@@ -690,15 +690,6 @@ public class TabPersistentStore {
                      .createFrozenTab(tabState, serializedCriticalPersistedTabData, tabToRestore.id,
                              isIncognito, restoredIndex);
          } else {
@@ -29,7 +29,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabPer
 diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabData.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabData.java
 --- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabData.java
 +++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/state/CriticalPersistedTabData.java
-@@ -438,10 +438,6 @@ public class CriticalPersistedTabData extends PersistedTabData {
+@@ -440,10 +440,6 @@ public class CriticalPersistedTabData extends PersistedTabData {
          if (getUrl() == null || TextUtils.isEmpty(getUrl().getSpec())) {
              return false;
          }

+ 11 - 13
build/patches/Logcat-crash-reports-UI.patch

@@ -127,7 +127,7 @@ diff --git a/chrome/browser/crash_upload_list/crash_upload_list_android.cc b/chr
 diff --git a/chrome/browser/crash_upload_list/crash_upload_list_android.h b/chrome/browser/crash_upload_list/crash_upload_list_android.h
 --- a/chrome/browser/crash_upload_list/crash_upload_list_android.h
 +++ b/chrome/browser/crash_upload_list/crash_upload_list_android.h
-@@ -32,6 +32,7 @@ class CrashUploadListAndroid : public TextLogUploadList {
+@@ -35,6 +35,7 @@ class CrashUploadListAndroid : public TextLogUploadList {
  
    std::vector<UploadInfo> LoadUploadList() override;
    void RequestSingleUpload(const std::string& local_id) override;
@@ -155,7 +155,7 @@ diff --git a/chrome/browser/net/chrome_network_delegate.cc b/chrome/browser/net/
 diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
 --- a/chrome/browser/ui/BUILD.gn
 +++ b/chrome/browser/ui/BUILD.gn
-@@ -594,6 +594,7 @@ static_library("ui") {
+@@ -616,6 +616,7 @@ static_library("ui") {
      "//third_party/re2",
      "//third_party/webrtc_overrides:webrtc_component",
      "//third_party/zlib",
@@ -201,10 +201,10 @@ diff --git a/chrome/browser/ui/webui/crashes_ui.cc b/chrome/browser/ui/webui/cra
   public:
 -  CrashesDOMHandler();
 +  CrashesDOMHandler(content::WebContents* web_contents);
-   ~CrashesDOMHandler() override;
  
-   // WebUIMessageHandler implementation.
-@@ -96,6 +111,8 @@ class CrashesDOMHandler : public WebUIMessageHandler {
+   CrashesDOMHandler(const CrashesDOMHandler&) = delete;
+   CrashesDOMHandler& operator=(const CrashesDOMHandler&) = delete;
+@@ -100,6 +115,8 @@ class CrashesDOMHandler : public WebUIMessageHandler {
    // Asynchronously fetches the list of crashes. Called from JS.
    void HandleRequestCrashes(base::Value::ConstListView args);
  
@@ -213,7 +213,7 @@ diff --git a/chrome/browser/ui/webui/crashes_ui.cc b/chrome/browser/ui/webui/cra
  #if BUILDFLAG(IS_CHROMEOS_ASH)
    // Asynchronously triggers crash uploading. Called from JS.
    void HandleRequestUploads(base::Value::ConstListView args);
-@@ -107,15 +124,28 @@ class CrashesDOMHandler : public WebUIMessageHandler {
+@@ -111,13 +128,26 @@ class CrashesDOMHandler : public WebUIMessageHandler {
    // Asynchronously requests a user triggered upload. Called from JS.
    void HandleRequestSingleCrashUpload(base::Value::ConstListView args);
  
@@ -232,8 +232,6 @@ diff --git a/chrome/browser/ui/webui/crashes_ui.cc b/chrome/browser/ui/webui/cra
    bool list_available_;
    bool first_load_;
 +  content::WebContents* web_contents_;
- 
-   DISALLOW_COPY_AND_ASSIGN(CrashesDOMHandler);
  };
  
 -CrashesDOMHandler::CrashesDOMHandler()
@@ -244,7 +242,7 @@ diff --git a/chrome/browser/ui/webui/crashes_ui.cc b/chrome/browser/ui/webui/cra
    upload_list_ = CreateCrashUploadList();
  }
  
-@@ -142,10 +172,24 @@ void CrashesDOMHandler::RegisterMessages() {
+@@ -144,10 +174,24 @@ void CrashesDOMHandler::RegisterMessages() {
        crash_reporter::kCrashesUIRequestSingleCrashUpload,
        base::BindRepeating(&CrashesDOMHandler::HandleRequestSingleCrashUpload,
                            base::Unretained(this)));
@@ -269,7 +267,7 @@ diff --git a/chrome/browser/ui/webui/crashes_ui.cc b/chrome/browser/ui/webui/cra
    if (first_load_) {
      first_load_ = false;
      if (list_available_)
-@@ -178,8 +222,7 @@ void CrashesDOMHandler::OnUploadListAvailable() {
+@@ -180,8 +224,7 @@ void CrashesDOMHandler::OnUploadListAvailable() {
  }
  
  void CrashesDOMHandler::UpdateUI() {
@@ -279,7 +277,7 @@ diff --git a/chrome/browser/ui/webui/crashes_ui.cc b/chrome/browser/ui/webui/cra
  
    bool system_crash_reporter = false;
  #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
-@@ -235,14 +278,112 @@ void CrashesDOMHandler::UpdateUI() {
+@@ -237,14 +280,112 @@ void CrashesDOMHandler::UpdateUI() {
  
  void CrashesDOMHandler::HandleRequestSingleCrashUpload(
      base::Value::ConstListView args) {
@@ -398,7 +396,7 @@ diff --git a/chrome/browser/ui/webui/crashes_ui.cc b/chrome/browser/ui/webui/cra
  }
  
  }  // namespace
-@@ -254,7 +395,8 @@ void CrashesDOMHandler::HandleRequestSingleCrashUpload(
+@@ -256,7 +397,8 @@ void CrashesDOMHandler::HandleRequestSingleCrashUpload(
  ///////////////////////////////////////////////////////////////////////////////
  
  CrashesUI::CrashesUI(content::WebUI* web_ui) : WebUIController(web_ui) {
@@ -851,7 +849,7 @@ diff --git a/components/upload_list/upload_list.h b/components/upload_list/uploa
    };
  
    UploadList();
-@@ -92,6 +95,12 @@ class UploadList : public base::RefCountedThreadSafe<UploadList> {
+@@ -95,6 +98,12 @@ class UploadList : public base::RefCountedThreadSafe<UploadList> {
    // Must be called only after a Load() callback has been received.
    void GetUploads(size_t max_count, std::vector<UploadInfo>* uploads);
  

+ 3 - 3
build/patches/Modify-default-preferences.patch

@@ -33,7 +33,7 @@ diff --git a/chrome/browser/background/background_mode_manager.cc b/chrome/brows
 diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
 --- a/chrome/browser/chrome_content_browser_client.cc
 +++ b/chrome/browser/chrome_content_browser_client.cc
-@@ -1203,7 +1203,7 @@ void ChromeContentBrowserClient::RegisterLocalStatePrefs(
+@@ -1267,7 +1267,7 @@ void ChromeContentBrowserClient::RegisterLocalStatePrefs(
  void ChromeContentBrowserClient::RegisterProfilePrefs(
      user_prefs::PrefRegistrySyncable* registry) {
    registry->RegisterBooleanPref(prefs::kDisable3DAPIs, false);
@@ -69,7 +69,7 @@ diff --git a/chrome/browser/net/prediction_options.h b/chrome/browser/net/predic
 diff --git a/chrome/browser/profiles/profile.cc b/chrome/browser/profiles/profile.cc
 --- a/chrome/browser/profiles/profile.cc
 +++ b/chrome/browser/profiles/profile.cc
-@@ -281,7 +281,7 @@ const char Profile::kProfileKey[] = "__PROFILE__";
+@@ -276,7 +276,7 @@ const char Profile::kProfileKey[] = "__PROFILE__";
  void Profile::RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
    registry->RegisterBooleanPref(
        prefs::kSearchSuggestEnabled,
@@ -123,7 +123,7 @@ diff --git a/chrome/service/cloud_print/connector_settings.cc b/chrome/service/c
 diff --git a/components/autofill/core/browser/browser_autofill_manager.h b/components/autofill/core/browser/browser_autofill_manager.h
 --- a/components/autofill/core/browser/browser_autofill_manager.h
 +++ b/components/autofill/core/browser/browser_autofill_manager.h
-@@ -691,9 +691,9 @@ class BrowserAutofillManager : public AutofillManager,
+@@ -695,9 +695,9 @@ class BrowserAutofillManager : public AutofillManager,
    std::unique_ptr<CreditCardFormEventLogger> credit_card_form_event_logger_;
  
    // Have we logged whether Autofill is enabled for this page load?

+ 11 - 11
build/patches/Move-some-account-settings-back-to-privacy-settings.patch

@@ -12,7 +12,7 @@ Search suggestions, autofill assistant and contextual search
 diff --git a/chrome/android/java/res/xml/privacy_preferences.xml b/chrome/android/java/res/xml/privacy_preferences.xml
 --- a/chrome/android/java/res/xml/privacy_preferences.xml
 +++ b/chrome/android/java/res/xml/privacy_preferences.xml
-@@ -59,4 +59,24 @@
+@@ -64,4 +64,24 @@
          android:key="privacy_sandbox"
          android:title="@string/prefs_privacy_sandbox"
          android:fragment="org.chromium.chrome.browser.privacy_sandbox.PrivacySandboxSettingsFragment"/>
@@ -47,8 +47,8 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
 +import org.chromium.chrome.browser.flags.ChromeFeatureList;
  import org.chromium.chrome.browser.feedback.HelpAndFeedbackLauncherImpl;
  import org.chromium.chrome.browser.flags.ChromeFeatureList;
- import org.chromium.chrome.browser.preferences.Pref;
-@@ -44,6 +45,13 @@ import org.chromium.components.user_prefs.UserPrefs;
+ import org.chromium.chrome.browser.incognito.reauth.IncognitoReauthManager;
+@@ -47,6 +48,13 @@ import org.chromium.components.user_prefs.UserPrefs;
  import org.chromium.ui.text.NoUnderlineClickableSpan;
  import org.chromium.ui.text.SpanApplier;
  
@@ -62,7 +62,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
  /**
   * Fragment to keep track of the all the privacy related preferences.
   */
-@@ -66,6 +74,18 @@ public class PrivacySettings
+@@ -70,6 +78,18 @@ public class PrivacySettings
  
      private static final String PREF_CLOSE_TABS_ON_EXIT = "close_tabs_on_exit";
  
@@ -81,7 +81,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
      private ManagedPreferenceDelegate mManagedPreferenceDelegate;
  
      @Override
-@@ -95,6 +115,29 @@ public class PrivacySettings
+@@ -108,6 +128,29 @@ public class PrivacySettings
  
          mManagedPreferenceDelegate = createManagedPreferenceDelegate();
  
@@ -111,7 +111,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
          ChromeSwitchPreference canMakePaymentPref =
                  (ChromeSwitchPreference) findPreference(PREF_CAN_MAKE_PAYMENT);
          canMakePaymentPref.setOnPreferenceChangeListener(this);
-@@ -155,6 +198,11 @@ public class PrivacySettings
+@@ -197,6 +240,11 @@ public class PrivacySettings
          } else if (PREF_CAN_MAKE_PAYMENT.equals(key)) {
              UserPrefs.get(Profile.getLastUsedRegularProfile())
                      .setBoolean(Pref.CAN_MAKE_PAYMENT_ENABLED, (boolean) newValue);
@@ -123,7 +123,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
          } else if (PREF_NETWORK_PREDICTIONS.equals(key)) {
              PrivacyPreferencesManagerImpl.getInstance().setNetworkPredictionEnabled(
                      (boolean) newValue);
-@@ -174,6 +222,16 @@ public class PrivacySettings
+@@ -219,6 +267,16 @@ public class PrivacySettings
  
      public static final String PREF_INCOGNITO_TAB_HISTORY_ENABLED = "incognito_history_enabled";
  
@@ -140,10 +140,10 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
      @Override
      public void onResume() {
          super.onResume();
-@@ -184,7 +242,7 @@ public class PrivacySettings
-      * Updates the summaries for several preferences.
+@@ -229,7 +287,7 @@ public class PrivacySettings
+      * Updates the preferences.
       */
-     public void updateSummaries() {
+     public void updatePreferences() {
 -        PrefService prefService = UserPrefs.get(Profile.getLastUsedRegularProfile());
 +        mSearchSuggestions.setChecked(prefService.getBoolean(Pref.SEARCH_SUGGEST_ENABLED));
  
@@ -152,7 +152,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/setting
 diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
 +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
-@@ -396,6 +396,10 @@ CHAR_LIMIT guidelines:
+@@ -405,6 +405,10 @@ CHAR_LIMIT guidelines:
          No statistics or crash reports are sent to Google
        </message>
  

+ 23 - 23
build/patches/Multiple-fingerprinting-mitigations.patch

@@ -56,7 +56,7 @@ Added flag --fingerprinting-canvas-image-data-noise to disable Canvas image data
 diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
 --- a/chrome/browser/BUILD.gn
 +++ b/chrome/browser/BUILD.gn
-@@ -2299,6 +2299,7 @@ static_library("browser") {
+@@ -2316,6 +2316,7 @@ static_library("browser") {
      "//services/device/public/cpp:device_features",
      "//services/device/public/cpp/serial:switches",
      "//services/device/public/cpp/usb",
@@ -67,7 +67,7 @@ diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
 diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 --- a/chrome/browser/about_flags.cc
 +++ b/chrome/browser/about_flags.cc
-@@ -182,6 +182,7 @@
+@@ -186,6 +186,7 @@
  #include "services/media_session/public/cpp/features.h"
  #include "services/network/public/cpp/features.h"
  #include "services/network/public/cpp/network_switches.h"
@@ -75,7 +75,7 @@ diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
  #include "storage/browser/quota/quota_features.h"
  #include "third_party/blink/public/common/features.h"
  #include "third_party/blink/public/common/forcedark/forcedark_switches.h"
-@@ -2860,6 +2861,20 @@ const FeatureEntry kFeatureEntries[] = {
+@@ -2824,6 +2825,20 @@ const FeatureEntry kFeatureEntries[] = {
       flag_descriptions::kWebrtcUseMinMaxVEADimensionsName,
       flag_descriptions::kWebrtcUseMinMaxVEADimensionsDescription, kOsAll,
       FEATURE_VALUE_TYPE(blink::features::kWebRtcUseMinMaxVEADimensions)},
@@ -99,7 +99,7 @@ diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
 --- a/content/browser/BUILD.gn
 +++ b/content/browser/BUILD.gn
-@@ -221,6 +221,7 @@ source_set("browser") {
+@@ -223,6 +223,7 @@ source_set("browser") {
      "//third_party/libyuv",
      "//third_party/re2",
      "//third_party/sqlite",
@@ -110,7 +110,7 @@ diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
 diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
 --- a/content/browser/renderer_host/render_process_host_impl.cc
 +++ b/content/browser/renderer_host/render_process_host_impl.cc
-@@ -213,6 +213,8 @@
+@@ -212,6 +212,8 @@
  #include "services/tracing/public/cpp/system_tracing_service.h"
  #endif
  
@@ -119,7 +119,7 @@ diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content
  #if defined(OS_WIN)
  #include "base/win/scoped_com_initializer.h"
  #include "base/win/windows_version.h"
-@@ -3427,6 +3429,9 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
+@@ -3413,6 +3415,9 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
      switches::kDisableBreakpad,
      switches::kDisableDatabases,
      switches::kDisableFileSystem,
@@ -152,7 +152,7 @@ diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.
  #if defined(OS_ANDROID)
  #include "base/android/build_info.h"
  #endif
-@@ -542,6 +544,13 @@ void SetCustomizedRuntimeFeaturesFromCombinedArgs(
+@@ -540,6 +542,13 @@ void SetCustomizedRuntimeFeaturesFromCombinedArgs(
    if (!command_line.HasSwitch(switches::kDisableYUVImageDecoding) &&
        base::FeatureList::IsEnabled(
            blink::features::kDecodeLossyWebPImagesToYUV)) {
@@ -169,7 +169,7 @@ diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.
 diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_party/blink/public/platform/web_runtime_features.h
 --- a/third_party/blink/public/platform/web_runtime_features.h
 +++ b/third_party/blink/public/platform/web_runtime_features.h
-@@ -217,6 +217,9 @@ class WebRuntimeFeatures {
+@@ -216,6 +216,9 @@ class WebRuntimeFeatures {
    BLINK_PLATFORM_EXPORT static void EnableAutomationControlled(bool);
    BLINK_PLATFORM_EXPORT static void EnableAutoplayIgnoresWebAudio(bool);
    BLINK_PLATFORM_EXPORT static void EnableMediaControlsExpandGesture(bool);
@@ -178,7 +178,7 @@ diff --git a/third_party/blink/public/platform/web_runtime_features.h b/third_pa
 +  BLINK_PLATFORM_EXPORT static void EnableFingerprintingCanvasImageDataNoise(bool);
    BLINK_PLATFORM_EXPORT static void EnableGetDisplayMedia(bool);
    BLINK_PLATFORM_EXPORT static void EnableAllowSyncXHRInPageDismissal(bool);
-   BLINK_PLATFORM_EXPORT static void
+   BLINK_PLATFORM_EXPORT static void EnableSignedExchangeSubresourcePrefetch(
 diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
 --- a/third_party/blink/renderer/core/dom/document.cc
 +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -190,7 +190,7 @@ diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink
  #include "base/time/time.h"
  #include "cc/input/overscroll_behavior.h"
  #include "cc/input/scroll_snap_data.h"
-@@ -2149,6 +2150,23 @@ void Document::UpdateStyleAndLayoutTreeForThisDocument() {
+@@ -2148,6 +2149,23 @@ void Document::UpdateStyleAndLayoutTreeForThisDocument() {
  #if DCHECK_IS_ON()
    AssertLayoutTreeUpdated(*this, true /* allow_dirty_container_subtrees */);
  #endif
@@ -228,7 +228,7 @@ diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/
    AtomicString visibilityState() const;
    bool IsPageVisible() const;
    bool hidden() const;
-@@ -2077,6 +2081,9 @@ class CORE_EXPORT Document : public ContainerNode,
+@@ -2081,6 +2085,9 @@ class CORE_EXPORT Document : public ContainerNode,
  
    base::ElapsedTimer start_time_;
  
@@ -241,7 +241,7 @@ diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/
 diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
 --- a/third_party/blink/renderer/core/dom/element.cc
 +++ b/third_party/blink/renderer/core/dom/element.cc
-@@ -2115,6 +2115,11 @@ DOMRectList* Element::getClientRects() {
+@@ -2114,6 +2114,11 @@ DOMRectList* Element::getClientRects() {
    DCHECK(element_layout_object);
    GetDocument().AdjustFloatQuadsForScrollAndAbsoluteZoom(
        quads, *element_layout_object);
@@ -253,7 +253,7 @@ diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/
    return MakeGarbageCollected<DOMRectList>(quads);
  }
  
-@@ -2132,6 +2137,9 @@ FloatRect Element::GetBoundingClientRectNoLifecycleUpdate() const {
+@@ -2131,6 +2136,9 @@ FloatRect Element::GetBoundingClientRectNoLifecycleUpdate() const {
    DCHECK(element_layout_object);
    GetDocument().AdjustFloatRectForScrollAndAbsoluteZoom(result,
                                                          *element_layout_object);
@@ -266,7 +266,7 @@ diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/
 diff --git a/third_party/blink/renderer/core/dom/range.cc b/third_party/blink/renderer/core/dom/range.cc
 --- a/third_party/blink/renderer/core/dom/range.cc
 +++ b/third_party/blink/renderer/core/dom/range.cc
-@@ -1595,6 +1595,12 @@ DOMRectList* Range::getClientRects() const {
+@@ -1598,6 +1598,12 @@ DOMRectList* Range::getClientRects() const {
    Vector<FloatQuad> quads;
    GetBorderAndTextQuads(quads);
  
@@ -279,7 +279,7 @@ diff --git a/third_party/blink/renderer/core/dom/range.cc b/third_party/blink/re
    return MakeGarbageCollected<DOMRectList>(quads);
  }
  
-@@ -1722,7 +1728,11 @@ FloatRect Range::BoundingRect() const {
+@@ -1733,7 +1739,11 @@ FloatRect Range::BoundingRect() const {
  
    // If all rects are empty, return the first rect.
    if (result.IsEmpty() && !quads.IsEmpty())
@@ -335,15 +335,15 @@ diff --git a/third_party/blink/renderer/core/html/canvas/text_metrics.h b/third_
 diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
 --- a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
 +++ b/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_context_2d.cc
-@@ -27,6 +27,7 @@
+@@ -29,6 +29,7 @@
  #include "third_party/blink/renderer/platform/geometry/float_quad.h"
  #include "third_party/blink/renderer/platform/graphics/bitmap_image.h"
  #include "third_party/blink/renderer/platform/graphics/graphics_context.h"
 +#include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
  #include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
  #include "third_party/blink/renderer/platform/graphics/stroke_data.h"
- #include "third_party/blink/renderer/platform/heap/heap.h"
-@@ -2273,6 +2274,10 @@ ImageData* BaseRenderingContext2D::getImageDataInternal(
+ #include "third_party/blink/renderer/platform/graphics/video_frame_image_util.h"
+@@ -2311,6 +2312,10 @@ ImageData* BaseRenderingContext2D::getImageDataInternal(
            snapshot->PaintImageForCurrentFrame().GetSkImageInfo().bounds();
        DCHECK(!bounds.intersect(SkIRect::MakeXYWH(sx, sy, sw, sh)));
      }
@@ -357,7 +357,7 @@ diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/base_rendering_c
 diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
 --- a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
 +++ b/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
-@@ -963,9 +963,15 @@ TextMetrics* CanvasRenderingContext2D::measureText(const String& text) {
+@@ -912,9 +912,15 @@ TextMetrics* CanvasRenderingContext2D::measureText(const String& text) {
    TextDirection direction =
        ToTextDirection(GetState().GetDirection(), canvas());
  
@@ -377,7 +377,7 @@ diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering
 diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn
 --- a/third_party/blink/renderer/platform/BUILD.gn
 +++ b/third_party/blink/renderer/platform/BUILD.gn
-@@ -1639,7 +1639,9 @@ component("platform") {
+@@ -1645,7 +1645,9 @@ component("platform") {
      "//third_party/blink/renderer:non_test_config",
    ]
  
@@ -388,7 +388,7 @@ diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/re
  
    allow_circular_includes_from = [
      "//third_party/blink/renderer/platform/blob",
-@@ -1707,6 +1709,7 @@ component("platform") {
+@@ -1712,6 +1714,7 @@ component("platform") {
      "//third_party/blink/public/strings",
      "//third_party/blink/renderer/platform/wtf",
      "//third_party/ced",
@@ -399,7 +399,7 @@ diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/re
 diff --git a/third_party/blink/renderer/platform/exported/web_runtime_features.cc b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
 --- a/third_party/blink/renderer/platform/exported/web_runtime_features.cc
 +++ b/third_party/blink/renderer/platform/exported/web_runtime_features.cc
-@@ -700,4 +700,16 @@ void WebRuntimeFeatures::EnableCLSScrollAnchoring(bool enable) {
+@@ -689,4 +689,16 @@ void WebRuntimeFeatures::EnableCLSScrollAnchoring(bool enable) {
    RuntimeEnabledFeatures::SetCLSScrollAnchoringEnabled(enable);
  }
  
@@ -632,7 +632,7 @@ diff --git a/third_party/blink/renderer/platform/graphics/static_bitmap_image.h
 diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
-@@ -1029,6 +1029,15 @@
+@@ -1039,6 +1039,15 @@
        origin_trial_allows_third_party: true,
        status: "experimental",
      },

+ 0 - 33
build/patches/Never-send-any-crash-upload-data.patch

@@ -1,33 +0,0 @@
-From: csagan5 <32685696+csagan5@users.noreply.github.com>
-Date: Mon, 12 Feb 2018 21:43:35 +0100
-Subject: Never send any crash upload data
-
----
- chrome/browser/tracing/crash_service_uploader.cc | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
-diff --git a/chrome/browser/tracing/crash_service_uploader.cc b/chrome/browser/tracing/crash_service_uploader.cc
---- a/chrome/browser/tracing/crash_service_uploader.cc
-+++ b/chrome/browser/tracing/crash_service_uploader.cc
-@@ -128,14 +128,16 @@ void TraceCrashServiceUploader::DoUpload(
-     UploadDoneCallback done_callback) {
-   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- 
--  progress_callback_ = progress_callback;
-+  std::move(done_callback).Run(false, "crash uploads are disabled");
-+
-+/*  progress_callback_ = progress_callback;
-   done_callback_ = std::move(done_callback);
- 
-   base::ThreadPool::PostTask(
-       FROM_HERE, {base::TaskPriority::BEST_EFFORT},
-       base::BindOnce(&TraceCrashServiceUploader::DoCompressOnBackgroundThread,
-                      base::Unretained(this), file_contents, upload_mode,
--                     upload_url_, std::move(metadata)));
-+                     upload_url_, std::move(metadata)));*/
- }
- 
- void TraceCrashServiceUploader::DoCompressOnBackgroundThread(
--- 
-2.20.1
-

+ 1 - 1
build/patches/Offer-builtin-autocomplete-for-chrome-flags.patch

@@ -9,7 +9,7 @@ Subject: Offer builtin autocomplete for chrome://flags
 diff --git a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
 --- a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
 +++ b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.cc
-@@ -359,6 +359,8 @@ std::vector<std::u16string> ChromeAutocompleteProviderClient::GetBuiltinURLs() {
+@@ -366,6 +366,8 @@ std::vector<std::u16string> ChromeAutocompleteProviderClient::GetBuiltinURLs() {
  std::vector<std::u16string>
  ChromeAutocompleteProviderClient::GetBuiltinsToProvideAsUserTypes() {
    std::vector<std::u16string> builtins_to_provide;

+ 1 - 1
build/patches/Override-UA-client-hint-for-model.patch

@@ -29,7 +29,7 @@ diff --git a/content/common/user_agent.cc b/content/common/user_agent.cc
 diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
 --- a/content/public/common/content_features.cc
 +++ b/content/public/common/content_features.cc
-@@ -326,7 +326,7 @@ const base::Feature kExtraSafelistedRequestHeadersForOutOfBlinkCors{
+@@ -310,7 +310,7 @@ const base::Feature kExtraSafelistedRequestHeadersForOutOfBlinkCors{
  
  // Controls whether Client Hints are guarded by Permissions Policy.
  const base::Feature kFeaturePolicyForClientHints{

+ 6 - 6
build/patches/Reduce-HTTP-headers-in-DoH-requests-to-bare-minimum.patch

@@ -27,7 +27,7 @@ diff --git a/net/base/load_flags_list.h b/net/base/load_flags_list.h
 diff --git a/net/dns/dns_transaction.cc b/net/dns/dns_transaction.cc
 --- a/net/dns/dns_transaction.cc
 +++ b/net/dns/dns_transaction.cc
-@@ -434,7 +434,7 @@ class DnsHTTPAttempt : public DnsAttempt, public URLRequest::Delegate {
+@@ -437,7 +437,7 @@ class DnsHTTPAttempt : public DnsAttempt, public URLRequest::Delegate {
      // Disable secure DNS for any DoH server hostname lookups to avoid deadlock.
      request_->SetSecureDnsPolicy(SecureDnsPolicy::kDisable);
      request_->SetLoadFlags(request_->load_flags() | LOAD_DISABLE_CACHE |
@@ -39,7 +39,7 @@ diff --git a/net/dns/dns_transaction.cc b/net/dns/dns_transaction.cc
 diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
 --- a/net/url_request/url_request_http_job.cc
 +++ b/net/url_request/url_request_http_job.cc
-@@ -300,6 +300,7 @@ void URLRequestHttpJob::Start() {
+@@ -319,6 +319,7 @@ void URLRequestHttpJob::Start() {
    // plugin could set a referrer although sending the referrer is inhibited.
    request_info_.extra_headers.RemoveHeader(HttpRequestHeaders::kReferer);
  
@@ -47,7 +47,7 @@ diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_reque
    // Our consumer should have made sure that this is a safe referrer (e.g. via
    // URLRequestJob::ComputeReferrerForPolicy).
    if (referrer.is_valid()) {
-@@ -307,11 +308,14 @@ void URLRequestHttpJob::Start() {
+@@ -326,11 +327,14 @@ void URLRequestHttpJob::Start() {
      request_info_.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
                                            referer_value);
    }
@@ -62,7 +62,7 @@ diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_reque
  
    AddExtraHeaders();
    AddCookieHeaderAndStart();
-@@ -526,6 +530,7 @@ void URLRequestHttpJob::AddExtraHeaders() {
+@@ -552,6 +556,7 @@ void URLRequestHttpJob::AddExtraHeaders() {
        if (request_->Supports(SourceStream::SourceType::TYPE_DEFLATE)) {
          advertised_encoding_names.push_back("deflate");
        }
@@ -70,7 +70,7 @@ diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_reque
        // Advertise "br" encoding only if transferred data is opaque to proxy.
        if (request()->context()->enable_brotli() &&
            request_->Supports(SourceStream::SourceType::TYPE_BROTLI)) {
-@@ -534,6 +539,7 @@ void URLRequestHttpJob::AddExtraHeaders() {
+@@ -560,6 +565,7 @@ void URLRequestHttpJob::AddExtraHeaders() {
            advertised_encoding_names.push_back("br");
          }
        }
@@ -78,7 +78,7 @@ diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_reque
        if (!advertised_encoding_names.empty()) {
          // Tell the server what compression formats are supported.
          request_info_.extra_headers.SetHeader(
-@@ -543,7 +549,7 @@ void URLRequestHttpJob::AddExtraHeaders() {
+@@ -569,7 +575,7 @@ void URLRequestHttpJob::AddExtraHeaders() {
      }
    }
  

+ 1 - 1
build/patches/Remove-EV-certificates.patch

@@ -66,7 +66,7 @@ diff --git a/net/cert/ev_root_ca_metadata.h b/net/cert/ev_root_ca_metadata.h
  #endif
  
  namespace base {
-@@ -62,12 +62,10 @@ class NET_EXPORT_PRIVATE EVRootCAMetadata {
+@@ -65,12 +65,10 @@ class NET_EXPORT_PRIVATE EVRootCAMetadata {
    bool HasEVPolicyOIDGivenBytes(const SHA256HashValue& fingerprint,
                                  const der::Input& policy_oid) const;
  

+ 3 - 3
build/patches/Remove-SMS-integration.patch

@@ -13,8 +13,8 @@ Subject: Remove SMS integration
 diff --git a/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/AppLocaleUtils.java b/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/AppLocaleUtils.java
 --- a/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/AppLocaleUtils.java
 +++ b/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/AppLocaleUtils.java
-@@ -69,44 +69,6 @@ public class AppLocaleUtils {
-                 ChromePreferenceKeys.APPLICATION_OVERRIDE_LANGUAGE, SYSTEM_LANGUAGE_VALUE);
+@@ -70,44 +70,6 @@ public class AppLocaleUtils {
+                 ChromePreferenceKeys.APPLICATION_OVERRIDE_LANGUAGE, APP_LOCALE_USE_SYSTEM_LANGUAGE);
      }
  
 -    /**
@@ -48,7 +48,7 @@ diff --git a/chrome/browser/language/android/java/src/org/chromium/chrome/browse
 -        // If this is not a bundle build or the default system language is being used the language
 -        // split should not be installed. Instead indicate that the listener completed successfully
 -        // since the language resources will already be present.
--        if (!BundleUtils.isBundle() || isDefaultSystemLanguage(languageName)) {
+-        if (!BundleUtils.isBundle() || isFollowSystemLanguage(languageName)) {
 -            wrappedListener.onComplete(true);
 -        } else {
 -            LanguageSplitInstaller.getInstance().installLanguage(languageName, wrappedListener);

+ 44 - 80
build/patches/Remove-binary-blob-integrations.patch

@@ -36,7 +36,6 @@ Parts of this patch were developed by csagan5, uazo and others.
  .../inline/FakeAppUpdateManagerWrapper.java   |  60 +-
  .../inline/InlineUpdateControllerFactory.java |  16 -
  .../inline/PlayInlineUpdateController.java    | 226 +-------
- .../settings/PasswordSettings.java            |  14 -
  .../modules/chrome_feature_modules.gni        |   3 -
  chrome/browser/BUILD.gn                       |   2 -
  chrome/browser/language/android/BUILD.gn      |   2 -
@@ -59,7 +58,7 @@ Parts of this patch were developed by csagan5, uazo and others.
  .../UserRecoverableErrorHandler.java          |   7 -
  components/gcm_driver/gcm_client_impl.cc      |   4 +
  .../gcm_driver/instance_id/android/BUILD.gn   |   3 -
- .../instance_id/InstanceIDBridge.java         |  49 +-
+ .../instance_id/InstanceIDBridge.java         |  47 +-
  .../media_router/browser/android/BUILD.gn     |   9 -
  .../media_router/BrowserMediaRouter.java      |  18 +-
  .../media_router/CastSessionUtil.java         |  35 --
@@ -84,7 +83,7 @@ Parts of this patch were developed by csagan5, uazo and others.
  components/signin/public/android/BUILD.gn     |   4 -
  components/webauthn/android/BUILD.gn          |   5 -
  .../webauthn/AuthenticatorImpl.java           |  31 +-
- .../push_messaging/push_messaging_manager.cc  |   6 +-
+ .../push_messaging/push_messaging_manager.cc  |   2 +-
  content/public/android/BUILD.gn               |   4 -
  content/public/common/content_features.cc     |   2 +-
  content/test/BUILD.gn                         |   4 -
@@ -96,14 +95,14 @@ Parts of this patch were developed by csagan5, uazo and others.
  third_party/android_deps/BUILD.gn             | 540 +-----------------
  .../preconditions/javatests/BUILD.gn          |   1 -
  .../gms/ChromiumPlayServicesAvailability.java |  10 +-
- 75 files changed, 67 insertions(+), 2599 deletions(-)
+ 74 files changed, 66 insertions(+), 2580 deletions(-)
  delete mode 100644 components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskGcmTaskService.java
  delete mode 100644 components/background_task_scheduler/internal/android/java/src/org/chromium/components/background_task_scheduler/internal/BackgroundTaskSchedulerGcmNetworkManager.java
 
 diff --git a/android_webview/expectations/system_webview_bundle.AndroidManifest.expected b/android_webview/expectations/system_webview_bundle.AndroidManifest.expected
 --- a/android_webview/expectations/system_webview_bundle.AndroidManifest.expected
 +++ b/android_webview/expectations/system_webview_bundle.AndroidManifest.expected
-@@ -23,10 +23,6 @@
+@@ -18,10 +18,6 @@
        android:label="Android System WebView"
        android:multiArch="true"
        android:use32bitAbi="true">
@@ -114,7 +113,7 @@ diff --git a/android_webview/expectations/system_webview_bundle.AndroidManifest.
      </activity>  # DIFF-ANCHOR: ea1a94af
      <activity  # DIFF-ANCHOR: a4438884
          android:name="org.chromium.android_webview.devui.MainActivity"
-@@ -70,7 +66,6 @@
+@@ -65,7 +61,6 @@
          android:visibleToInstantApps="true">
      </activity-alias>  # DIFF-ANCHOR: b7cc06e9
      <meta-data android:name="$PACKAGE.WebViewLibrary" android:value="libwebviewchromium.so"/>
@@ -146,7 +145,7 @@ diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
      "//chrome/android/modules/image_editor/provider:java",
      "//chrome/android/modules/stack_unwinder/provider:java",
      "//chrome/android/webapk/libs/client:client_java",
-@@ -564,7 +554,6 @@ android_library("chrome_java") {
+@@ -571,7 +561,6 @@ android_library("chrome_java") {
      "//third_party/android_data_chart:android_data_chart_java",
      "//third_party/android_deps:android_support_v7_appcompat_java",
      "//third_party/android_deps:chromium_play_services_availability_java",
@@ -154,7 +153,7 @@ diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
      "//third_party/android_deps:com_google_code_findbugs_jsr305_java",
      "//third_party/android_deps:com_google_guava_listenablefuture_java",
      "//third_party/android_deps:dagger_java",
-@@ -890,11 +879,6 @@ junit_binary("chrome_junit_tests") {
+@@ -894,11 +883,6 @@ junit_binary("chrome_junit_tests") {
      ":chrome_java",
      ":chrome_public_android_manifest",
      ":delegate_public_impl_java",
@@ -166,7 +165,7 @@ diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
      "//base:base_java",
      "//base:base_java_test_support",
      "//base:base_junit_test_support",
-@@ -1252,14 +1236,6 @@ android_library("chrome_test_java") {
+@@ -1260,14 +1244,6 @@ android_library("chrome_test_java") {
      ":chrome_test_util_java",
      ":chrome_test_util_jni",
      ":delegate_public_impl_java",
@@ -181,7 +180,7 @@ diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
      "//base:base_java",
      "//base:base_java_test_support",
      "//base/test:test_support_java",
-@@ -2299,7 +2275,6 @@ android_library("browser_java_test_support") {
+@@ -2314,7 +2290,6 @@ android_library("browser_java_test_support") {
    ]
    deps = [
      ":chrome_java",
@@ -189,16 +188,17 @@ diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
      "//base:base_java",
      "//base:base_java_test_support",
      "//base:jni_java",
-@@ -2444,8 +2419,6 @@ android_library("base_monochrome_module_java") {
+@@ -2459,9 +2434,7 @@ android_library("base_monochrome_module_java") {
  android_library("base_module_java") {
    sources = [
      "../browser/attribution_reporting/android/java/src/org/chromium/chrome/browser/attribution_reporting/AttributionReportingProvider.java",
 -    "java/src/com/google/ipc/invalidation/ticl/android2/channel/GcmRegistrationTaskService.java",
+     "java/src/org/chromium/chrome/app/TrichromeZygotePreload.java",
 -    "java/src/org/chromium/chrome/browser/ChromeBackgroundService.java",
      "java/src/org/chromium/chrome/browser/ChromeBackupAgent.java",
      "java/src/org/chromium/chrome/browser/DeferredStartupHandler.java",
      "java/src/org/chromium/chrome/browser/base/DexFixer.java",
-@@ -2456,8 +2429,6 @@ android_library("base_module_java") {
+@@ -2472,8 +2445,6 @@ android_library("base_module_java") {
      "java/src/org/chromium/chrome/browser/base/SplitCompatBackupAgent.java",
      "java/src/org/chromium/chrome/browser/base/SplitCompatContentProvider.java",
      "java/src/org/chromium/chrome/browser/base/SplitCompatCustomTabsService.java",
@@ -207,7 +207,7 @@ diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
      "java/src/org/chromium/chrome/browser/base/SplitCompatIntentService.java",
      "java/src/org/chromium/chrome/browser/base/SplitCompatJobService.java",
      "java/src/org/chromium/chrome/browser/base/SplitCompatMinidumpUploadJobService.java",
-@@ -2484,16 +2455,10 @@ android_library("base_module_java") {
+@@ -2500,16 +2471,10 @@ android_library("base_module_java") {
      "java/src/org/chromium/chrome/browser/photo_picker/DecoderService.java",
      "java/src/org/chromium/chrome/browser/prerender/ChromePrerenderService.java",
      "java/src/org/chromium/chrome/browser/provider/ChromeBrowserProvider.java",
@@ -224,7 +224,7 @@ diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
      "//base:base_java",
      "//chrome/browser/download/android:file_provider_java",
      "//chrome/browser/flags:java",
-@@ -2506,7 +2471,6 @@ android_library("base_module_java") {
+@@ -2522,7 +2487,6 @@ android_library("base_module_java") {
      "//components/media_router/browser/android:cast_options_provider_java",
      "//components/minidump_uploader:minidump_uploader_java",
      "//components/module_installer/android:module_installer_java",
@@ -232,7 +232,7 @@ diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
      "//third_party/androidx:androidx_annotation_annotation_java",
      "//third_party/androidx:androidx_collection_collection_java",
      "//third_party/androidx:androidx_fragment_fragment_java",
-@@ -2528,7 +2492,6 @@ android_library("base_module_java") {
+@@ -2544,7 +2508,6 @@ android_library("base_module_java") {
      # Deps to pull services into base module.
      # TODO(crbug.com/1126301): Consider moving these to the chrome module to
      # reduce base dex size.
@@ -251,7 +251,7 @@ diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java
    "java/src/org/chromium/chrome/browser/ChromeBackupAgentImpl.java",
    "java/src/org/chromium/chrome/browser/ChromeBackupWatcher.java",
    "java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java",
-@@ -1029,10 +1028,6 @@ chrome_java_sources = [
+@@ -1025,10 +1024,6 @@ chrome_java_sources = [
    "java/src/org/chromium/chrome/browser/searchwidget/SearchType.java",
    "java/src/org/chromium/chrome/browser/searchwidget/SearchWidgetProvider.java",
    "java/src/org/chromium/chrome/browser/send_tab_to_self/SendTabToSelfShareActivity.java",
@@ -1282,37 +1282,6 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/inline/Pl
      private static void recordCallFailure(@CallFailure int failure) {
          RecordHistogram.recordEnumeratedHistogram(
                  "GoogleUpdate.Inline.CallFailure", failure, CallFailure.NUM_ENTRIES);
-diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java
---- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java
-+++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/settings/PasswordSettings.java
-@@ -40,7 +40,6 @@ import org.chromium.chrome.browser.preferences.Pref;
- import org.chromium.chrome.browser.profiles.Profile;
- import org.chromium.chrome.browser.settings.ChromeManagedPreferenceDelegate;
- import org.chromium.chrome.browser.settings.SettingsLauncherImpl;
--import org.chromium.chrome.browser.webauthn.CableAuthenticatorModuleProvider;
- import org.chromium.components.browser_ui.settings.ChromeBasePreference;
- import org.chromium.components.browser_ui.settings.ChromeSwitchPreference;
- import org.chromium.components.browser_ui.settings.SearchUtils;
-@@ -593,19 +592,6 @@ public class PasswordSettings extends PreferenceFragmentCompat
-     }
- 
-     private void displaySecurityKeyLink() {
--        if (mSecurityKey == null) {
--            mSecurityKey = new ChromeBasePreference(getStyledContext());
--            mSecurityKey.setKey(PREF_KEY_SECURITY_KEY_LINK);
--            mSecurityKey.setTitle(R.string.phone_as_security_key_text);
--            mSecurityKey.setOnPreferenceClickListener(preference -> {
--                SettingsLauncher settingsLauncher = new SettingsLauncherImpl();
--                settingsLauncher.launchSettingsActivity(
--                        getActivity(), CableAuthenticatorModuleProvider.class, null);
--                return true;
--            });
--            mSecurityKey.setOrder(ORDER_SECURITY_KEY);
--        }
--        getPreferenceScreen().addPreference(mSecurityKey);
-     }
- 
-     private Context getStyledContext() {
 diff --git a/chrome/android/modules/chrome_feature_modules.gni b/chrome/android/modules/chrome_feature_modules.gni
 --- a/chrome/android/modules/chrome_feature_modules.gni
 +++ b/chrome/android/modules/chrome_feature_modules.gni
@@ -1336,7 +1305,7 @@ diff --git a/chrome/android/modules/chrome_feature_modules.gni b/chrome/android/
 diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
 --- a/chrome/browser/BUILD.gn
 +++ b/chrome/browser/BUILD.gn
-@@ -6399,8 +6399,6 @@ static_library("browser") {
+@@ -6501,8 +6501,6 @@ static_library("browser") {
        "offline_pages/offliner_helper.h",
        "offline_pages/offliner_user_data.cc",
        "offline_pages/offliner_user_data.h",
@@ -1365,7 +1334,7 @@ diff --git a/chrome/browser/language/android/BUILD.gn b/chrome/browser/language/
 diff --git a/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/AppLanguagePromoDialog.java b/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/AppLanguagePromoDialog.java
 --- a/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/AppLanguagePromoDialog.java
 +++ b/chrome/browser/language/android/java/src/org/chromium/chrome/browser/language/AppLanguagePromoDialog.java
-@@ -458,19 +458,6 @@ public class AppLanguagePromoDialog {
+@@ -459,19 +459,6 @@ public class AppLanguagePromoDialog {
          }
          AndroidLanguageMetricsBridge.reportAppLanguagePromptLanguage(
                  selectedLanguage.isSystemDefault() ? "" : selectedLanguage.getCode());
@@ -1480,7 +1449,7 @@ diff --git a/chrome/browser/push_messaging/push_messaging_service_factory.cc b/c
 diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
 --- a/chrome/browser/ui/BUILD.gn
 +++ b/chrome/browser/ui/BUILD.gn
-@@ -241,8 +241,6 @@ static_library("ui") {
+@@ -254,8 +254,6 @@ static_library("ui") {
      "webui/flags/flags_ui.h",
      "webui/flags/flags_ui_handler.cc",
      "webui/flags/flags_ui_handler.h",
@@ -1489,7 +1458,7 @@ diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
      "webui/internals/internals_ui.cc",
      "webui/internals/internals_ui.h",
      "webui/interstitials/interstitial_ui.cc",
-@@ -461,7 +459,6 @@ static_library("ui") {
+@@ -483,7 +481,6 @@ static_library("ui") {
      "//components/feedback/content",
      "//components/find_in_page",
      "//components/flags_ui",
@@ -1508,7 +1477,7 @@ diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrom
  #include "chrome/browser/ui/webui/image_editor/image_editor_ui.h"
  #include "chrome/browser/ui/webui/internals/internals_ui.h"
  #include "chrome/browser/ui/webui/interstitials/interstitial_ui.h"
-@@ -623,8 +622,6 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui,
+@@ -629,8 +628,6 @@ WebUIFactoryFunction GetWebUIFactoryFunction(WebUI* web_ui,
      return &NewWebUI<FlagsUI>;
    if (url.host_piece() == chrome::kChromeUIFlocInternalsHost)
      return &NewWebUI<FlocInternalsUI>;
@@ -1520,7 +1489,7 @@ diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrom
 diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn
 --- a/chrome/test/android/BUILD.gn
 +++ b/chrome/test/android/BUILD.gn
-@@ -267,8 +267,6 @@ android_library("chrome_java_test_support") {
+@@ -268,8 +268,6 @@ android_library("chrome_java_test_support") {
    ]
  
    deps = [
@@ -2252,7 +2221,7 @@ diff --git a/components/gcm_driver/instance_id/android/java/src/org/chromium/com
              @Override
              protected String doBackgroundWork() {
 -                try {
--                    // TODO(knollr): Migrate stored LazySubscriptionsManager data to
+-                    // TODO(crbug.com/1247170): Migrate stored LazySubscriptionsManager data to
 -                    // SubscriptionFlagManager.
 -                    LazySubscriptionsManager.storeLazinessInformation(
 -                            LazySubscriptionsManager.buildSubscriptionUniqueId(
@@ -2264,9 +2233,8 @@ diff --git a/components/gcm_driver/instance_id/android/java/src/org/chromium/com
 -                            flags);
 -                    return mInstanceID.getToken(authorizedEntity, scope);
 -                } catch (IOException ex) {
--                    return "";
+                     return "";
 -                }
-+                return "";
              }
              @Override
              protected void sendResultToNative(String token) {
@@ -3867,7 +3835,7 @@ diff --git a/components/webauthn/android/BUILD.gn b/components/webauthn/android/
 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
 --- a/components/webauthn/android/java/src/org/chromium/components/webauthn/AuthenticatorImpl.java
 +++ b/components/webauthn/android/java/src/org/chromium/components/webauthn/AuthenticatorImpl.java
-@@ -94,17 +94,7 @@ public class AuthenticatorImpl implements Authenticator {
+@@ -95,17 +95,7 @@ public class AuthenticatorImpl implements Authenticator {
  
          mMakeCredentialCallback = callback;
          mIsOperationPending = true;
@@ -3886,7 +3854,7 @@ diff --git a/components/webauthn/android/java/src/org/chromium/components/webaut
      }
  
      @Override
-@@ -117,16 +107,7 @@ public class AuthenticatorImpl implements Authenticator {
+@@ -118,16 +108,7 @@ public class AuthenticatorImpl implements Authenticator {
  
          mGetAssertionCallback = callback;
          mIsOperationPending = true;
@@ -3904,17 +3872,17 @@ diff --git a/components/webauthn/android/java/src/org/chromium/components/webaut
      }
  
      @Override
-@@ -145,16 +126,8 @@ public class AuthenticatorImpl implements Authenticator {
+@@ -152,16 +133,8 @@ public class AuthenticatorImpl implements Authenticator {
              return;
          }
  
 -        if (PackageUtils.getPackageVersion(context, GMSCORE_PACKAGE_NAME)
 -                < Fido2ApiHandler.GMSCORE_MIN_VERSION) {
-             callback.call(false);
+             decoratedCallback.call(false);
              return;
 -        }
 -
--        mIsUserVerifyingPlatformAuthenticatorAvailableCallbackQueue.add(callback);
+-        mIsUserVerifyingPlatformAuthenticatorAvailableCallbackQueue.add(decoratedCallback);
 -        Fido2ApiHandler.getInstance().isUserVerifyingPlatformAuthenticatorAvailable(
 -                mRenderFrameHost,
 -                isUvpaa -> onIsUserVerifyingPlatformAuthenticatorAvailableResponse(isUvpaa));
@@ -3924,19 +3892,15 @@ diff --git a/components/webauthn/android/java/src/org/chromium/components/webaut
 diff --git a/content/browser/push_messaging/push_messaging_manager.cc b/content/browser/push_messaging/push_messaging_manager.cc
 --- a/content/browser/push_messaging/push_messaging_manager.cc
 +++ b/content/browser/push_messaging/push_messaging_manager.cc
-@@ -956,11 +956,7 @@ void PushMessagingManager::Core::GetSubscriptionInfoOnUI(
- 
- PushMessagingService* PushMessagingManager::Core::service() {
-   DCHECK_CURRENTLY_ON(BrowserThread::UI);
--  RenderProcessHost* process_host =
--      RenderProcessHost::FromID(render_process_id_);
--  return process_host
--             ? process_host->GetBrowserContext()->GetPushMessagingService()
--             : nullptr;
+@@ -755,7 +755,7 @@ void PushMessagingManager::GetSubscriptionInfo(
+ }
+ 
+ PushMessagingService* PushMessagingManager::GetService() {
+-  return render_process_host_.GetBrowserContext()->GetPushMessagingService();
 +  return nullptr;
  }
  
- base::WeakPtr<PushMessagingManager::Core>
+ }  // namespace content
 diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn
 --- a/content/public/android/BUILD.gn
 +++ b/content/public/android/BUILD.gn
@@ -3954,7 +3918,7 @@ diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn
 diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
 --- a/content/public/common/content_features.cc
 +++ b/content/public/common/content_features.cc
-@@ -957,7 +957,7 @@ const base::Feature kWebAssemblyTrapHandler {
+@@ -939,7 +939,7 @@ const base::Feature kWebAssemblyTrapHandler {
  // Controls whether the WebAuthentication API is enabled:
  // https://w3c.github.io/webauthn
  const base::Feature kWebAuth{"WebAuthentication",
@@ -3962,11 +3926,11 @@ diff --git a/content/public/common/content_features.cc b/content/public/common/c
 +                             base::FEATURE_DISABLED_BY_DEFAULT};
  
  // Controls whether WebAuthn assertion transport is enabled.
- const base::Feature kWebAuthAssertionTransport{
+ const base::Feature kWebAuthAuthenticatorAttachment{
 diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
 --- a/content/test/BUILD.gn
 +++ b/content/test/BUILD.gn
-@@ -2865,10 +2865,6 @@ if (is_android) {
+@@ -2869,10 +2869,6 @@ if (is_android) {
      testonly = true
      sources = content_java_sources_needing_jni
      deps = [
@@ -4067,7 +4031,7 @@ diff --git a/third_party/android_deps/BUILD.gn b/third_party/android_deps/BUILD.
        ":org_robolectric_utils_java",
        ":org_robolectric_utils_reflector_java",
  
-@@ -92,7 +91,7 @@ if (!limit_android_deps) {
+@@ -93,7 +92,7 @@ if (!limit_android_deps) {
  
    android_library("chromium_play_services_availability_java") {
      sources = [ "util/org/chromium/gms/ChromiumPlayServicesAvailability.java" ]
@@ -4076,7 +4040,7 @@ diff --git a/third_party/android_deps/BUILD.gn b/third_party/android_deps/BUILD.
    }
  
    android_library("chromium_play_services_availability_shadows_java") {
-@@ -1027,210 +1026,6 @@ if (!limit_android_deps) {
+@@ -1030,210 +1029,6 @@ if (!limit_android_deps) {
      resource_overlay = true
    }
  
@@ -4287,7 +4251,7 @@ diff --git a/third_party/android_deps/BUILD.gn b/third_party/android_deps/BUILD.
    # This is generated, do not edit. Update BuildConfigGenerator.groovy instead.
    android_aar_prebuilt("com_google_android_material_material_java") {
      aar_path =
-@@ -1264,60 +1059,6 @@ if (!limit_android_deps) {
+@@ -1267,60 +1062,6 @@ if (!limit_android_deps) {
      ignore_proguard_configs = true
    }
  
@@ -4347,8 +4311,8 @@ diff --git a/third_party/android_deps/BUILD.gn b/third_party/android_deps/BUILD.
 -
    # This is generated, do not edit. Update BuildConfigGenerator.groovy instead.
    java_prebuilt("com_google_guava_guava_android_java") {
-     jar_path = "libs/com_google_guava_guava_android/guava-30.1-android.jar"
-@@ -1454,19 +1195,6 @@ if (!limit_android_deps) {
+     jar_path = "libs/com_google_guava_guava_android/guava-31.0-android.jar"
+@@ -1458,19 +1199,6 @@ if (!limit_android_deps) {
      bypass_platform_checks = true
    }
  
@@ -4368,7 +4332,7 @@ diff --git a/third_party/android_deps/BUILD.gn b/third_party/android_deps/BUILD.
    # This is generated, do not edit. Update BuildConfigGenerator.groovy instead.
    java_prebuilt("org_robolectric_utils_java") {
      jar_path = "libs/org_robolectric_utils/utils-4.3.1.jar"
-@@ -1843,272 +1571,6 @@ if (!limit_android_deps) {
+@@ -1847,272 +1575,6 @@ if (!limit_android_deps) {
      deps = [ "//third_party/androidx:androidx_annotation_annotation_java" ]
    }
  

+ 5 - 5
build/patches/Remove-blocklisted-URLs-upon-bookmark-creation.patch

@@ -9,9 +9,9 @@ Subject: Remove blocklisted URLs upon bookmark creation
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
-@@ -139,6 +139,8 @@ import org.chromium.chrome.browser.metrics.UmaSessionStats;
- import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
- import org.chromium.chrome.browser.night_mode.SystemNightModeMonitor;
+@@ -141,6 +141,8 @@ import org.chromium.chrome.browser.night_mode.SystemNightModeMonitor;
+ import org.chromium.chrome.browser.night_mode.WebContentsDarkModeController;
+ import org.chromium.chrome.browser.night_mode.WebContentsDarkModeMessageController;
  import org.chromium.chrome.browser.ntp.NewTabPageUma;
 +import org.chromium.chrome.browser.suggestions.SuggestionsDependencyFactory;
 +import org.chromium.chrome.browser.suggestions.mostvisited.MostVisitedSites;
@@ -35,7 +35,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActiv
  
      private boolean mPartnerBrowserRefreshNeeded;
  
-@@ -1451,6 +1456,11 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
+@@ -1438,6 +1443,11 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
              mCompositorViewHolderSupplier.set(null);
          }
  
@@ -47,7 +47,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActiv
          onDestroyInternal();
  
          if (mDidAddPolicyChangeListener) {
-@@ -1761,6 +1771,13 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
+@@ -1763,6 +1773,13 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
  
          // Defense in depth against the UI being erroneously enabled.
          BookmarkBridge bridge = mBookmarkBridgeSupplier.get();

+ 6 - 6
build/patches/Remove-help-menu-item.patch

@@ -13,7 +13,7 @@ Subject: Remove help menu item
 diff --git a/chrome/android/java/res/menu/main_menu.xml b/chrome/android/java/res/menu/main_menu.xml
 --- a/chrome/android/java/res/menu/main_menu.xml
 +++ b/chrome/android/java/res/menu/main_menu.xml
-@@ -116,9 +116,6 @@
+@@ -142,9 +142,6 @@
          <item android:id="@+id/preferences_id"
              android:title="@string/menu_settings"
              android:icon="@drawable/settings_cog" />
@@ -39,7 +39,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/KeyboardShortcu
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
-@@ -2322,16 +2322,6 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
+@@ -2329,16 +2329,6 @@ public abstract class ChromeActivity<C extends ChromeActivityComponent>
  
          final Tab currentTab = getActivityTab();
  
@@ -59,12 +59,12 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActiv
 diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
 +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
-@@ -523,7 +523,7 @@ public abstract class BaseCustomTabActivity extends ChromeActivity<BaseCustomTab
-     @Override
+@@ -524,7 +524,7 @@ public abstract class BaseCustomTabActivity extends ChromeActivity<BaseCustomTab
      public boolean onMenuOrKeyboardAction(int id, boolean fromMenu) {
          // Disable creating new tabs, bookmark, history, print, help, focus_url, etc.
--        if (id == R.id.focus_url_bar || id == R.id.all_bookmarks_menu_id || id == R.id.help_id
-+        if (id == R.id.focus_url_bar || id == R.id.all_bookmarks_menu_id
+         if (id == R.id.focus_url_bar || id == R.id.all_bookmarks_menu_id
+-                || id == R.id.add_to_reading_list_menu_id || id == R.id.help_id
++                || id == R.id.add_to_reading_list_menu_id
                  || id == R.id.recent_tabs_menu_id || id == R.id.new_incognito_tab_menu_id
                  || id == R.id.new_tab_menu_id || id == R.id.open_history_menu_id) {
              return true;

+ 1 - 1
build/patches/Remove-offline-measurement-background-task.patch

@@ -17,7 +17,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ProcessIni
  import org.chromium.chrome.browser.omnibox.voice.AssistantVoiceSearchService;
  import org.chromium.chrome.browser.optimization_guide.OptimizationGuideBridgeFactory;
  import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomizations;
-@@ -408,8 +407,6 @@ public class ProcessInitializationHandler {
+@@ -420,8 +419,6 @@ public class ProcessInitializationHandler {
                  () -> VideoTutorialShareHelper.saveUrlsToSharedPrefs());
          deferredStartupHandler.addDeferredTask(
                  () -> TosDialogBehaviorSharedPrefInvalidator.refreshSharedPreferenceIfTosSkipped());

File diff suppressed because it is too large
+ 232 - 168
build/patches/Remove-signin-and-data-saver-integrations.patch


+ 1 - 1
build/patches/Replace-DoH-probe-domain-with-RIPE-domain.patch

@@ -23,7 +23,7 @@ diff --git a/chrome/browser/net/dns_probe_runner.cc b/chrome/browser/net/dns_pro
 diff --git a/net/dns/dns_transaction.cc b/net/dns/dns_transaction.cc
 --- a/net/dns/dns_transaction.cc
 +++ b/net/dns/dns_transaction.cc
-@@ -871,7 +871,7 @@ class DnsTCPAttempt : public DnsAttempt {
+@@ -876,7 +876,7 @@ class DnsTCPAttempt : public DnsAttempt {
  
  // ----------------------------------------------------------------------------
  

+ 19 - 19
build/patches/Restore-Search-Ready-Omnibox-flag.patch

@@ -21,19 +21,19 @@ diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 --- a/chrome/browser/about_flags.cc
 +++ b/chrome/browser/about_flags.cc
 @@ -3381,6 +3381,9 @@ const FeatureEntry kFeatureEntries[] = {
-      flag_descriptions::kUseLookalikesForNavigationSuggestionsDescription,
-      kOsAll,
-      FEATURE_VALUE_TYPE(net::features::kUseLookalikesForNavigationSuggestions)},
+     {"overscroll-history-navigation",
+      flag_descriptions::kOverscrollHistoryNavigationName,
+      flag_descriptions::kOverscrollHistoryNavigationDescription, kOsAura,
 +    {"enable-search-ready-omnibox", flag_descriptions::kSearchReadyOmniboxName,
 +     flag_descriptions::kSearchReadyOmniboxDescription, kOsAndroid,
 +     FEATURE_VALUE_TYPE(chrome::android::kSearchReadyOmniboxFeature)},
-     {"username-first-flow", flag_descriptions::kUsernameFirstFlowName,
-      flag_descriptions::kUsernameFirstFlowDescription, kOsAll,
-      FEATURE_VALUE_TYPE(password_manager::features::kUsernameFirstFlow)},
+      FEATURE_VALUE_TYPE(features::kOverscrollHistoryNavigation)},
+     {"pull-to-refresh", flag_descriptions::kPullToRefreshName,
+      flag_descriptions::kPullToRefreshDescription, kOsAura,
 diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
 --- a/chrome/browser/flag-metadata.json
 +++ b/chrome/browser/flag-metadata.json
-@@ -2390,6 +2390,11 @@
+@@ -2355,6 +2355,11 @@
      //  with neural net palm detection.
      "expiry_milestone": 90
    },
@@ -48,7 +48,7 @@ diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.js
 diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
 --- a/chrome/browser/flag_descriptions.cc
 +++ b/chrome/browser/flag_descriptions.cc
-@@ -3485,6 +3485,11 @@ const char kSecurePaymentConfirmationAndroidName[] =
+@@ -3525,6 +3525,11 @@ const char kSecurePaymentConfirmationAndroidName[] =
  const char kSecurePaymentConfirmationAndroidDescription[] =
      "Enables Secure Payment Confirmation on Android.";
  
@@ -63,7 +63,7 @@ diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descripti
 diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
 --- a/chrome/browser/flag_descriptions.h
 +++ b/chrome/browser/flag_descriptions.h
-@@ -1999,6 +1999,9 @@ extern const char kScrollCaptureDescription[];
+@@ -2020,6 +2020,9 @@ extern const char kScrollCaptureDescription[];
  extern const char kSecurePaymentConfirmationAndroidName[];
  extern const char kSecurePaymentConfirmationAndroidDescription[];
  
@@ -76,7 +76,7 @@ diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptio
 diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
 --- a/chrome/browser/flags/android/chrome_feature_list.cc
 +++ b/chrome/browser/flags/android/chrome_feature_list.cc
-@@ -243,6 +243,7 @@ const base::Feature* const kFeaturesExposedToJava[] = {
+@@ -255,6 +255,7 @@ const base::Feature* const kFeaturesExposedToJava[] = {
      &kReachedCodeProfiler,
      &kReaderModeInCCT,
      &kReengagementNotification,
@@ -84,7 +84,7 @@ diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browse
      &kRelatedSearches,
      &kRelatedSearchesAlternateUx,
      &kRelatedSearchesInBar,
-@@ -682,6 +683,9 @@ const base::Feature kRelatedSearchesSimplifiedUx{
+@@ -698,6 +699,9 @@ const base::Feature kRelatedSearchesSimplifiedUx{
  const base::Feature kRelatedSearchesUi{"RelatedSearchesUi",
                                         base::FEATURE_DISABLED_BY_DEFAULT};
  
@@ -97,7 +97,7 @@ diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browse
 diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h
 --- a/chrome/browser/flags/android/chrome_feature_list.h
 +++ b/chrome/browser/flags/android/chrome_feature_list.h
-@@ -120,6 +120,7 @@ extern const base::Feature kRelatedSearchesSimplifiedUx;
+@@ -123,6 +123,7 @@ extern const base::Feature kRelatedSearchesSimplifiedUx;
  extern const base::Feature kRelatedSearchesUi;
  extern const base::Feature kSearchEnginePromoExistingDevice;
  extern const base::Feature kSearchEnginePromoNewDevice;
@@ -108,14 +108,14 @@ diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser
 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
 --- 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
-@@ -402,6 +402,7 @@ public abstract class ChromeFeatureList {
-     public static final String OMNIBOX_ADAPTIVE_SUGGESTIONS_COUNT =
-             "OmniboxAdaptiveSuggestionsCount";
-     public static final String OMNIBOX_ASSISTANT_VOICE_SEARCH = "OmniboxAssistantVoiceSearch";
+@@ -399,6 +399,7 @@ public abstract class ChromeFeatureList {
+     public static final String MODAL_PERMISSION_DIALOG_VIEW = "ModalPermissionDialogView";
+     public static final String METRICS_SETTINGS_ANDROID = "MetricsSettingsAndroid";
+     public static final String NEW_WINDOW_APP_MENU = "NewWindowAppMenu";
 +    public static final String SEARCH_READY_OMNIBOX = "SearchReadyOmnibox";
-     public static final String OMNIBOX_COMPACT_SUGGESTIONS = "OmniboxCompactSuggestions";
-     public static final String OMNIBOX_ENABLE_CLIPBOARD_PROVIDER_IMAGE_SUGGESTIONS =
-             "OmniboxEnableClipboardProviderImageSuggestions";
+     public static final String OFFLINE_INDICATOR = "OfflineIndicator";
+     public static final String OFFLINE_INDICATOR_V2 = "OfflineIndicatorV2";
+     public static final String OFFLINE_MEASUREMENTS_BACKGROUND_TASK =
 diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListBuilder.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListBuilder.java
 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListBuilder.java
 +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListBuilder.java

+ 14 - 14
build/patches/Restore-Simplified-NTP-launch.patch

@@ -29,7 +29,7 @@ This reverts commit 4d0e4483c5f77c66a8b6193e8a3bec5d0624d6ad.
 diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni
 --- a/chrome/android/chrome_java_resources.gni
 +++ b/chrome/android/chrome_java_resources.gni
-@@ -684,6 +684,7 @@ chrome_java_resources = [
+@@ -680,6 +680,7 @@ chrome_java_resources = [
    "java/res/layout/new_tab_page_multi_feed_header.xml",
    "java/res/layout/new_tab_page_section_tab.xml",
    "java/res/layout/new_tab_page_tile_grid_placeholder.xml",
@@ -40,7 +40,7 @@ diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_ja
 diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
 --- a/chrome/android/chrome_java_sources.gni
 +++ b/chrome/android/chrome_java_sources.gni
-@@ -590,6 +590,7 @@ chrome_java_sources = [
+@@ -598,6 +598,7 @@ chrome_java_sources = [
    "java/src/org/chromium/chrome/browser/feedback/FeedFeedbackCollector.java",
    "java/src/org/chromium/chrome/browser/feedback/HelpAndFeedbackLauncherImpl.java",
    "java/src/org/chromium/chrome/browser/feedback/ScreenshotTask.java",
@@ -215,7 +215,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageL
  import org.chromium.chrome.browser.lens.LensMetrics;
  import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
  import org.chromium.chrome.browser.native_page.ContextMenuManager;
-@@ -117,6 +118,8 @@ public class NewTabPageLayout extends LinearLayout implements TileGroup.Observer
+@@ -118,6 +119,8 @@ public class NewTabPageLayout extends LinearLayout implements TileGroup.Observer
      private UiConfig mUiConfig;
      private CallbackController mCallbackController = new CallbackController();
  
@@ -224,7 +224,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageL
      /**
       * Whether the tiles shown in the layout have finished loading.
       * With {@link #mHasShownView}, it's one of the 2 flags used to track initialisation progress.
-@@ -282,6 +285,7 @@ public class NewTabPageLayout extends LinearLayout implements TileGroup.Observer
+@@ -283,6 +286,7 @@ public class NewTabPageLayout extends LinearLayout implements TileGroup.Observer
          mNoSearchLogoSpacer = findViewById(R.id.no_search_logo_spacer);
  
          initializeSearchBoxBackground();
@@ -232,7 +232,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPageL
          initializeSearchBoxTextView();
          initializeVoiceSearchButton();
          initializeLensButton();
-@@ -595,10 +599,16 @@ public class NewTabPageLayout extends LinearLayout implements TileGroup.Observer
+@@ -596,10 +600,16 @@ public class NewTabPageLayout extends LinearLayout implements TileGroup.Observer
       * Updates the padding for the tile grid based on what is shown above it.
       */
      private void updateTileGridPadding() {
@@ -325,7 +325,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/Sug
 diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 --- a/chrome/browser/about_flags.cc
 +++ b/chrome/browser/about_flags.cc
-@@ -4061,6 +4061,9 @@ const FeatureEntry kFeatureEntries[] = {
+@@ -4005,6 +4005,9 @@ const FeatureEntry kFeatureEntries[] = {
       SINGLE_VALUE_TYPE_AND_VALUE(
           switches::kForceShowUpdateMenuItemCustomSummary,
           "Custom Summary")},
@@ -338,7 +338,7 @@ diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
 --- a/chrome/browser/flag_descriptions.cc
 +++ b/chrome/browser/flag_descriptions.cc
-@@ -3533,6 +3533,9 @@ const char kSharingHubLinkToggleName[] = "Sharing Hub Link Toggle";
+@@ -3573,6 +3573,9 @@ const char kSharingHubLinkToggleName[] = "Sharing Hub Link Toggle";
  const char kSharingHubLinkToggleDescription[] =
      "Enable the link toggle in the Sharing Hub.";
  
@@ -351,7 +351,7 @@ diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descripti
 diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
 --- a/chrome/browser/flag_descriptions.h
 +++ b/chrome/browser/flag_descriptions.h
-@@ -2020,6 +2020,9 @@ extern const char kSiteIsolationForPasswordSitesDescription[];
+@@ -2041,6 +2041,9 @@ extern const char kSiteIsolationForPasswordSitesDescription[];
  extern const char kSmartSuggestionForLargeDownloadsName[];
  extern const char kSmartSuggestionForLargeDownloadsDescription[];
  
@@ -364,7 +364,7 @@ diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptio
 diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
 --- a/chrome/browser/flags/android/chrome_feature_list.cc
 +++ b/chrome/browser/flags/android/chrome_feature_list.cc
-@@ -221,6 +221,7 @@ const base::Feature* const kFeaturesExposedToJava[] = {
+@@ -233,6 +233,7 @@ const base::Feature* const kFeaturesExposedToJava[] = {
      &kEnhancedProtectionPromoCard,
      &kExperimentsForAgsa,
      &kExploreSites,
@@ -372,7 +372,7 @@ diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browse
      &kFocusOmniboxInIncognitoTabIntents,
      &kGoogleLensSdkIntent,
      &kHandleMediaIntents,
-@@ -651,6 +652,9 @@ const base::Feature kOfflineIndicatorV2{"OfflineIndicatorV2",
+@@ -664,6 +665,9 @@ const base::Feature kOfflineIndicatorV2{"OfflineIndicatorV2",
  const base::Feature kOfflineMeasurementsBackgroundTask{
      "OfflineMeasurementsBackgroundTask", base::FEATURE_DISABLED_BY_DEFAULT};
  
@@ -385,18 +385,18 @@ diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browse
 diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h
 --- a/chrome/browser/flags/android/chrome_feature_list.h
 +++ b/chrome/browser/flags/android/chrome_feature_list.h
-@@ -108,6 +108,7 @@ extern const base::Feature kNewWindowAppMenu;
+@@ -110,6 +110,7 @@ extern const base::Feature kNewWindowAppMenu;
  extern const base::Feature kOfflineIndicatorV2;
  extern const base::Feature kOfflineMeasurementsBackgroundTask;
  extern const base::Feature kPageAnnotationsService;
 +extern const base::Feature kSimplifiedNTP;
+ extern const base::Feature kBookmarksImprovedSaveFlow;
  extern const base::Feature kBookmarksRefresh;
  extern const base::Feature kProbabilisticCryptidRenderer;
- extern const base::Feature kQuickActionSearchWidgetAndroid;
 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
 --- 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
-@@ -379,6 +379,7 @@ public abstract class ChromeFeatureList {
+@@ -389,6 +389,7 @@ public abstract class ChromeFeatureList {
      public static final String MARK_HTTP_AS = "MarkHttpAs";
      public static final String MESSAGES_FOR_ANDROID_CHROME_SURVEY =
              "MessagesForAndroidChromeSurvey";
@@ -429,7 +429,7 @@ diff --git a/components/ntp_snippets/features.cc b/components/ntp_snippets/featu
 diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
 --- a/testing/variations/fieldtrial_testing_config.json
 +++ b/testing/variations/fieldtrial_testing_config.json
-@@ -4119,6 +4119,24 @@
+@@ -3972,6 +3972,24 @@
              ]
          }
      ],

+ 4 - 4
build/patches/Revert-flags-remove-disable-pull-to-refresh-effect.patch

@@ -13,7 +13,7 @@ This reverts commit 4e598f38a0e6dd3dbede009c6a99b2a520a94e1f.
 diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 --- a/chrome/browser/about_flags.cc
 +++ b/chrome/browser/about_flags.cc
-@@ -3473,6 +3473,10 @@ const FeatureEntry kFeatureEntries[] = {
+@@ -3435,6 +3435,10 @@ const FeatureEntry kFeatureEntries[] = {
       SINGLE_DISABLE_VALUE_TYPE(switches::kDisableHostedAppShimCreation)},
  #endif  // OS_MAC
  #if defined(OS_ANDROID)
@@ -27,7 +27,7 @@ diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
 --- a/chrome/browser/flag-metadata.json
 +++ b/chrome/browser/flag-metadata.json
-@@ -1141,6 +1141,11 @@
+@@ -1160,6 +1160,11 @@
      // enable-javascript-harmony.
      "expiry_milestone": -1
    },
@@ -42,7 +42,7 @@ diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.js
 diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
 --- a/chrome/browser/flag_descriptions.cc
 +++ b/chrome/browser/flag_descriptions.cc
-@@ -3375,6 +3375,10 @@ const char kReadLaterDescription[] =
+@@ -3409,6 +3409,10 @@ const char kReadLaterDescription[] =
      "Allow users to save tabs for later. Enables a new button and menu for "
      "accessing tabs saved for later.";
  
@@ -56,7 +56,7 @@ diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descripti
 diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
 --- a/chrome/browser/flag_descriptions.h
 +++ b/chrome/browser/flag_descriptions.h
-@@ -1936,6 +1936,9 @@ extern const char kQueryTilesSegmentationDescription[];
+@@ -1954,6 +1954,9 @@ extern const char kQueryTilesSegmentationDescription[];
  extern const char kQueryTilesSwapTrendingName[];
  extern const char kQueryTilesSwapTrendingDescription[];
  

+ 8 - 8
build/patches/Revert-flags-remove-num-raster-threads.patch

@@ -13,7 +13,7 @@ This reverts commit 2a51528a1737e9038f7f96f29403032a6a845a25.
 diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
 --- a/chrome/browser/about_flags.cc
 +++ b/chrome/browser/about_flags.cc
-@@ -311,6 +311,15 @@ const FeatureEntry::Choice kOverlayStrategiesChoices[] = {
+@@ -319,6 +319,15 @@ const FeatureEntry::Choice kOverlayStrategiesChoices[] = {
       "single-fullscreen,single-on-top,underlay"},
  };
  
@@ -29,7 +29,7 @@ diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
  const FeatureEntry::Choice kTouchTextSelectionStrategyChoices[] = {
      {flags_ui::kGenericExperimentChoiceDefault, "", ""},
      {flag_descriptions::kTouchSelectionStrategyCharacter,
-@@ -3694,6 +3703,9 @@ const FeatureEntry kFeatureEntries[] = {
+@@ -3647,6 +3656,9 @@ const FeatureEntry kFeatureEntries[] = {
      {"enable-use-zoom-for-dsf", flag_descriptions::kEnableUseZoomForDsfName,
       flag_descriptions::kEnableUseZoomForDsfDescription, kOsAll,
       MULTI_VALUE_TYPE(kEnableUseZoomForDSFChoices)},
@@ -43,8 +43,8 @@ diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.js
 --- a/chrome/browser/flag-metadata.json
 +++ b/chrome/browser/flag-metadata.json
 @@ -3945,6 +3945,11 @@
-     "owners": [ "carlosil" ],
-     "expiry_milestone": 92
+     "owners": [ "jerem", "tiborg" ],
+     "expiry_milestone": 96
    },
 +  {
 +    "name": "num-raster-threads",
@@ -52,12 +52,12 @@ diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.js
 +    "expiry_milestone": -1
 +  },
    {
-     "name": "mobile-google-srp",
-     "owners": [ "gambard", "bling-flags@google.com" ],
+     "name": "ntp-realbox-pedals",
+     "owners": [ "mahmadi", "mfacey" ],
 diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
 --- a/chrome/browser/flag_descriptions.cc
 +++ b/chrome/browser/flag_descriptions.cc
-@@ -1714,6 +1714,14 @@ const char kOmniboxActiveSearchEnginesDescription[] =
+@@ -1742,6 +1742,14 @@ const char kOmniboxActiveSearchEnginesDescription[] =
      "Enables a 'Your Search Engines' section on "
      "chrome://settings/searchEngines.";
  
@@ -75,7 +75,7 @@ diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descripti
 diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
 --- a/chrome/browser/flag_descriptions.h
 +++ b/chrome/browser/flag_descriptions.h
-@@ -999,6 +999,13 @@ extern const char kNotificationsSystemFlagDescription[];
+@@ -1009,6 +1009,13 @@ extern const char kNotificationsSystemFlagDescription[];
  extern const char kOmniboxActiveSearchEnginesName[];
  extern const char kOmniboxActiveSearchEnginesDescription[];
  

+ 69 - 94
build/patches/Revert-the-removal-of-an-option-to-block-autoplay.patch

@@ -9,15 +9,14 @@ Subject: Revert the removal of an option to block autoplay
  .../res/drawable-xhdpi/settings_autoplay.png  | Bin 0 -> 551 bytes
  .../res/drawable-xxhdpi/settings_autoplay.png | Bin 0 -> 792 bytes
  .../drawable-xxxhdpi/settings_autoplay.png    | Bin 0 -> 1064 bytes
- .../res/xml/site_settings_preferences.xml     |   4 +++
+ .../res/xml/site_settings_preferences.xml     |   4 ++++
  .../ContentSettingsResources.java             |   5 +++-
- .../site_settings/SingleCategorySettings.java |   4 +++
- .../site_settings/SingleWebsiteSettings.java  |  22 +++++++++++++++++
+ .../site_settings/SingleCategorySettings.java |   4 ++++
+ .../site_settings/SingleWebsiteSettings.java  |  22 ++++++++++++++++++
  .../site_settings/SiteSettingsCategory.java   |   9 +++++--
- .../browser_ui/site_settings/Website.java     |   8 ++++++
+ .../browser_ui/site_settings/Website.java     |   8 +++++++
  .../WebsitePermissionsFetcher.java            |   1 +
- .../WebsitePreferenceBridge.java              |   4 +++
- .../android/website_preference_bridge.cc      |  23 ++++++++++++++++++
+ .../android/website_preference_bridge.cc      |   1 +
  .../strings/android/site_settings.grdp        |   9 +++++++
  .../core/browser/content_settings_registry.cc |   2 +-
  .../core/browser/content_settings_utils.cc    |   2 ++
@@ -33,9 +32,9 @@ Subject: Revert the removal of an option to block autoplay
  components/page_info/page_info_ui.cc          |   1 +
  components/site_settings_strings.grdp         |   5 +++-
  .../platform/web_content_settings_client.h    |   3 +++
- .../core/html/media/autoplay_policy.cc        |  12 ++++++++-
- .../core/html/media/autoplay_policy.h         |   4 +++
- 32 files changed, 145 insertions(+), 6 deletions(-)
+ .../core/html/media/autoplay_policy.cc        |  12 +++++++++-
+ .../core/html/media/autoplay_policy.h         |   4 ++++
+ 31 files changed, 119 insertions(+), 6 deletions(-)
  create mode 100644 components/browser_ui/site_settings/android/java/res/drawable-hdpi/settings_autoplay.png
  create mode 100644 components/browser_ui/site_settings/android/java/res/drawable-mdpi/settings_autoplay.png
  create mode 100644 components/browser_ui/site_settings/android/java/res/drawable-xhdpi/settings_autoplay.png
@@ -43,6 +42,7 @@ Subject: Revert the removal of an option to block autoplay
  create mode 100644 components/browser_ui/site_settings/android/java/res/drawable-xxxhdpi/settings_autoplay.png
 
 diff --git a/components/browser_ui/site_settings/android/BUILD.gn b/components/browser_ui/site_settings/android/BUILD.gn
+index 624ba958356ba..216eb2c2381ef 100644
 --- a/components/browser_ui/site_settings/android/BUILD.gn
 +++ b/components/browser_ui/site_settings/android/BUILD.gn
 @@ -145,6 +145,11 @@ android_resources("java_resources") {
@@ -166,9 +166,10 @@ literal 0
 HcmV?d00001
 
 diff --git a/components/browser_ui/site_settings/android/java/res/xml/site_settings_preferences.xml b/components/browser_ui/site_settings/android/java/res/xml/site_settings_preferences.xml
+index 31260c27852a3..7bae9b4f3afcc 100644
 --- a/components/browser_ui/site_settings/android/java/res/xml/site_settings_preferences.xml
 +++ b/components/browser_ui/site_settings/android/java/res/xml/site_settings_preferences.xml
-@@ -65,6 +65,10 @@
+@@ -61,6 +61,10 @@
      <org.chromium.components.browser_ui.settings.ChromeBasePreference
          android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings"
          android:key="protected_content" />
@@ -180,10 +181,11 @@ diff --git a/components/browser_ui/site_settings/android/java/res/xml/site_setti
      <org.chromium.components.browser_ui.settings.ChromeBasePreference
          android:fragment="org.chromium.components.browser_ui.site_settings.SingleCategorySettings"
 diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java
+index 04379683aa48b..a78f79463e044 100644
 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java
 +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java
-@@ -112,7 +112,10 @@ public class ContentSettingsResources {
-                 return new ResourceItem(R.drawable.infobar_downloading, 0,
+@@ -113,7 +113,10 @@ public class ContentSettingsResources {
+                 return new ResourceItem(R.drawable.infobar_downloading, /*smallIcon=*/0,
                          R.string.automatic_downloads_permission_title, ContentSettingValues.ASK,
                          ContentSettingValues.BLOCK, R.string.website_settings_category_ask, 0);
 -
@@ -191,13 +193,14 @@ diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/c
 +                return new ResourceItem(R.drawable.settings_autoplay, 0, R.string.autoplay_title,
 +                            ContentSettingValues.ALLOW, ContentSettingValues.BLOCK,
 +                            R.string.website_settings_category_autoplay_allowed, 0);
-             case ContentSettingsType.BACKGROUND_SYNC:
-                 return new ResourceItem(R.drawable.permission_background_sync, 0,
-                         R.string.background_sync_permission_title, ContentSettingValues.ALLOW,
+             case ContentSettingsType.AUTO_DARK_WEB_CONTENT:
+                 return new ResourceItem(R.drawable.ic_brightness_medium_24dp,
+                         R.drawable.ic_brightness_medium_20dp, R.string.auto_dark_web_content_title,
 diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java
+index 2f289db26c670..6440e0ff63271 100644
 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java
 +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java
-@@ -534,6 +534,8 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment
+@@ -567,6 +567,8 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment
          int resource = 0;
          if (mCategory.showSites(SiteSettingsCategory.Type.AUTOMATIC_DOWNLOADS)) {
              resource = R.string.website_settings_add_site_description_automatic_downloads;
@@ -206,7 +209,7 @@ diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/c
          } else if (mCategory.showSites(SiteSettingsCategory.Type.BACKGROUND_SYNC)) {
              resource = R.string.website_settings_add_site_description_background_sync;
          } else if (mCategory.showSites(SiteSettingsCategory.Type.JAVASCRIPT)) {
-@@ -650,6 +652,8 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment
+@@ -680,6 +682,8 @@ public class SingleCategorySettings extends SiteSettingsPreferenceFragment
          boolean exception = false;
          if (mCategory.showSites(SiteSettingsCategory.Type.SOUND)) {
              exception = true;
@@ -216,9 +219,10 @@ diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/c
              exception = true;
          } else if (mCategory.showSites(SiteSettingsCategory.Type.COOKIES)) {
 diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
+index 046bf481a685c..78c8579eb9c6c 100644
 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
 +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
-@@ -116,6 +116,8 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment
+@@ -119,6 +119,8 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment
                  return "bluetooth_scanning_permission_list";
              case ContentSettingsType.COOKIES:
                  return "cookies_permission_list";
@@ -227,7 +231,7 @@ diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/c
              case ContentSettingsType.IDLE_DETECTION:
                  return "idle_detection_permission_list";
              case ContentSettingsType.JAVASCRIPT:
-@@ -482,6 +484,8 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment
+@@ -483,6 +485,8 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment
  
              if (type == ContentSettingsType.ADS) {
                  setUpAdsPreference(preference);
@@ -236,8 +240,8 @@ diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/c
              } else if (type == ContentSettingsType.SOUND) {
                  setUpSoundPreference(preference);
              } else if (type == ContentSettingsType.JAVASCRIPT) {
-@@ -949,6 +953,24 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment
-         }
+@@ -971,6 +975,24 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment
+         setupContentSettingsPreference(preference, currentValue, false /* isEmbargoed */);
      }
  
 +    private void setUpAutoplayPreference(Preference preference) {
@@ -258,35 +262,36 @@ diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/c
 +        setupContentSettingsPreference(preference, currentValue, false /* isEmbargoed */);
 +    }
 +
-     private void setUpSoundPreference(Preference preference) {
+     private void setUpJavascriptPreference(Preference preference) {
          BrowserContextHandle browserContextHandle =
                  getSiteSettingsDelegate().getBrowserContextHandle();
 diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsCategory.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsCategory.java
+index 801c2454e2984..65aa0fd8899db 100644
 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsCategory.java
 +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SiteSettingsCategory.java
 @@ -42,7 +42,7 @@ public class SiteSettingsCategory {
              Type.CLIPBOARD, Type.COOKIES, Type.IDLE_DETECTION, Type.DEVICE_LOCATION,
              Type.JAVASCRIPT, Type.MICROPHONE, Type.NFC, Type.NOTIFICATIONS, Type.POPUPS,
              Type.PROTECTED_MEDIA, Type.SENSORS, Type.SOUND, Type.USB, Type.VIRTUAL_REALITY,
--            Type.USE_STORAGE, Type.TIMEZONE_OVERRIDE})
-+            Type.USE_STORAGE, Type.TIMEZONE_OVERRIDE, Type.AUTOPLAY})
+-            Type.USE_STORAGE, Type.AUTO_DARK_WEB_CONTENT, Type.REQUEST_DESKTOP_SITE})
++            Type.USE_STORAGE, Type.AUTO_DARK_WEB_CONTENT, Type.REQUEST_DESKTOP_SITE, Type.AUTOPLAY})
      @Retention(RetentionPolicy.SOURCE)
      public @interface Type {
          // All updates here must also be reflected in {@link #preferenceKey(int)
-@@ -71,10 +71,11 @@ public class SiteSettingsCategory {
-         int VIRTUAL_REALITY = 21;
+@@ -72,10 +72,11 @@ public class SiteSettingsCategory {
          int USE_STORAGE = 22;
-         int TIMEZONE_OVERRIDE = 23;
-+        int AUTOPLAY = 24;
+         int AUTO_DARK_WEB_CONTENT = 23;
+         int REQUEST_DESKTOP_SITE = 24;
++        int AUTOPLAY = 25;
          /**
           * Number of handled categories used for calculating array sizes.
           */
--        int NUM_ENTRIES = 24;
-+        int NUM_ENTRIES = 25;
+-        int NUM_ENTRIES = 25;
++        int NUM_ENTRIES = 26;
      }
  
      private final BrowserContextHandle mBrowserContextHandle;
-@@ -180,6 +181,8 @@ public class SiteSettingsCategory {
+@@ -186,6 +187,8 @@ public class SiteSettingsCategory {
                  return ContentSettingsType.NFC;
              case Type.NOTIFICATIONS:
                  return ContentSettingsType.NOTIFICATIONS;
@@ -295,7 +300,7 @@ diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/c
              case Type.POPUPS:
                  return ContentSettingsType.POPUPS;
              case Type.PROTECTED_MEDIA:
-@@ -253,6 +256,8 @@ public class SiteSettingsCategory {
+@@ -262,6 +265,8 @@ public class SiteSettingsCategory {
                  return "nfc";
              case Type.NOTIFICATIONS:
                  return "notifications";
@@ -305,6 +310,7 @@ diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/c
                  return "popups";
              case Type.PROTECTED_MEDIA:
 diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/Website.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/Website.java
+index fa69c4b50b536..8d0c56709ab3d 100644
 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/Website.java
 +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/Website.java
 @@ -216,6 +216,14 @@ public final class Website implements Serializable {
@@ -323,52 +329,22 @@ diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/c
              // It is possible to set the permission without having an existing exception,
              // because we always show the sound permission in Site Settings.
 diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePermissionsFetcher.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePermissionsFetcher.java
+index 9523dcca60d51..5a2c743b245f3 100644
 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePermissionsFetcher.java
 +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePermissionsFetcher.java
-@@ -60,6 +60,7 @@ public class WebsitePermissionsFetcher {
+@@ -61,6 +61,7 @@ public class WebsitePermissionsFetcher {
              case ContentSettingsType.AUTOMATIC_DOWNLOADS:
              case ContentSettingsType.BACKGROUND_SYNC:
              case ContentSettingsType.BLUETOOTH_SCANNING:
 +            case ContentSettingsType.AUTOPLAY:
              case ContentSettingsType.COOKIES:
+             case ContentSettingsType.REQUEST_DESKTOP_SITE:
              case ContentSettingsType.JAVASCRIPT:
-             case ContentSettingsType.JAVASCRIPT_JIT:
-diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java
---- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java
-+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java
-@@ -370,6 +370,10 @@ public class WebsitePreferenceBridge {
-         void setSettingForOrigin(BrowserContextHandle browserContextHandle,
-                 @ContentSettingsType int contentSettingsType, String origin, String embedder,
-                 int value);
-+        void getAutoplayOrigins(
-+                BrowserContextHandle browserContextHandle, Object list, boolean managedOnly);
-+        void setAutoplaySettingForOrigin(
-+                BrowserContextHandle browserContextHandle, String origin, int value);
-         boolean isPermissionControlledByDSE(BrowserContextHandle browserContextHandle,
-                 @ContentSettingsType int contentSettingsType, String origin);
-         boolean isDSEOrigin(BrowserContextHandle browserContextHandle, String origin);
 diff --git a/components/browser_ui/site_settings/android/website_preference_bridge.cc b/components/browser_ui/site_settings/android/website_preference_bridge.cc
+index ee7d9bf53f8d3..f0aaa0ffd23e8 100644
 --- a/components/browser_ui/site_settings/android/website_preference_bridge.cc
 +++ b/components/browser_ui/site_settings/android/website_preference_bridge.cc
-@@ -448,6 +448,17 @@ static void JNI_WebsitePreferenceBridge_GetOriginsForPermission(
-              managedOnly);
- }
- 
-+static void JNI_WebsitePreferenceBridge_SetAutoplaySettingForOrigin(
-+    JNIEnv* env,
-+    const JavaParamRef<jobject>& jbrowser_context_handle,
-+    const JavaParamRef<jstring>& origin,
-+    jint value) {
-+  // Here 'nullptr' indicates that autoplay uses wildcard for embedder.
-+  SetSettingForOrigin(env, jbrowser_context_handle,
-+                      ContentSettingsType::AUTOPLAY, origin, nullptr,
-+                      static_cast<ContentSetting>(value));
-+}
-+
- static jboolean JNI_WebsitePreferenceBridge_IsContentSettingsPatternValid(
-     JNIEnv* env,
-     const JavaParamRef<jstring>& pattern) {
-@@ -814,6 +825,7 @@ static void JNI_WebsitePreferenceBridge_SetContentSettingEnabled(
+@@ -820,6 +820,7 @@ static void JNI_WebsitePreferenceBridge_SetContentSettingEnabled(
        case ContentSettingsType::POPUPS:
        case ContentSettingsType::SENSORS:
        case ContentSettingsType::SOUND:
@@ -376,25 +352,8 @@ diff --git a/components/browser_ui/site_settings/android/website_preference_brid
          value = CONTENT_SETTING_ALLOW;
          break;
        default:
-@@ -894,6 +906,17 @@ static jboolean JNI_WebsitePreferenceBridge_IsContentSettingUserModifiable(
-       static_cast<ContentSettingsType>(content_settings_type));
- }
- 
-+static void JNI_WebsitePreferenceBridge_GetAutoplayOrigins(
-+    JNIEnv* env,
-+    const JavaParamRef<jobject>& jbrowser_context_handle,
-+    const JavaParamRef<jobject>& list,
-+    jboolean managedOnly) {
-+  GetOrigins(env, jbrowser_context_handle,
-+             ContentSettingsType::AUTOPLAY,
-+             &Java_WebsitePreferenceBridge_insertPermissionInfoIntoList, list,
-+             managedOnly);
-+}
-+
- static jboolean JNI_WebsitePreferenceBridge_IsContentSettingManagedByCustodian(
-     JNIEnv* env,
-     const JavaParamRef<jobject>& jbrowser_context_handle,
 diff --git a/components/browser_ui/strings/android/site_settings.grdp b/components/browser_ui/strings/android/site_settings.grdp
+index 9a03fda430baa..35c484f1f74b1 100644
 --- a/components/browser_ui/strings/android/site_settings.grdp
 +++ b/components/browser_ui/strings/android/site_settings.grdp
 @@ -12,6 +12,15 @@
@@ -414,6 +373,7 @@ diff --git a/components/browser_ui/strings/android/site_settings.grdp b/componen
      Augmented reality
    </message>
 diff --git a/components/content_settings/core/browser/content_settings_registry.cc b/components/content_settings/core/browser/content_settings_registry.cc
+index 336b5498e3ff4..6de84a2e75ca0 100644
 --- a/components/content_settings/core/browser/content_settings_registry.cc
 +++ b/components/content_settings/core/browser/content_settings_registry.cc
 @@ -313,7 +313,7 @@ void ContentSettingsRegistry::Init() {
@@ -426,9 +386,10 @@ diff --git a/components/content_settings/core/browser/content_settings_registry.
             ValidSettings(CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK),
             WebsiteSettingsInfo::SINGLE_ORIGIN_ONLY_SCOPE,
 diff --git a/components/content_settings/core/browser/content_settings_utils.cc b/components/content_settings/core/browser/content_settings_utils.cc
+index 75473709e0ee6..e26e3d099bd1c 100644
 --- a/components/content_settings/core/browser/content_settings_utils.cc
 +++ b/components/content_settings/core/browser/content_settings_utils.cc
-@@ -143,6 +143,8 @@ void GetRendererContentSettingRules(const HostContentSettingsMap* map,
+@@ -152,6 +152,8 @@ void GetRendererContentSettingRules(const HostContentSettingsMap* map,
  #endif
    map->GetSettingsForOneType(ContentSettingsType::JAVASCRIPT,
                               &(rules->script_rules));
@@ -436,11 +397,12 @@ diff --git a/components/content_settings/core/browser/content_settings_utils.cc
 +                             &(rules->autoplay_rules));
    map->GetSettingsForOneType(ContentSettingsType::POPUPS,
                               &(rules->popup_redirect_rules));
- 
+ }
 diff --git a/components/content_settings/core/common/content_settings.cc b/components/content_settings/core/common/content_settings.cc
+index 7006397be6f0d..49d322793d64e 100644
 --- a/components/content_settings/core/common/content_settings.cc
 +++ b/components/content_settings/core/common/content_settings.cc
-@@ -185,6 +185,7 @@ bool RendererContentSettingRules::IsRendererContentSetting(
+@@ -187,6 +187,7 @@ bool RendererContentSettingRules::IsRendererContentSetting(
      ContentSettingsType content_type) {
    return content_type == ContentSettingsType::IMAGES ||
           content_type == ContentSettingsType::JAVASCRIPT ||
@@ -449,6 +411,7 @@ diff --git a/components/content_settings/core/common/content_settings.cc b/compo
           content_type == ContentSettingsType::POPUPS ||
           content_type == ContentSettingsType::MIXEDSCRIPT ||
 diff --git a/components/content_settings/core/common/content_settings.h b/components/content_settings/core/common/content_settings.h
+index 135e07ab6c5d2..2721a8d0d2e93 100644
 --- a/components/content_settings/core/common/content_settings.h
 +++ b/components/content_settings/core/common/content_settings.h
 @@ -77,6 +77,7 @@ struct RendererContentSettingRules {
@@ -458,8 +421,9 @@ diff --git a/components/content_settings/core/common/content_settings.h b/compon
 +  ContentSettingsForOneType autoplay_rules;
    ContentSettingsForOneType popup_redirect_rules;
    ContentSettingsForOneType mixed_content_rules;
-   ContentSettingsForOneType timezone_override_rules;
+   ContentSettingsForOneType auto_dark_content_rules;
 diff --git a/components/content_settings/core/common/content_settings.mojom b/components/content_settings/core/common/content_settings.mojom
+index f2f3eba2167a2..1393eb5741925 100644
 --- a/components/content_settings/core/common/content_settings.mojom
 +++ b/components/content_settings/core/common/content_settings.mojom
 @@ -75,6 +75,7 @@ struct ContentSettingPatternSource {
@@ -469,8 +433,9 @@ diff --git a/components/content_settings/core/common/content_settings.mojom b/co
 +  array<ContentSettingPatternSource> autoplay_rules;
    array<ContentSettingPatternSource> popup_redirect_rules;
    array<ContentSettingPatternSource> mixed_content_rules;
-   array<ContentSettingPatternSource> timezone_override_rules;
+   array<ContentSettingPatternSource> auto_dark_content_rules;
 diff --git a/components/content_settings/core/common/content_settings_mojom_traits.cc b/components/content_settings/core/common/content_settings_mojom_traits.cc
+index 4ae7a3b123dc2..af71710b33e8d 100644
 --- a/components/content_settings/core/common/content_settings_mojom_traits.cc
 +++ b/components/content_settings/core/common/content_settings_mojom_traits.cc
 @@ -99,6 +99,7 @@ bool StructTraits<content_settings::mojom::RendererContentSettingRulesDataView,
@@ -480,8 +445,9 @@ diff --git a/components/content_settings/core/common/content_settings_mojom_trai
 +         data.ReadAutoplayRules(&out->autoplay_rules) &&
           data.ReadPopupRedirectRules(&out->popup_redirect_rules) &&
           data.ReadMixedContentRules(&out->mixed_content_rules) &&
-          data.ReadTimezoneOverrideRules(&out->timezone_override_rules) &&
+          data.ReadAutoDarkContentRules(&out->auto_dark_content_rules);
 diff --git a/components/content_settings/core/common/content_settings_mojom_traits.h b/components/content_settings/core/common/content_settings_mojom_traits.h
+index 7127ca7d852b6..66244e9875e43 100644
 --- a/components/content_settings/core/common/content_settings_mojom_traits.h
 +++ b/components/content_settings/core/common/content_settings_mojom_traits.h
 @@ -135,6 +135,11 @@ struct StructTraits<
@@ -497,9 +463,10 @@ diff --git a/components/content_settings/core/common/content_settings_mojom_trai
        const RendererContentSettingRules& r) {
      return r.popup_redirect_rules;
 diff --git a/components/content_settings/renderer/content_settings_agent_impl.cc b/components/content_settings/renderer/content_settings_agent_impl.cc
+index c88d87dc4c5f0..defee1d9a7f31 100644
 --- a/components/content_settings/renderer/content_settings_agent_impl.cc
 +++ b/components/content_settings/renderer/content_settings_agent_impl.cc
-@@ -423,6 +423,17 @@ bool ContentSettingsAgentImpl::AllowRunningInsecureContent(
+@@ -427,6 +427,17 @@ bool ContentSettingsAgentImpl::AllowRunningInsecureContent(
    return false;
  }
  
@@ -518,9 +485,10 @@ diff --git a/components/content_settings/renderer/content_settings_agent_impl.cc
    if (!content_setting_rules_)
      return default_value;
 diff --git a/components/content_settings/renderer/content_settings_agent_impl.h b/components/content_settings/renderer/content_settings_agent_impl.h
+index e618979c959c3..3d833922010ef 100644
 --- a/components/content_settings/renderer/content_settings_agent_impl.h
 +++ b/components/content_settings/renderer/content_settings_agent_impl.h
-@@ -94,6 +94,7 @@ class ContentSettingsAgentImpl
+@@ -99,6 +99,7 @@ class ContentSettingsAgentImpl
    void DidNotAllowScript() override;
    bool AllowRunningInsecureContent(bool allowed_per_settings,
                                     const blink::WebURL& url) override;
@@ -529,6 +497,7 @@ diff --git a/components/content_settings/renderer/content_settings_agent_impl.h
    void PassiveInsecureContentFound(const blink::WebURL& resource_url) override;
    bool ShouldAutoupgradeMixedContent() override;
 diff --git a/components/page_info/android/page_info_controller_android.cc b/components/page_info/android/page_info_controller_android.cc
+index a3c94a59322ec..8362dea2f051c 100644
 --- a/components/page_info/android/page_info_controller_android.cc
 +++ b/components/page_info/android/page_info_controller_android.cc
 @@ -134,6 +134,7 @@ void PageInfoControllerAndroid::SetPermissionInfo(
@@ -540,6 +509,7 @@ diff --git a/components/page_info/android/page_info_controller_android.cc b/comp
    if (base::FeatureList::IsEnabled(features::kWebNfc))
      permissions_to_display.push_back(ContentSettingsType::NFC);
 diff --git a/components/page_info/page_info.cc b/components/page_info/page_info.cc
+index e0a09a3fa24b1..328220fe1243e 100644
 --- a/components/page_info/page_info.cc
 +++ b/components/page_info/page_info.cc
 @@ -97,6 +97,7 @@ ContentSettingsType kPermissionType[] = {
@@ -563,6 +533,7 @@ diff --git a/components/page_info/page_info.cc b/components/page_info/page_info.
      // The sound content setting should always show up when the tab has played
      // audio.
 diff --git a/components/page_info/page_info_ui.cc b/components/page_info/page_info_ui.cc
+index 7aacf8ff75ab7..236cb026b74c5 100644
 --- a/components/page_info/page_info_ui.cc
 +++ b/components/page_info/page_info_ui.cc
 @@ -161,6 +161,7 @@ base::span<const PageInfoUI::PermissionUIInfo> GetContentSettingsUIInfo() {
@@ -574,6 +545,7 @@ diff --git a/components/page_info/page_info_ui.cc b/components/page_info/page_in
       IDS_SITE_SETTINGS_TYPE_SOUND_MID_SENTENCE},
      {ContentSettingsType::CLIPBOARD_READ_WRITE,
 diff --git a/components/site_settings_strings.grdp b/components/site_settings_strings.grdp
+index 923aa610485ce..d99c482facf22 100644
 --- a/components/site_settings_strings.grdp
 +++ b/components/site_settings_strings.grdp
 @@ -130,6 +130,9 @@
@@ -594,9 +566,10 @@ diff --git a/components/site_settings_strings.grdp b/components/site_settings_st
 \ No newline at end of file
 +</grit-part>
 diff --git a/third_party/blink/public/platform/web_content_settings_client.h b/third_party/blink/public/platform/web_content_settings_client.h
+index 87d4a0ee3887d..d61ff95389243 100644
 --- a/third_party/blink/public/platform/web_content_settings_client.h
 +++ b/third_party/blink/public/platform/web_content_settings_client.h
-@@ -87,6 +87,9 @@ class WebContentSettingsClient {
+@@ -92,6 +92,9 @@ class WebContentSettingsClient {
    // interface.
    virtual bool AllowMutationEvents(bool default_value) { return default_value; }
  
@@ -607,6 +580,7 @@ diff --git a/third_party/blink/public/platform/web_content_settings_client.h b/t
      return default_value;
    }
 diff --git a/third_party/blink/renderer/core/html/media/autoplay_policy.cc b/third_party/blink/renderer/core/html/media/autoplay_policy.cc
+index e0413d62cc3c1..91b681a8d1bd7 100644
 --- a/third_party/blink/renderer/core/html/media/autoplay_policy.cc
 +++ b/third_party/blink/renderer/core/html/media/autoplay_policy.cc
 @@ -8,6 +8,7 @@
@@ -643,6 +617,7 @@ diff --git a/third_party/blink/renderer/core/html/media/autoplay_policy.cc b/thi
    if (!element_->GetExecutionContext() ||
        element_->GetExecutionContext()->IsSandboxed(
 diff --git a/third_party/blink/renderer/core/html/media/autoplay_policy.h b/third_party/blink/renderer/core/html/media/autoplay_policy.h
+index 2d8dc569e465e..ee99746385c4b 100644
 --- a/third_party/blink/renderer/core/html/media/autoplay_policy.h
 +++ b/third_party/blink/renderer/core/html/media/autoplay_policy.h
 @@ -132,6 +132,10 @@ class CORE_EXPORT AutoplayPolicy final

+ 4 - 4
build/patches/Show-site-settings-for-cookies-javascript-and-ads.patch

@@ -11,7 +11,7 @@ Avoid displaying info about intrusive ads
 diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
 --- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
 +++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleWebsiteSettings.java
-@@ -484,6 +484,8 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment
+@@ -487,6 +487,8 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment
                  setUpSoundPreference(preference);
              } else if (type == ContentSettingsType.JAVASCRIPT) {
                  setUpJavascriptPreference(preference);
@@ -20,7 +20,7 @@ diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/c
              } else if (type == ContentSettingsType.GEOLOCATION) {
                  setUpLocationPreference(preference);
              } else if (type == ContentSettingsType.NOTIFICATIONS) {
-@@ -810,16 +812,8 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment
+@@ -813,16 +815,8 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment
      private void setUpAdsInformationalBanner() {
          // Add the informational banner which shows at the top of the UI if ad blocking is
          // activated on this site.
@@ -37,7 +37,7 @@ diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/c
      }
  
      private SiteSettingsCategory getWarningCategory() {
-@@ -977,17 +971,35 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment
+@@ -984,17 +978,35 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment
          @Nullable
          Integer currentValue =
                  mSite.getContentSetting(browserContextHandle, ContentSettingsType.JAVASCRIPT);
@@ -79,7 +79,7 @@ diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/c
      /**
       * Updates the ads list preference based on whether the site is a candidate for blocking. This
       * has some custom behavior.
-@@ -1003,22 +1015,10 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment
+@@ -1010,22 +1022,10 @@ public class SingleWebsiteSettings extends SiteSettingsPreferenceFragment
              setupContentSettingsPreference(preference, null, false);
              return;
          }

Some files were not shown because too many files changed in this diff