From 45b1ffb4f46dbcac1b16b44f564840c5f16a4238 Mon Sep 17 00:00:00 2001 From: Saalim Quadri Date: Tue, 18 Nov 2025 11:14:00 +0530 Subject: [PATCH 1/4] Integrate cromite as a submodule Signed-off-by: Saalim Quadri --- .gitmodules | 3 +++ README.md | 6 ++++++ build.sh | 13 ++++++++++++- build/.gitignore | 1 - build/cromite | 1 + update_cromite_patches.sh | 34 +++++++++++++++++++--------------- 6 files changed, 41 insertions(+), 17 deletions(-) create mode 100644 .gitmodules delete mode 100644 build/.gitignore create mode 160000 build/cromite diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..86b05109 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "build/cromite"] + path = build/cromite + url = https://github.com/uazo/cromite diff --git a/README.md b/README.md index 0eb453be..f56bffe9 100644 --- a/README.md +++ b/README.md @@ -35,3 +35,9 @@ Browser is built using the [GitLab's CI/CD](https://docs.gitlab.com/ee/ci/). You - A the list of contributors can be viewed on this repository's [contributors graph](https://gitlab.e.foundation/e/os/browser/-/graphs/master). In case you wish to contribute to the development of this project, feel free to open a [Merge Request](https://gitlab.e.foundation/e/os/browser/-/merge_requests) or an [Issue](https://gitlab.e.foundation/e/backlog/-/issues/) for the same. Contributions are always welcome. + +## Cromite patches +- The Cromite patch set is tracked via the `build/cromite` git submodule (upstream: [uazo/cromite](https://github.com/uazo/cromite)). +- After cloning this repository, run `git submodule update --init --recursive build/cromite` before building. +- `./update_cromite_patches.sh` fast-forwards the submodule to the branch or tag defined by `cromite_branch` in `versions.txt`. +- `build.sh` applies patches directly from `build/cromite/build/patches` using the order defined in `build/cromite_patches_list.txt`, so the submodule must be kept in sync. diff --git a/build.sh b/build.sh index 13a4fd71..9ec78387 100755 --- a/build.sh +++ b/build.sh @@ -110,8 +110,19 @@ patch() { echo ">> [$(date)] Applying cromite patches" cromite_patches_list=$(cat "${root_dir}/build/cromite_patches_list.txt") + cromite_patch_dir="${root_dir}/build/cromite/build/patches" + if [ ! -d "${cromite_patch_dir}" ]; then + echo "Cromite patches directory not found at ${cromite_patch_dir}." + echo "Ensure the cromite submodule is initialized (run ./update_cromite_patches.sh)." + exit 1 + fi for file in $cromite_patches_list; do - git am -C0 -3 --ignore-whitespace "${root_dir}/build/cromite_patches/$file" + patch_path="${cromite_patch_dir}/$file" + if [ ! -f "${patch_path}" ]; then + echo "Patch ${patch_path} missing." + exit 1 + fi + git am -C0 -3 --ignore-whitespace "${patch_path}" done echo ">> [$(date)] Applying /e/ patches" diff --git a/build/.gitignore b/build/.gitignore deleted file mode 100644 index 4ac1fbaf..00000000 --- a/build/.gitignore +++ /dev/null @@ -1 +0,0 @@ -cromite/ diff --git a/build/cromite b/build/cromite new file mode 160000 index 00000000..8f68189b --- /dev/null +++ b/build/cromite @@ -0,0 +1 @@ +Subproject commit 8f68189b3b33eaccd1bff868f1c7347ab7077afc diff --git a/update_cromite_patches.sh b/update_cromite_patches.sh index 64c0065f..d7fd5bbb 100755 --- a/update_cromite_patches.sh +++ b/update_cromite_patches.sh @@ -1,24 +1,28 @@ #!/usr/bin/env bash -root_dir=$(dirname "$(readlink -f "$0")") +set -euo pipefail +root_dir=$(dirname "$(readlink -f "$0")") branch=$(grep 'cromite_branch' versions.txt | awk -F'"' '{print $2}') +cromite_dir="${root_dir}/build/cromite" + +if [ ! -d "${cromite_dir}/.git" ]; then + echo ">> Cromite submodule not initialized, fetching it now" + git -C "${root_dir}" submodule update --init --recursive build/cromite +fi + +cd "${cromite_dir}" -cd $root_dir/build -if [ -d cromite ]; then - cd cromite - git fetch origin $branch - git reset --hard FETCH_HEAD - cd .. -else - git clone https://gitlab.e.foundation/e/os/cromite.git -b $branch cromite --depth=1 +if [ -n "$(git status --porcelain)" ]; then + echo "!! Cromite submodule has local changes. Please commit or stash them before updating." + exit 1 fi -rm -rf cromite_patches/* +echo ">> Fetching cromite branch/tag ${branch}" +git fetch --tags origin +git fetch origin "${branch}" -cromite_patches_list=$(cat "cromite_patches_list.txt") -for file in $cromite_patches_list; do - cp cromite/build/patches/$file "cromite_patches/$file" -done +git checkout --detach FETCH_HEAD +git reset --hard FETCH_HEAD -echo "Copy done" +echo ">> Cromite submodule updated to $(git rev-parse --short HEAD) (${branch})" -- GitLab From b6214d68d6cf7245d05abb40060fec64eada1748 Mon Sep 17 00:00:00 2001 From: Saalim Quadri Date: Tue, 18 Nov 2025 11:14:26 +0530 Subject: [PATCH 2/4] Remote cromite_patches Signed-off-by: Saalim Quadri --- .../Add-AllowUserCertificates-flag.patch | 133 - ...dd-Alt-D-hotkey-to-focus-address-bar.patch | 26 - .../Add-IsCleartextPermitted-flag.patch | 59 - .../Add-a-proxy-configuration-page.patch | 1433 - .../Add-an-always-incognito-mode.patch | 2241 - .../Add-autoplay-site-setting.patch | 343 - .../Add-bookmark-import-export-actions.patch | 1650 - .../Add-cromite-flags-support.patch | 2104 - ...dd-custom-tab-intents-privacy-option.patch | 438 - .../cromite_patches/Add-exit-menu-item.patch | 121 - ...g-for-omnibox-autocomplete-filtering.patch | 137 - .../Add-flag-for-save-data-header.patch | 73 - ...nfigure-maximum-connections-per-host.patch | 126 - ...ontrol-video-playback-resume-feature.patch | 39 - .../Add-flag-to-disable-IPv6-probes.patch | 81 - ...-to-disable-external-intent-requests.patch | 277 - .../Add-flag-to-disable-vibration.patch | 118 - ...Add-lifetime-options-for-permissions.patch | 1431 - .../Add-menu-item-to-bookmark-all-tabs.patch | 931 - .../Add-menu-item-to-view-source.patch | 128 - .../Add-option-to-force-tablet-UI.patch | 747 - ...-to-not-persist-tabs-across-sessions.patch | 120 - .../Add-option-to-use-home-page-as-NTP.patch | 294 - build/cromite_patches/Add-search-engine.patch | 418 - .../Add-site-engagement-flag.patch | 263 - ...-support-for-ISupportHelpAndFeedback.patch | 52 - .../Add-support-for-writing-URIs.patch | 99 - .../Add-webGL-site-setting.patch | 286 - .../Add-webRTC-site-settings.patch | 266 - ...ow-building-without-enable_reporting.patch | 560 - ...ow-building-without-supervised-users.patch | 247 - .../Allow-playing-audio-in-background.patch | 52 - ...e-new-tab-page-for-default-home-page.patch | 96 - ...ioBuffer-AnalyserNode-fp-mitigations.patch | 233 - .../Battery-API-return-nothing.patch | 66 - .../Block-qjz9zk-or-trk-requests.patch | 277 - .../Bookmarks-select-all-menu-entry.patch | 93 - .../Bromite-package-name.patch | 22 - .../Bromite-subresource-adblocker.patch | 2038 - .../Client-hints-overrides.patch | 280 - ...ress-libchrome-to-free-up-some-space.patch | 24 - .../Content-settings-infrastructure.patch | 3675 -- ...ctionary-suggestions-for-the-Omnibox.patch | 107 - ...ble-Accessibility-service-by-default.patch | 57 - .../Disable-Android-Tab-Declutter.patch | 50 - .../Disable-AsyncDNS-by-default.patch | 20 - ...DRM-media-origin-IDs-preprovisioning.patch | 21 - .../Disable-Feeback-Collector.patch | 74 - ...le-NTP-remote-suggestions-by-default.patch | 24 - .../Disable-PrivacyGuide.patch | 35 - .../Disable-TLS-resumption.patch | 252 - .../Disable-UA-full-version.patch | 61 - .../Disable-all-predictors-code.patch | 1456 - .../Disable-all-promo-dialogs.patch | 135 - .../Disable-conversion-measurement-api.patch | 1167 - .../Disable-crash-reporting.patch | 66 - .../Disable-feeds-support-by-default.patch | 94 - ...Disable-fetching-of-all-field-trials.patch | 465 - .../Disable-idle-detection.patch | 70 - ...media-router-and-remoting-by-default.patch | 100 - .../Disable-minidump-upload-scheduling.patch | 38 - .../Disable-offline-pages-in-CCT.patch | 17 - .../Disable-omission-of-URL-elements.patch | 171 - .../Disable-plugins-enumeration.patch | 23 - ...e-privacy-issues-in-password-manager.patch | 199 - .../Disable-privacy-sandbox.patch | 490 - ...e-references-to-fonts.googleapis.com.patch | 90 - ...sts-for-single-word-Omnibar-searches.patch | 45 - .../Disable-safety-check.patch | 284 - .../Disable-smart-selection-by-default.patch | 92 - ...isable-some-signed-exchange-features.patch | 35 - .../Disable-text-fragments-by-default.patch | 108 - ...Disable-the-DIAL-repeating-discovery.patch | 35 - .../Disable-third-party-origin-trials.patch | 279 - .../Disable-update-scheduler.patch | 22 - .../Disable-various-metrics.patch | 258 - .../Do-not-build-API-keys-infobar.patch | 44 - .../Do-not-compile-QR-code-sharing.patch | 194 - ...ore-download-location-prompt-setting.patch | 43 - .../Do-not-link-with-libatomic.patch | 26 - .../Do-not-store-passwords-by-default.patch | 42 - build/cromite_patches/DoH-improvements.patch | 183 - .../Enable-Certificate-Transparency.patch | 124 - .../Enable-HEVC-by-default.patch | 24 - .../Enable-ImprovedBookmarks-by-default.patch | 84 - ...ctOriginIsolation-and-SitePerProcess.patch | 80 - ...e-darken-websites-checkbox-in-themes.patch | 40 - ...fwrapv-in-Clang-for-non-UBSan-builds.patch | 59 - .../Enable-native-Android-autofill.patch | 921 - .../Enable-network-isolation-features.patch | 118 - .../cromite_patches/Enable-share-intent.patch | 544 - ...ble-third-party-storage-partitioning.patch | 17 - .../Experimental-user-scripts-support.patch | 11509 ---- .../Eyeo-Adblock-for-Cromite.patch | 13078 ---- .../Final-patch-for-chromium-vanilla.patch | 17 - .../Fix-chromium-build-bugs.patch | 141 - .../Fix-chromium-vanilla.patch | 34 - .../Follow-only-system-dark-mode.patch | 24 - ...ing-against-incognito-mode-detection.patch | 44 - ...story-number-of-days-privacy-setting.patch | 669 - ...e-enterprise-policies-for-secure-DNS.patch | 28 - ...prove-plain-text-rendering-on-mobile.patch | 34 - ...number-of-autocomplete-matches-to-10.patch | 46 - .../Invalidate-components-public-key.patch | 25 - build/cromite_patches/JIT-site-settings.patch | 393 - .../Keep-empty-tabs-between-sessions.patch | 58 - ...-allow-screenshots-in-Incognito-mode.patch | 45 - .../Logcat-crash-reports-UI.patch | 945 - .../Modify-default-preferences.patch | 331 - .../Move-navigation-bar-to-bottom.patch | 3244 - ...nt-settings-back-to-privacy-settings.patch | 122 - .../Never-fetch-popular-sites.patch | 44 - ...HTTP-probes-for-connection-detection.patch | 26 - .../OpenSearch-miscellaneous.patch | 334 - .../Override-Navigator-Language.patch | 85 - .../Partition-Blink-memory-cache.patch | 273 - .../Partition-blobs-by-top-frame-URL.patch | 435 - ...-modal-dialog-flag-to-close-all-tabs.patch | 107 - ...e-introduce-override_build_timestamp.patch | 48 - ...ders-in-DoH-requests-to-bare-minimum.patch | 76 - .../Remove-EV-certificates.patch | 60 - ...referrals-in-cross-origin-navigation.patch | 681 - .../Remove-SMS-integration.patch | 444 - .../Remove-binary-blob-integrations.patch | 4860 -- ...cklisted-URLs-upon-bookmark-creation.patch | 48 - .../Remove-help-menu-item.patch | 232 - ...load-of-com.google.android.gms.fonts.patch | 70 - .../Remove-segmentation-platform.patch | 58 - ...Remove-voice-recognition-integration.patch | 774 - ...ndow-name-on-cross-origin-navigation.patch | 55 - ...ce-DoH-probe-domain-with-RIPE-domain.patch | 37 - ...ore-BookmarkToolbar-setCurrentFolder.patch | 141 - .../Restore-LastTabStandingTracker.patch | 421 - .../Restore-Search-Ready-Omnibox-flag.patch | 120 - .../Restore-Simplified-NTP-launch.patch | 1669 - ...-button-in-top-toolbar-customization.patch | 281 - .../Restore-chrome-password-store.patch | 6442 -- .../Restore-classic-new-tab-page.patch | 87 - .../Restore-offline-indicator-v2-flag.patch | 170 - ...evert-Permit-blocking-of-view-source.patch | 23 - ...emove-disable-pull-to-refresh-effect.patch | 145 - ...vert-flags-remove-num-raster-threads.patch | 41 - ...l-of-execution-context-address-space.patch | 874 - ...script-content-setting-secondary-url.patch | 400 - ...-Note-9-SDK27-crazylinker-workaround.patch | 45 - ...tings-for-cookies-javascript-and-ads.patch | 139 - .../Site-setting-for-images.patch | 515 - .../Switch-to-fstack-protector-strong.patch | 31 - .../Temp-disable-UseContextSnapshot.patch | 23 - .../Timezone-customization.patch | 1084 - .../Use-64-bit-WebView-processes.patch | 41 - .../Use-browser-navigation-handler.patch | 388 - .../Use-dummy-DFM-installer.patch | 225 - .../User-agent-customization.patch | 1341 - build/cromite_patches/Welcome-screen.patch | 1251 - .../autofill-miscellaneous.patch | 335 - .../cromite_patches/bromite-build-utils.patch | 812 - .../disable-AdsBlockedInfoBar.patch | 21 - .../disable-WebView-variations-support.patch | 43 - .../disable-appending-variations-header.patch | 25 - .../disable-battery-status-updater.patch | 48 - ...IPv6-connectivity-probes-to-RIPE-DNS.patch | 59 - .../do-not-add-suffix-to-package-name.patch | 22 - .../do-not-hide-.orig-files.patch | 22 - .../enable-ftrivial-auto-var-init-zero.patch | 25 - .../exit-on-failure-of-inclusion.patch | 32 - .../eyeo-133.0.6943.49-android_api.patch | 5959 -- .../eyeo-133.0.6943.49-android_settings.patch | 3506 -- .../eyeo-133.0.6943.49-base.patch | 51803 ---------------- ...yeo-133.0.6943.49-chrome_integration.patch | 4066 -- .../eyeo-133.0.6943.49-extension_api.patch | 5981 -- build/cromite_patches/kill-Auth.patch | 26 - .../kill-Location-fall-back-to-system.patch | 77 - build/cromite_patches/kill-Vision.patch | 128 - ...rce-text-x-suse-ymp-to-be-downloaded.patch | 24 - ...always-prompt-for-download-directory.patch | 43 - ...ofile-resetter-disable-send-settings.patch | 30 - .../sharing-hub-always-use-visible-URL.patch | 21 - ...le-fetching-of-languages-from-server.patch | 29 - ...hromium-Disable-Network-Time-Tracker.patch | 35 - ...d-chromium-Disable-intranet-detector.patch | 28 - ...gled-chromium-Disable-profile-avatar.patch | 54 - ...romium-Disable-translate-integration.patch | 229 - ...ed-chromium-Disable-untraceable-URLs.patch | 76 - ...chromium-Disable-webRTC-log-uploader.patch | 22 - ...ed-chromium-no-special-hosts-domains.patch | 1967 - ...RTC-do-not-expose-local-IP-addresses.patch | 57 - ...iew-Hard-no-to-persistent-histograms.patch | 35 - 188 files changed, 162151 deletions(-) delete mode 100644 build/cromite_patches/Add-AllowUserCertificates-flag.patch delete mode 100644 build/cromite_patches/Add-Alt-D-hotkey-to-focus-address-bar.patch delete mode 100644 build/cromite_patches/Add-IsCleartextPermitted-flag.patch delete mode 100644 build/cromite_patches/Add-a-proxy-configuration-page.patch delete mode 100644 build/cromite_patches/Add-an-always-incognito-mode.patch delete mode 100644 build/cromite_patches/Add-autoplay-site-setting.patch delete mode 100644 build/cromite_patches/Add-bookmark-import-export-actions.patch delete mode 100644 build/cromite_patches/Add-cromite-flags-support.patch delete mode 100644 build/cromite_patches/Add-custom-tab-intents-privacy-option.patch delete mode 100644 build/cromite_patches/Add-exit-menu-item.patch delete mode 100644 build/cromite_patches/Add-flag-for-omnibox-autocomplete-filtering.patch delete mode 100644 build/cromite_patches/Add-flag-for-save-data-header.patch delete mode 100644 build/cromite_patches/Add-flag-to-configure-maximum-connections-per-host.patch delete mode 100644 build/cromite_patches/Add-flag-to-control-video-playback-resume-feature.patch delete mode 100644 build/cromite_patches/Add-flag-to-disable-IPv6-probes.patch delete mode 100644 build/cromite_patches/Add-flag-to-disable-external-intent-requests.patch delete mode 100644 build/cromite_patches/Add-flag-to-disable-vibration.patch delete mode 100644 build/cromite_patches/Add-lifetime-options-for-permissions.patch delete mode 100644 build/cromite_patches/Add-menu-item-to-bookmark-all-tabs.patch delete mode 100644 build/cromite_patches/Add-menu-item-to-view-source.patch delete mode 100644 build/cromite_patches/Add-option-to-force-tablet-UI.patch delete mode 100644 build/cromite_patches/Add-option-to-not-persist-tabs-across-sessions.patch delete mode 100644 build/cromite_patches/Add-option-to-use-home-page-as-NTP.patch delete mode 100644 build/cromite_patches/Add-search-engine.patch delete mode 100644 build/cromite_patches/Add-site-engagement-flag.patch delete mode 100644 build/cromite_patches/Add-support-for-ISupportHelpAndFeedback.patch delete mode 100644 build/cromite_patches/Add-support-for-writing-URIs.patch delete mode 100644 build/cromite_patches/Add-webGL-site-setting.patch delete mode 100644 build/cromite_patches/Add-webRTC-site-settings.patch delete mode 100644 build/cromite_patches/Allow-building-without-enable_reporting.patch delete mode 100644 build/cromite_patches/Allow-building-without-supervised-users.patch delete mode 100644 build/cromite_patches/Allow-playing-audio-in-background.patch delete mode 100644 build/cromite_patches/Always-use-new-tab-page-for-default-home-page.patch delete mode 100644 build/cromite_patches/AudioBuffer-AnalyserNode-fp-mitigations.patch delete mode 100644 build/cromite_patches/Battery-API-return-nothing.patch delete mode 100644 build/cromite_patches/Block-qjz9zk-or-trk-requests.patch delete mode 100644 build/cromite_patches/Bookmarks-select-all-menu-entry.patch delete mode 100644 build/cromite_patches/Bromite-package-name.patch delete mode 100644 build/cromite_patches/Bromite-subresource-adblocker.patch delete mode 100644 build/cromite_patches/Client-hints-overrides.patch delete mode 100644 build/cromite_patches/Compress-libchrome-to-free-up-some-space.patch delete mode 100644 build/cromite_patches/Content-settings-infrastructure.patch delete mode 100644 build/cromite_patches/Dictionary-suggestions-for-the-Omnibox.patch delete mode 100644 build/cromite_patches/Disable-Accessibility-service-by-default.patch delete mode 100644 build/cromite_patches/Disable-Android-Tab-Declutter.patch delete mode 100644 build/cromite_patches/Disable-AsyncDNS-by-default.patch delete mode 100644 build/cromite_patches/Disable-DRM-media-origin-IDs-preprovisioning.patch delete mode 100644 build/cromite_patches/Disable-Feeback-Collector.patch delete mode 100644 build/cromite_patches/Disable-NTP-remote-suggestions-by-default.patch delete mode 100644 build/cromite_patches/Disable-PrivacyGuide.patch delete mode 100644 build/cromite_patches/Disable-TLS-resumption.patch delete mode 100644 build/cromite_patches/Disable-UA-full-version.patch delete mode 100644 build/cromite_patches/Disable-all-predictors-code.patch delete mode 100644 build/cromite_patches/Disable-all-promo-dialogs.patch delete mode 100644 build/cromite_patches/Disable-conversion-measurement-api.patch delete mode 100644 build/cromite_patches/Disable-crash-reporting.patch delete mode 100644 build/cromite_patches/Disable-feeds-support-by-default.patch delete mode 100644 build/cromite_patches/Disable-fetching-of-all-field-trials.patch delete mode 100644 build/cromite_patches/Disable-idle-detection.patch delete mode 100644 build/cromite_patches/Disable-media-router-and-remoting-by-default.patch delete mode 100644 build/cromite_patches/Disable-minidump-upload-scheduling.patch delete mode 100644 build/cromite_patches/Disable-offline-pages-in-CCT.patch delete mode 100644 build/cromite_patches/Disable-omission-of-URL-elements.patch delete mode 100644 build/cromite_patches/Disable-plugins-enumeration.patch delete mode 100644 build/cromite_patches/Disable-privacy-issues-in-password-manager.patch delete mode 100644 build/cromite_patches/Disable-privacy-sandbox.patch delete mode 100644 build/cromite_patches/Disable-references-to-fonts.googleapis.com.patch delete mode 100644 build/cromite_patches/Disable-requests-for-single-word-Omnibar-searches.patch delete mode 100644 build/cromite_patches/Disable-safety-check.patch delete mode 100644 build/cromite_patches/Disable-smart-selection-by-default.patch delete mode 100644 build/cromite_patches/Disable-some-signed-exchange-features.patch delete mode 100644 build/cromite_patches/Disable-text-fragments-by-default.patch delete mode 100644 build/cromite_patches/Disable-the-DIAL-repeating-discovery.patch delete mode 100644 build/cromite_patches/Disable-third-party-origin-trials.patch delete mode 100644 build/cromite_patches/Disable-update-scheduler.patch delete mode 100644 build/cromite_patches/Disable-various-metrics.patch delete mode 100644 build/cromite_patches/Do-not-build-API-keys-infobar.patch delete mode 100644 build/cromite_patches/Do-not-compile-QR-code-sharing.patch delete mode 100644 build/cromite_patches/Do-not-ignore-download-location-prompt-setting.patch delete mode 100644 build/cromite_patches/Do-not-link-with-libatomic.patch delete mode 100644 build/cromite_patches/Do-not-store-passwords-by-default.patch delete mode 100644 build/cromite_patches/DoH-improvements.patch delete mode 100644 build/cromite_patches/Enable-Certificate-Transparency.patch delete mode 100644 build/cromite_patches/Enable-HEVC-by-default.patch delete mode 100644 build/cromite_patches/Enable-ImprovedBookmarks-by-default.patch delete mode 100644 build/cromite_patches/Enable-StrictOriginIsolation-and-SitePerProcess.patch delete mode 100644 build/cromite_patches/Enable-darken-websites-checkbox-in-themes.patch delete mode 100644 build/cromite_patches/Enable-fwrapv-in-Clang-for-non-UBSan-builds.patch delete mode 100644 build/cromite_patches/Enable-native-Android-autofill.patch delete mode 100644 build/cromite_patches/Enable-network-isolation-features.patch delete mode 100644 build/cromite_patches/Enable-share-intent.patch delete mode 100644 build/cromite_patches/Enable-third-party-storage-partitioning.patch delete mode 100644 build/cromite_patches/Experimental-user-scripts-support.patch delete mode 100644 build/cromite_patches/Eyeo-Adblock-for-Cromite.patch delete mode 100644 build/cromite_patches/Final-patch-for-chromium-vanilla.patch delete mode 100644 build/cromite_patches/Fix-chromium-build-bugs.patch delete mode 100644 build/cromite_patches/Fix-chromium-vanilla.patch delete mode 100644 build/cromite_patches/Follow-only-system-dark-mode.patch delete mode 100644 build/cromite_patches/Hardening-against-incognito-mode-detection.patch delete mode 100644 build/cromite_patches/History-number-of-days-privacy-setting.patch delete mode 100644 build/cromite_patches/Ignore-enterprise-policies-for-secure-DNS.patch delete mode 100644 build/cromite_patches/Improve-plain-text-rendering-on-mobile.patch delete mode 100644 build/cromite_patches/Increase-number-of-autocomplete-matches-to-10.patch delete mode 100644 build/cromite_patches/Invalidate-components-public-key.patch delete mode 100644 build/cromite_patches/JIT-site-settings.patch delete mode 100644 build/cromite_patches/Keep-empty-tabs-between-sessions.patch delete mode 100644 build/cromite_patches/Keep-flag-to-allow-screenshots-in-Incognito-mode.patch delete mode 100644 build/cromite_patches/Logcat-crash-reports-UI.patch delete mode 100644 build/cromite_patches/Modify-default-preferences.patch delete mode 100644 build/cromite_patches/Move-navigation-bar-to-bottom.patch delete mode 100644 build/cromite_patches/Move-some-account-settings-back-to-privacy-settings.patch delete mode 100644 build/cromite_patches/Never-fetch-popular-sites.patch delete mode 100644 build/cromite_patches/Never-use-HTTP-probes-for-connection-detection.patch delete mode 100644 build/cromite_patches/OpenSearch-miscellaneous.patch delete mode 100644 build/cromite_patches/Override-Navigator-Language.patch delete mode 100644 build/cromite_patches/Partition-Blink-memory-cache.patch delete mode 100644 build/cromite_patches/Partition-blobs-by-top-frame-URL.patch delete mode 100644 build/cromite_patches/Re-introduce-modal-dialog-flag-to-close-all-tabs.patch delete mode 100644 build/cromite_patches/Re-introduce-override_build_timestamp.patch delete mode 100644 build/cromite_patches/Reduce-HTTP-headers-in-DoH-requests-to-bare-minimum.patch delete mode 100644 build/cromite_patches/Remove-EV-certificates.patch delete mode 100644 build/cromite_patches/Remove-HTTP-referrals-in-cross-origin-navigation.patch delete mode 100644 build/cromite_patches/Remove-SMS-integration.patch delete mode 100644 build/cromite_patches/Remove-binary-blob-integrations.patch delete mode 100644 build/cromite_patches/Remove-blocklisted-URLs-upon-bookmark-creation.patch delete mode 100644 build/cromite_patches/Remove-help-menu-item.patch delete mode 100644 build/cromite_patches/Remove-preload-of-com.google.android.gms.fonts.patch delete mode 100644 build/cromite_patches/Remove-segmentation-platform.patch delete mode 100644 build/cromite_patches/Remove-voice-recognition-integration.patch delete mode 100644 build/cromite_patches/Remove-window-name-on-cross-origin-navigation.patch delete mode 100644 build/cromite_patches/Replace-DoH-probe-domain-with-RIPE-domain.patch delete mode 100644 build/cromite_patches/Restore-BookmarkToolbar-setCurrentFolder.patch delete mode 100644 build/cromite_patches/Restore-LastTabStandingTracker.patch delete mode 100644 build/cromite_patches/Restore-Search-Ready-Omnibox-flag.patch delete mode 100644 build/cromite_patches/Restore-Simplified-NTP-launch.patch delete mode 100644 build/cromite_patches/Restore-adaptive-button-in-top-toolbar-customization.patch delete mode 100644 build/cromite_patches/Restore-chrome-password-store.patch delete mode 100644 build/cromite_patches/Restore-classic-new-tab-page.patch delete mode 100644 build/cromite_patches/Restore-offline-indicator-v2-flag.patch delete mode 100644 build/cromite_patches/Revert-Permit-blocking-of-view-source.patch delete mode 100644 build/cromite_patches/Revert-flags-remove-disable-pull-to-refresh-effect.patch delete mode 100644 build/cromite_patches/Revert-flags-remove-num-raster-threads.patch delete mode 100644 build/cromite_patches/Revert-removal-of-execution-context-address-space.patch delete mode 100644 build/cromite_patches/Revert-remove-allowscript-content-setting-secondary-url.patch delete mode 100644 build/cromite_patches/Samsung-Note-9-SDK27-crazylinker-workaround.patch delete mode 100644 build/cromite_patches/Show-site-settings-for-cookies-javascript-and-ads.patch delete mode 100644 build/cromite_patches/Site-setting-for-images.patch delete mode 100644 build/cromite_patches/Switch-to-fstack-protector-strong.patch delete mode 100644 build/cromite_patches/Temp-disable-UseContextSnapshot.patch delete mode 100644 build/cromite_patches/Timezone-customization.patch delete mode 100644 build/cromite_patches/Use-64-bit-WebView-processes.patch delete mode 100644 build/cromite_patches/Use-browser-navigation-handler.patch delete mode 100644 build/cromite_patches/Use-dummy-DFM-installer.patch delete mode 100644 build/cromite_patches/User-agent-customization.patch delete mode 100644 build/cromite_patches/Welcome-screen.patch delete mode 100644 build/cromite_patches/autofill-miscellaneous.patch delete mode 100644 build/cromite_patches/bromite-build-utils.patch delete mode 100644 build/cromite_patches/disable-AdsBlockedInfoBar.patch delete mode 100644 build/cromite_patches/disable-WebView-variations-support.patch delete mode 100644 build/cromite_patches/disable-appending-variations-header.patch delete mode 100644 build/cromite_patches/disable-battery-status-updater.patch delete mode 100644 build/cromite_patches/dns-send-IPv6-connectivity-probes-to-RIPE-DNS.patch delete mode 100644 build/cromite_patches/do-not-add-suffix-to-package-name.patch delete mode 100644 build/cromite_patches/do-not-hide-.orig-files.patch delete mode 100644 build/cromite_patches/enable-ftrivial-auto-var-init-zero.patch delete mode 100644 build/cromite_patches/exit-on-failure-of-inclusion.patch delete mode 100644 build/cromite_patches/eyeo-133.0.6943.49-android_api.patch delete mode 100644 build/cromite_patches/eyeo-133.0.6943.49-android_settings.patch delete mode 100644 build/cromite_patches/eyeo-133.0.6943.49-base.patch delete mode 100644 build/cromite_patches/eyeo-133.0.6943.49-chrome_integration.patch delete mode 100644 build/cromite_patches/eyeo-133.0.6943.49-extension_api.patch delete mode 100644 build/cromite_patches/kill-Auth.patch delete mode 100644 build/cromite_patches/kill-Location-fall-back-to-system.patch delete mode 100644 build/cromite_patches/kill-Vision.patch delete mode 100644 build/cromite_patches/mime_util-force-text-x-suse-ymp-to-be-downloaded.patch delete mode 100644 build/cromite_patches/prefs-always-prompt-for-download-directory.patch delete mode 100644 build/cromite_patches/profile-resetter-disable-send-settings.patch delete mode 100644 build/cromite_patches/sharing-hub-always-use-visible-URL.patch delete mode 100644 build/cromite_patches/translate-disable-fetching-of-languages-from-server.patch delete mode 100644 build/cromite_patches/ungoogled-chromium-Disable-Network-Time-Tracker.patch delete mode 100644 build/cromite_patches/ungoogled-chromium-Disable-intranet-detector.patch delete mode 100644 build/cromite_patches/ungoogled-chromium-Disable-profile-avatar.patch delete mode 100644 build/cromite_patches/ungoogled-chromium-Disable-translate-integration.patch delete mode 100644 build/cromite_patches/ungoogled-chromium-Disable-untraceable-URLs.patch delete mode 100644 build/cromite_patches/ungoogled-chromium-Disable-webRTC-log-uploader.patch delete mode 100644 build/cromite_patches/ungoogled-chromium-no-special-hosts-domains.patch delete mode 100644 build/cromite_patches/webRTC-do-not-expose-local-IP-addresses.patch delete mode 100644 build/cromite_patches/webview-Hard-no-to-persistent-histograms.patch diff --git a/build/cromite_patches/Add-AllowUserCertificates-flag.patch b/build/cromite_patches/Add-AllowUserCertificates-flag.patch deleted file mode 100644 index 8a9e869b..00000000 --- a/build/cromite_patches/Add-AllowUserCertificates-flag.patch +++ /dev/null @@ -1,133 +0,0 @@ -From: uazo -Date: Mon, 26 Apr 2021 13:28:24 +0000 -Subject: Add AllowUserCertificates flag - -Original License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../chromium/chrome/browser/app/ChromeActivity.java | 3 +++ - chrome/browser/flags/android/chrome_feature_list.cc | 1 + - .../chrome/browser/flags/ChromeFeatureList.java | 4 ++++ - .../Add-AllowUserCertificates-flag.inc | 13 +++++++++++++ - .../Add-AllowUserCertificates-flag.inc | 3 +++ - .../Add-AllowUserCertificates-flag.inc | 1 + - net/android/java/src/org/chromium/net/X509Util.java | 5 +++++ - 7 files changed, 30 insertions(+) - create mode 100644 cromite_flags/chrome/browser/about_flags_cc/Add-AllowUserCertificates-flag.inc - create mode 100644 cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/Add-AllowUserCertificates-flag.inc - create mode 100644 cromite_flags/chrome/browser/flags/android/chrome_feature_list_h/Add-AllowUserCertificates-flag.inc - -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 -@@ -242,6 +242,7 @@ import org.chromium.content_public.browser.LoadUrlParams; - import org.chromium.content_public.browser.SelectionPopupController; - import org.chromium.content_public.browser.WebContents; - import org.chromium.content_public.common.ContentSwitches; -+import org.chromium.net.X509Util; - import org.chromium.printing.PrintManagerDelegateImpl; - import org.chromium.printing.PrintingController; - import org.chromium.printing.PrintingControllerImpl; -@@ -1004,6 +1005,8 @@ public abstract class ChromeActivity extends AsyncInitializationActivity - super.onStartWithNative(); - - ChromeActivitySessionTracker.getInstance().onStartWithNative(getProfileProviderSupplier()); -+ X509Util.AllowUserCertificates = ChromeFeatureList.isEnabled( -+ ChromeFeatureList.ALLOW_USER_CERTIFICATES); - - // postDeferredStartupIfNeeded() is called in TabModelSelectorTabObsever#onLoadStopped(), - // #onPageLoadFinished() and #onCrash(). If we are not actively loading a tab (e.g. -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 -@@ -185,6 +185,7 @@ const base::Feature* const kFeaturesExposedToJava[] = { - &feed::kFeedPerformanceStudy, - &feed::kFeedShowSignInCommand, - &feed::kFeedSignedOutViewDemotion, -+ &kAllowUserCertificates, - &feed::kFeedRecyclerBinderUnmountOnDetach, - &feed::kInterestFeedV2, - &feed::kWebFeedAwareness, -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 -@@ -164,6 +164,7 @@ public abstract class ChromeFeatureList { - "AccountForSuppressedKeyboardInsets"; - public static final String ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_CUSTOMIZATION_V2 = - "AdaptiveButtonInTopToolbarCustomizationV2"; -+ public static final String ALLOW_USER_CERTIFICATES = "AllowUserCertificates"; - public static final String ADAPTIVE_BUTTON_IN_TOP_TOOLBAR_PAGE_SUMMARY = - "AdaptiveButtonInTopToolbarPageSummary"; - public static final String ALLOW_TAB_CLOSING_UPON_MINIMIZATION = -@@ -807,6 +808,8 @@ public abstract class ChromeFeatureList { - public static final CachedFlag sAndroidWindowPopupResizeAfterSpawn = - newCachedFlag(ANDROID_WINDOW_POPUP_RESIZE_AFTER_SPAWN, false, true); - public static final CachedFlag sAppSpecificHistory = newCachedFlag(APP_SPECIFIC_HISTORY, true); -+ public static final CachedFlag sAllowUserCertificates = -+ newCachedFlag(ALLOW_USER_CERTIFICATES, false); - public static final CachedFlag sAppSpecificHistoryViewIntent = - newCachedFlag(APP_SPECIFIC_HISTORY_VIEW_INTENT, true); - public static final CachedFlag sAsyncNotificationManager = -@@ -1130,6 +1133,7 @@ public abstract class ChromeFeatureList { - sAllowTabClosingUponMinimization, - sAndroidAnimatedProgressBarInBrowser, - sAndroidAnimatedProgressBarInViz, -+ sAllowUserCertificates, - sAndroidAppIntegrationModule, - sAndroidAppIntegrationMultiDataSource, - sAndroidBottomToolbar, -diff --git a/cromite_flags/chrome/browser/about_flags_cc/Add-AllowUserCertificates-flag.inc b/cromite_flags/chrome/browser/about_flags_cc/Add-AllowUserCertificates-flag.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/chrome/browser/about_flags_cc/Add-AllowUserCertificates-flag.inc -@@ -0,0 +1,13 @@ -+#ifdef FLAG_SECTION -+ -+#if BUILDFLAG(IS_ANDROID) -+ -+ {"allow-user-certificates", -+ "Allow user certificates", -+ "Allow user CA certificates during " -+ "validation of the certificate chain", kOsAndroid, -+ FEATURE_VALUE_TYPE(chrome::android::kAllowUserCertificates)}, -+ -+#endif -+ -+#endif -diff --git a/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/Add-AllowUserCertificates-flag.inc b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/Add-AllowUserCertificates-flag.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/Add-AllowUserCertificates-flag.inc -@@ -0,0 +1,3 @@ -+CROMITE_FEATURE(kAllowUserCertificates, -+ "AllowUserCertificates", -+ base::FEATURE_DISABLED_BY_DEFAULT); -diff --git a/cromite_flags/chrome/browser/flags/android/chrome_feature_list_h/Add-AllowUserCertificates-flag.inc b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_h/Add-AllowUserCertificates-flag.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_h/Add-AllowUserCertificates-flag.inc -@@ -0,0 +1 @@ -+BASE_DECLARE_FEATURE(kAllowUserCertificates); -diff --git a/net/android/java/src/org/chromium/net/X509Util.java b/net/android/java/src/org/chromium/net/X509Util.java ---- a/net/android/java/src/org/chromium/net/X509Util.java -+++ b/net/android/java/src/org/chromium/net/X509Util.java -@@ -537,6 +537,8 @@ public class X509Util { - return userRootBytes.toArray(new byte[0][]); - } - -+ public static boolean AllowUserCertificates = false; -+ - public static AndroidCertVerifyResult verifyServerCertificates( - byte[][] certChain, - String authType, -@@ -639,6 +641,9 @@ public class X509Util { - X509Certificate root = verifiedChain.get(verifiedChain.size() - 1); - isIssuedByKnownRoot = isKnownRoot(root); - } -+ if (AllowUserCertificates == false && isIssuedByKnownRoot == false) -+ return new AndroidCertVerifyResult(CertVerifyStatusAndroid.NO_TRUSTED_ROOT); -+ - return new AndroidCertVerifyResult( - CertVerifyStatusAndroid.OK, isIssuedByKnownRoot, verifiedChain); - } --- diff --git a/build/cromite_patches/Add-Alt-D-hotkey-to-focus-address-bar.patch b/build/cromite_patches/Add-Alt-D-hotkey-to-focus-address-bar.patch deleted file mode 100644 index f857bb8b..00000000 --- a/build/cromite_patches/Add-Alt-D-hotkey-to-focus-address-bar.patch +++ /dev/null @@ -1,26 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Tue, 9 Mar 2021 19:43:00 +0100 -Subject: Add Alt+D hotkey to focus address bar - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../src/org/chromium/chrome/browser/KeyboardShortcuts.java | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/KeyboardShortcuts.java b/chrome/android/java/src/org/chromium/chrome/browser/KeyboardShortcuts.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/KeyboardShortcuts.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/KeyboardShortcuts.java -@@ -883,6 +883,12 @@ public class KeyboardShortcuts { - KeyEvent.KEYCODE_ESCAPE, - KeyEvent.META_CTRL_ON); - } -+ addShortcut(context, -+ shortcutGroupsById, -+ R.string.keyboard_shortcut_chrome_feature_group_header, -+ R.string.keyboard_shortcut_address_bar, -+ KeyEvent.KEYCODE_D, -+ KeyEvent.META_ALT_ON); - return new ArrayList<>(shortcutGroupsById.values()); - } - --- diff --git a/build/cromite_patches/Add-IsCleartextPermitted-flag.patch b/build/cromite_patches/Add-IsCleartextPermitted-flag.patch deleted file mode 100644 index 090c933f..00000000 --- a/build/cromite_patches/Add-IsCleartextPermitted-flag.patch +++ /dev/null @@ -1,59 +0,0 @@ -From: uazo -Date: Mon, 26 Apr 2021 15:04:11 +0000 -Subject: Add IsCleartextPermitted flag - -Original License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../about_flags_cc/Add-IsCleartextPermitted-flag.inc | 8 ++++++++ - .../base/features_cc/Add-IsCleartextPermitted-flag.inc | 3 +++ - .../net/base/features_h/Add-IsCleartextPermitted-flag.inc | 1 + - net/url_request/url_request_http_job.cc | 5 +++++ - 4 files changed, 17 insertions(+) - create mode 100644 cromite_flags/chrome/browser/about_flags_cc/Add-IsCleartextPermitted-flag.inc - create mode 100644 cromite_flags/net/base/features_cc/Add-IsCleartextPermitted-flag.inc - create mode 100644 cromite_flags/net/base/features_h/Add-IsCleartextPermitted-flag.inc - -diff --git a/cromite_flags/chrome/browser/about_flags_cc/Add-IsCleartextPermitted-flag.inc b/cromite_flags/chrome/browser/about_flags_cc/Add-IsCleartextPermitted-flag.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/chrome/browser/about_flags_cc/Add-IsCleartextPermitted-flag.inc -@@ -0,0 +1,8 @@ -+#ifdef FLAG_SECTION -+ -+ {"cleartext-permitted", -+ "Allow cleartext traffic", -+ "Allow insecure connections over HTTP", kOsAll, -+ FEATURE_VALUE_TYPE(net::features::kIsCleartextPermitted)}, -+ -+#endif -diff --git a/cromite_flags/net/base/features_cc/Add-IsCleartextPermitted-flag.inc b/cromite_flags/net/base/features_cc/Add-IsCleartextPermitted-flag.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/net/base/features_cc/Add-IsCleartextPermitted-flag.inc -@@ -0,0 +1,3 @@ -+CROMITE_FEATURE(kIsCleartextPermitted, -+ "IsCleartextPermitted", -+ base::FEATURE_ENABLED_BY_DEFAULT); -diff --git a/cromite_flags/net/base/features_h/Add-IsCleartextPermitted-flag.inc b/cromite_flags/net/base/features_h/Add-IsCleartextPermitted-flag.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/net/base/features_h/Add-IsCleartextPermitted-flag.inc -@@ -0,0 +1 @@ -+NET_EXPORT BASE_DECLARE_FEATURE(kIsCleartextPermitted); -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 -@@ -413,6 +413,11 @@ std::unique_ptr URLRequestHttpJob::Create(URLRequest* request) { - } - } - -+ if (base::FeatureList::IsEnabled(net::features::kIsCleartextPermitted) == false) { -+ return std::make_unique(request, -+ ERR_CLEARTEXT_NOT_PERMITTED); -+ } -+ - #if BUILDFLAG(IS_ANDROID) - // Check whether the app allows cleartext traffic to this host, and return - // ERR_CLEARTEXT_NOT_PERMITTED if not. --- diff --git a/build/cromite_patches/Add-a-proxy-configuration-page.patch b/build/cromite_patches/Add-a-proxy-configuration-page.patch deleted file mode 100644 index 9d89df06..00000000 --- a/build/cromite_patches/Add-a-proxy-configuration-page.patch +++ /dev/null @@ -1,1433 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Thu, 29 Mar 2018 00:43:32 +0200 -Subject: Add a proxy configuration page - -Accessible from proxy settings and chrome://proxy -Allows to use a PAC script URL, automatic configuration and explicit proxy settings. -Offer auto-complete for the proxy page URL. -Store proxy settings in LocalState instead of Profile, so that proxy is used for SimpleURLLoaders as well; -this implementation is the same as the one in ChromeOS which gets proxy information from the LocalState -for the system network context; this is strictly not correct on Android because the network context is -never connected to any user profile and only gets proxy information from the system. -Existing settings on Profile are migrated to LocalState on startup. - -Credits to @uazo for the LocalState integration. - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - chrome/android/java/res/values/values.xml | 3 + - .../java/res/xml/privacy_preferences.xml | 4 + - .../privacy/settings/PrivacySettings.java | 1 + - .../chrome_autocomplete_provider_client.cc | 1 + - chrome/browser/browser_resources.grd | 3 + - .../extensions/api/proxy/proxy_api_helpers.cc | 2 +- - chrome/browser/net/proxy_service_factory.cc | 24 +- - chrome/browser/net/proxy_service_factory.h | 3 + - chrome/browser/prefs/browser_prefs.cc | 4 + - .../prefs/chrome_command_line_pref_store.cc | 2 +- - chrome/browser/resources/proxy_config.css | 61 +++ - chrome/browser/resources/proxy_config.html | 77 ++++ - chrome/browser/resources/proxy_config.js | 278 +++++++++++++ - chrome/browser/ui/BUILD.gn | 2 + - .../browser/ui/webui/chrome_web_ui_configs.cc | 5 +- - chrome/browser/ui/webui/proxy_config_ui.cc | 389 ++++++++++++++++++ - chrome/browser/ui/webui/proxy_config_ui.h | 41 ++ - chrome/common/webui_url_constants.cc | 2 + - chrome/common/webui_url_constants.h | 2 + - .../pref_proxy_config_tracker_impl.cc | 5 +- - .../proxy_config/proxy_config_dictionary.cc | 30 +- - .../proxy_config/proxy_config_dictionary.h | 7 +- - .../proxy_config/proxy_policy_handler.cc | 2 +- - net/proxy_resolution/pac_file_fetcher_impl.cc | 8 - - net/proxy_resolution/proxy_config.cc | 53 ++- - net/proxy_resolution/proxy_config.h | 3 + - 26 files changed, 986 insertions(+), 26 deletions(-) - create mode 100644 chrome/browser/resources/proxy_config.css - create mode 100644 chrome/browser/resources/proxy_config.html - create mode 100644 chrome/browser/resources/proxy_config.js - create mode 100644 chrome/browser/ui/webui/proxy_config_ui.cc - create mode 100644 chrome/browser/ui/webui/proxy_config_ui.h - -diff --git a/chrome/android/java/res/values/values.xml b/chrome/android/java/res/values/values.xml ---- a/chrome/android/java/res/values/values.xml -+++ b/chrome/android/java/res/values/values.xml -@@ -22,6 +22,9 @@ found in the LICENSE file. - - true - -+ Proxy configuration -+ chrome://proxy -+ - - 1200 - 200 -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 -@@ -10,6 +10,10 @@ found in the LICENSE file. - -+ - - - -+ -+ -+ - - - -diff --git a/chrome/browser/extensions/api/proxy/proxy_api_helpers.cc b/chrome/browser/extensions/api/proxy/proxy_api_helpers.cc ---- a/chrome/browser/extensions/api/proxy/proxy_api_helpers.cc -+++ b/chrome/browser/extensions/api/proxy/proxy_api_helpers.cc -@@ -375,7 +375,7 @@ std::optional CreateProxyConfigDict( - return std::nullopt; - } - return ProxyConfigDictionary::CreateFixedServers(proxy_rules_string, -- bypass_list); -+ bypass_list, /*reverse_bypass*/false); - } - case ProxyPrefs::MODE_SYSTEM: - return ProxyConfigDictionary::CreateSystem(); -diff --git a/chrome/browser/net/proxy_service_factory.cc b/chrome/browser/net/proxy_service_factory.cc ---- a/chrome/browser/net/proxy_service_factory.cc -+++ b/chrome/browser/net/proxy_service_factory.cc -@@ -6,6 +6,7 @@ - - #include - -+#include "base/logging.h" - #include "base/task/single_thread_task_runner.h" - #include "build/build_config.h" - #include "build/chromeos_buildflags.h" -@@ -13,6 +14,9 @@ - #include "content/public/browser/browser_task_traits.h" - #include "content/public/browser/browser_thread.h" - #include "net/proxy_resolution/proxy_config_service.h" -+#include "components/proxy_config/proxy_config_pref_names.h" -+#include "components/prefs/pref_service.h" -+#include "components/prefs/pref_registry_simple.h" - - #if BUILDFLAG(IS_CHROMEOS) - #include "chromeos/ash/components/network/proxy/proxy_config_service_impl.h" -@@ -57,7 +61,20 @@ ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile( - return std::make_unique( - profile_prefs, local_state_prefs, nullptr); - #else -- return std::make_unique(profile_prefs, nullptr); -+ // Migrate from profile_prefs to local_state_prefs -+ if (local_state_prefs->GetBoolean("proxy_migrated") == false) { -+ const base::Value::Dict& dict = -+ profile_prefs->GetDict(proxy_config::prefs::kProxy); -+ -+ LOG(INFO) << "CreatePrefProxyConfigTrackerOfProfile: Migration from profile to local state"; -+ -+ const base::Value /*ProxyConfigDictionary*/ proxy_dict(dict.Clone()); -+ local_state_prefs->Set(proxy_config::prefs::kProxy, proxy_dict); -+ -+ local_state_prefs->SetBoolean("proxy_migrated", true); -+ local_state_prefs->CommitPendingWrite(); -+ } -+ return std::make_unique(local_state_prefs, nullptr); - #endif // BUILDFLAG(IS_CHROMEOS) - } - -@@ -73,3 +90,8 @@ ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState( - nullptr); - #endif // BUILDFLAG(IS_CHROMEOS) - } -+ -+// static -+void ProxyServiceFactory::RegisterPrefs(PrefRegistrySimple* registry) { -+ registry->RegisterBooleanPref("proxy_migrated", false); -+} -diff --git a/chrome/browser/net/proxy_service_factory.h b/chrome/browser/net/proxy_service_factory.h ---- a/chrome/browser/net/proxy_service_factory.h -+++ b/chrome/browser/net/proxy_service_factory.h -@@ -6,6 +6,7 @@ - #define CHROME_BROWSER_NET_PROXY_SERVICE_FACTORY_H_ - - #include -+#include "components/prefs/pref_registry_simple.h" - - class PrefProxyConfigTracker; - class PrefService; -@@ -35,6 +36,8 @@ class ProxyServiceFactory { - CreatePrefProxyConfigTrackerOfProfile(PrefService* profile_prefs, - PrefService* local_state_prefs); - -+ static void RegisterPrefs(PrefRegistrySimple* registry); -+ - // 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 -@@ -207,6 +207,8 @@ - #include "printing/buildflags/buildflags.h" - #include "rlz/buildflags/buildflags.h" - -+#include "chrome/browser/net/proxy_service_factory.h" -+ - #if BUILDFLAG(ENABLE_BACKGROUND_MODE) - #include "chrome/browser/background/extensions/background_mode_manager.h" - #endif -@@ -1749,6 +1751,8 @@ void RegisterLocalState(PrefRegistrySimple* registry) { - component_updater::RegisterPrefs(registry); - domain_reliability::RegisterPrefs(registry); - embedder_support::OriginTrialPrefs::RegisterPrefs(registry); -+ ProxyServiceFactory::RegisterPrefs(registry); -+ - enterprise_reporting::RegisterLocalStatePrefs(registry); - ExternalProtocolHandler::RegisterPrefs(registry); - flags_ui::PrefServiceFlagsStorage::RegisterPrefs(registry); -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 -@@ -163,7 +163,7 @@ void ChromeCommandLinePrefStore::ApplyProxyMode() { - command_line()->GetSwitchValueASCII(switches::kProxyBypassList); - SetValue(proxy_config::prefs::kProxy, - base::Value(ProxyConfigDictionary::CreateFixedServers( -- proxy_server, bypass_list)), -+ proxy_server, bypass_list, false)), - WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); - } - } -diff --git a/chrome/browser/resources/proxy_config.css b/chrome/browser/resources/proxy_config.css -new file mode 100644 ---- /dev/null -+++ b/chrome/browser/resources/proxy_config.css -@@ -0,0 +1,61 @@ -+/* Copyright (c) 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. -+ */ -+ -+body { -+ font-size: 80%; -+ margin: 1em; -+} -+ -+#main-container { -+ max-width: 60em; -+ margin-left: auto; -+ margin-right: auto; -+} -+ -+button { -+ display: block; -+ font-size: 110%; -+ font-weight: bold; -+ margin: 10px auto; -+ padding: 1em; -+ width: 15em; -+} -+ -+h2 { -+ color: #546E7A; -+ font-weight: normal; -+ font-size: 170%; -+ margin-bottom: 1.5em; -+} -+ -+.radio-button-div { -+ margin: 7px auto; -+} -+ -+.warning { -+ color: red; -+ font-size: 90%; -+} -+ -+.section-container { -+ margin-top: 2em; -+} -+ -+#file-path-logging, -+#file-path-stopped { -+ font-family: monospace; -+} -+ -+.outline-box { -+ margin-top: 2em; -+ border: 1px solid #ababab; -+ padding: 0.5em; -+ line-height: 1.5em; -+} -+ -+textarea { -+ width: 95%; -+ height: 4em; -+} -diff --git a/chrome/browser/resources/proxy_config.html b/chrome/browser/resources/proxy_config.html -new file mode 100644 ---- /dev/null -+++ b/chrome/browser/resources/proxy_config.html -@@ -0,0 +1,77 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+Proxy configuration -+ -+ -+
-+ -+
-+

Proxy configuration

-+ Loading... -+
-+ -+ -+ -+ -+
-+ -+ -diff --git a/chrome/browser/resources/proxy_config.js b/chrome/browser/resources/proxy_config.js -new file mode 100644 ---- /dev/null -+++ b/chrome/browser/resources/proxy_config.js -@@ -0,0 +1,278 @@ -+/* -+ 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 . -+*/ -+ -+import {$} from 'chrome://resources/js/util.js'; -+ -+/** -+ * Main entry point called once the page has loaded. -+ */ -+function onLoad() { -+ ProxyConfigView.getInstance(); -+} -+ -+document.addEventListener('DOMContentLoaded', onLoad); -+ -+/** -+ * This class handles the presentation of the proxy-config view. Used as a -+ * singleton. -+ */ -+var ProxyConfigView = (function() { -+ 'use strict'; -+ -+ // -------------------------------------------------------------------------- -+ -+ var kIdStateDivUninitialized = 'state-pending'; -+ var kIdStateDivMain = 'state-main'; -+ var kIdApplyButton = 'apply'; -+ var kIdResetButton = 'reset'; -+ var kIdClearButton = 'clear'; -+ -+ var kIdModeEmpty = 'empty'; -+ var kIdModeDirect = 'direct'; -+ var kIdModeAutoDetect = 'auto-detect'; -+ var kIdModeUsePacURL = 'use-pac-url'; -+ -+ var kIdModeUseSingleList = 'use-single-list'; -+ var kIdModeUseListPerScheme = 'use-list-per-scheme'; -+ -+ var kIdPacURL = 'pac-url'; -+ var kIdPacMandatory = 'pac-mandatory'; -+ var kIdBypassRules = 'bypass-rules'; -+ var kIdReverseBypass = 'reverse-bypass'; -+ var kIdSingleProxies = 'single-proxies'; -+ var kIdHttpProxies = 'http-proxies'; -+ var kIdHttpsProxies = 'https-proxies'; -+ var kIdFtpProxies = 'ftp-proxies'; -+ var kIdFallbackProxies = 'fallback-proxies'; -+ -+ /** -+ * Adds a {@code getInstance} static method that always return the same -+ * instance object. -+ * @param {!Function} ctor The constructor for the class to add the static -+ * method to. -+ */ -+ function addSingletonGetter(ctor) { -+ ctor.getInstance = function() { -+ return ctor.instance_ || (ctor.instance_ = new ctor()); -+ }; -+ } -+ -+ /** -+ * @constructor -+ */ -+ function ProxyConfigView() { -+ this.currentConfig = null; -+ -+ $(kIdResetButton).onclick = this.onReset_.bind(this); -+ $(kIdApplyButton).onclick = this.onApply_.bind(this); -+ $(kIdClearButton).onclick = this.onClear_.bind(this); -+ -+ // Tell ProxyConfigMessageHandler to notify the UI of future state changes -+ // from this point on. -+ chrome.send('enableNotifyUIWithState'); -+ } -+ -+ addSingletonGetter(ProxyConfigView); -+ window.ProxyConfigView = ProxyConfigView; -+ -+ ProxyConfigView.prototype = { -+ /** -+ * Updates the UI to reflect the current state. The state transitions are -+ * sent by the browser controller (ProxyConfigMessageHandler): -+ * -+ * * PENDING - This is the initial state when proxy configuration is opened -+ * for the first time, or there was an error during initialization. -+ * This state is short-lived and likely not observed; will -+ * immediately transition to AVAILABLE). -+ * -+ * * AVAILABLE - The reported proxy configuration is active; this state is entered -+ * on first page load (or right after PENDING if configuration was not -+ * available on page load) and every time some configuration change was applied. -+ * It can transition to either AVAILABLE or UNSET. -+ * -+ * * UNSET - Proxy configuration is reported to be currently not set. -+ * -+ */ -+ onProxyConfigChanged: function(state) { -+ // may happen only on first load; leave the loading page as another update is expected -+ // when proxy configuration has finished loading -+ if (state.pending) { -+ $(kIdStateDivMain).hidden = true; -+ $(kIdStateDivUninitialized).hidden = false; -+ return; -+ } -+ -+ if (!state.hasOwnProperty('config')) { -+ // configuration has been unset, use an empty one -+ this.eraseCurrentConfig_(); -+ } else { -+ // save the configuration as current and reset all controls to it -+ this.currentConfig = state.config; -+ } -+ -+ this.renderConfig_(); -+ -+ this.toggleButtons_(false); -+ $(kIdStateDivUninitialized).hidden = true; -+ $(kIdStateDivMain).hidden = false; -+ }, -+ -+ /** -+ * Set current configuration to an empty (default) one. -+ */ -+ eraseCurrentConfig_: function() { -+ this.currentConfig = { -+ "auto_detect": false, -+ "pending": false, -+ "rules": { -+ "bypass_rules": "", -+ "reverse_bypass": false, -+ "type": "none" -+ } -+ }; -+ }, -+ -+ /** -+ * Serialize the user-selected configuration in an object. -+ */ -+ serializeConfig_: function() { -+ if ($(kIdModeEmpty).checked) { -+ return { -+ "auto_detect": false, -+ "rules": { -+ "type": "none" -+ } -+ }; -+ } else if ($(kIdModeDirect).checked) { -+ return { -+ "auto_detect": false, -+ "rules": { -+ "type": "direct" -+ } -+ }; -+ } else if ($(kIdModeAutoDetect).checked) { -+ return { -+ "auto_detect": true -+ }; -+ } else if ($(kIdModeUsePacURL).checked) { -+ return { -+ "auto_detect": false, -+ "pac_url": $(kIdPacURL).value.trim(), -+ "pac_mandatory": $(kIdPacMandatory).checked, -+ "rules": {} -+ }; -+ } else if ($(kIdModeUseListPerScheme).checked || $(kIdModeUseSingleList).checked) { -+ var config = { -+ "auto_detect": false, -+ "rules": { -+ "bypass_rules": $(kIdBypassRules).value.trim(), -+ "reverse_bypass": $(kIdReverseBypass).checked, -+ "type": "list" -+ } -+ }; -+ -+ if ($(kIdModeUseListPerScheme).checked) { -+ config.rules.type = "list_per_scheme"; -+ -+ config.rules.proxies_for_http = $(kIdHttpProxies).value.trim(); -+ config.rules.proxies_for_https = $(kIdHttpsProxies).value.trim(); -+ config.rules.proxies_for_ftp = $(kIdFtpProxies).value.trim(); -+ config.rules.fallback_proxies = $(kIdFallbackProxies).value.trim(); -+ } else { -+ config.rules.single_proxies = $(kIdSingleProxies).value.trim(); -+ } -+ -+ return config; -+ } -+ -+ throw new Error('unexpected mode'); -+ }, -+ -+ /** -+ * Updates the UI to display the current proxy configuration. -+ */ -+ renderConfig_: function() { -+ if (this.currentConfig.auto_detect) { -+ $(kIdModeAutoDetect).checked = true; -+ } else if (this.currentConfig.hasOwnProperty('pac_url')) { -+ $(kIdPacURL).value = this.currentConfig.pac_url; -+ $(kIdPacMandatory).checked = this.currentConfig.pac_mandatory; -+ $(kIdModeUsePacURL).checked = true; -+ } else if (this.currentConfig.rules.type == "none") { -+ $(kIdModeEmpty).checked = true; -+ } else if (this.currentConfig.rules.type == "direct") { -+ $(kIdModeDirect).checked = true; -+ } else { -+ $(kIdBypassRules).value = this.currentConfig.rules.bypass_rules; -+ $(kIdReverseBypass).checked = this.currentConfig.rules.reverse_bypass; -+ -+ switch (this.currentConfig.rules.type) { -+ case "list": -+ $(kIdModeUseSingleList).checked = true; -+ $(kIdSingleProxies).value = this.currentConfig.rules.single_proxies; -+ break; -+ case "list_per_scheme": -+ $(kIdModeUseListPerScheme).checked = true; -+ $(kIdHttpProxies).value = this.currentConfig.rules.proxies_for_http; -+ $(kIdHttpsProxies).value = this.currentConfig.rules.proxies_for_https; -+ $(kIdFtpProxies).value = this.currentConfig.rules.proxies_for_ftp; -+ $(kIdFallbackProxies).value = this.currentConfig.rules.fallback_proxies; -+ break; -+ } -+ } -+ }, -+ -+ /** -+ * Apply the configuration currently displayed. -+ */ -+ onApply_: function() { -+ var config = this.serializeConfig_(); -+ -+ // disable buttons; will be enabled back when UI receives a state update -+ this.toggleButtons_(true); -+ chrome.send('apply', [config]); -+ }, -+ -+ /** -+ * Apply the configuration currently displayed. -+ */ -+ onClear_: function() { -+ // disable buttons; will be enabled back when UI receives a state update -+ this.toggleButtons_(true); -+ this.eraseCurrentConfig_(); -+ chrome.send('clear', []); -+ }, -+ -+ /** -+ * Toggle the disabled status of the action buttons. -+ */ -+ toggleButtons_: function(disabled) { -+ $(kIdApplyButton).disabled = disabled; -+ $(kIdResetButton).disabled = disabled; -+ $(kIdClearButton).disabled = disabled; -+ }, -+ -+ /** -+ * Reset currently displayed configuration to the last known configuration in use. -+ */ -+ onReset_: function() { -+ this.renderConfig_(); -+ } -+ }; -+ -+ return ProxyConfigView; -+})(); -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 -@@ -158,6 +158,8 @@ static_library("ui") { - "webui/metrics_internals/metrics_internals_ui.h", - "webui/net_export_ui.cc", - "webui/net_export_ui.h", -+ "webui/proxy_config_ui.cc", -+ "webui/proxy_config_ui.h", - "webui/net_internals/net_internals_ui.cc", - "webui/net_internals/net_internals_ui.h", - "webui/ntp_tiles_internals_ui.cc", -diff --git a/chrome/browser/ui/webui/chrome_web_ui_configs.cc b/chrome/browser/ui/webui/chrome_web_ui_configs.cc ---- a/chrome/browser/ui/webui/chrome_web_ui_configs.cc -+++ b/chrome/browser/ui/webui/chrome_web_ui_configs.cc -@@ -58,6 +58,9 @@ - #include "extensions/buildflags/buildflags.h" - #include "printing/buildflags/buildflags.h" - -+#include "chrome/browser/ui/webui/proxy_config_ui.h" -+ -+ - #if BUILDFLAG(ENABLE_WEBUI_CERTIFICATE_VIEWER) - #include "chrome/browser/ui/webui/certificate_viewer/certificate_viewer_ui.h" - #endif -@@ -426,7 +429,7 @@ void RegisterChromeWebUIConfigs() { - map.AddWebUIConfig(std::make_unique()); - map.AddWebUIConfig(std::make_unique()); - #endif -- -+ map.AddWebUIConfig(std::make_unique()); - #if BUILDFLAG(SAFE_BROWSING_AVAILABLE) - map.AddWebUIConfig( - std::make_unique()); -diff --git a/chrome/browser/ui/webui/proxy_config_ui.cc b/chrome/browser/ui/webui/proxy_config_ui.cc -new file mode 100644 ---- /dev/null -+++ b/chrome/browser/ui/webui/proxy_config_ui.cc -@@ -0,0 +1,389 @@ -+/* -+ 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 . -+*/ -+ -+#include "chrome/browser/ui/webui/proxy_config_ui.h" -+ -+#include -+ -+#include -+#include -+#include -+ -+#include "base/command_line.h" -+#include "base/lazy_instance.h" -+#include "base/memory/ref_counted.h" -+#include "base/strings/string_util.h" -+#include "base/strings/utf_string_conversions.h" -+#include "base/values.h" -+#include "chrome/browser/browser_process.h" -+#include "chrome/browser/net/proxy_service_factory.h" -+#include "chrome/browser/platform_util.h" -+#include "chrome/browser/profiles/profile.h" -+#include "chrome/common/url_constants.h" -+#include "chrome/grit/browser_resources.h" -+#include "components/prefs/pref_service.h" -+#include "components/proxy_config/pref_proxy_config_tracker_impl.h" -+#include "components/proxy_config/proxy_config_pref_names.h" -+#include "components/grit/components_resources.h" -+#include "content/public/browser/browser_thread.h" -+#include "content/public/browser/url_data_source.h" -+#include "content/public/browser/web_contents.h" -+#include "content/public/browser/web_ui.h" -+#include "content/public/browser/web_ui_data_source.h" -+#include "content/public/browser/web_ui_message_handler.h" -+ -+#include "url/gurl.h" -+ -+using content::BrowserThread; -+using content::WebContents; -+using content::WebUIMessageHandler; -+ -+namespace { -+ -+// This class receives javascript messages from the renderer. -+// Note that the WebUI infrastructure runs on the UI thread, therefore all of -+// this class's public methods are expected to run on the UI thread. -+class ProxyConfigMessageHandler -+ : public WebUIMessageHandler, -+ public net::ProxyConfigService::Observer { -+ public: -+ ProxyConfigMessageHandler(const ProxyConfigMessageHandler&) = delete; -+ ProxyConfigMessageHandler& operator=(const ProxyConfigMessageHandler&) = delete; -+ // Creates a ProxyConfigMessageHandler that handles message exchanges with the Javascript -+ // side of the UI and gets proxy settings from the Web UI associated profile to watch for changes. -+ // The created ProxyConfigMessageHandler must be destroyed before |profile|. -+ ProxyConfigMessageHandler(Profile *profile); -+ ~ProxyConfigMessageHandler() override; -+ -+ // WebUIMessageHandler implementation. -+ void RegisterMessages() override; -+ -+ // Messages -+ void OnEnableNotifyUIWithState(const base::Value::List& args); -+ void OnApply(const base::Value::List& args); -+ void OnClear(const base::Value::List& args); -+ -+ // net::ProxyConfigService::Observer implementation: -+ // Calls ProxyConfigView.onProxyConfigChanged JavaScript function in the -+ // renderer. -+ void OnProxyConfigChanged( -+ const net::ProxyConfigWithAnnotation& config, -+ net::ProxyConfigService::ConfigAvailability availability) override; -+ -+ private: -+ // Not owned. -+ raw_ptr pref_service_; -+ std::unique_ptr proxy_config_service_; -+ // Monitors global and Profile prefs related to proxy configuration. -+ std::unique_ptr pref_proxy_config_tracker_; -+ bool is_observing_; -+ -+ void encodeConfig(const net::ProxyConfig& config, base::Value::Dict& state); -+ -+ void apply(const net::ProxyConfig& config); -+ -+ base::WeakPtrFactory weak_ptr_factory_{this}; -+}; -+ -+ProxyConfigMessageHandler::ProxyConfigMessageHandler(Profile *profile) { -+ -+ // used to set new configuration preferences -+ pref_service_ = g_browser_process->local_state(); -+ // observer is explicitly added only later in enableNotifyUIWithState -+ is_observing_ = false; -+ -+// If this is the ChromeOS sign-in profile, just create the tracker from global -+// state. -+#if defined(OS_CHROMEOS) -+ if (chromeos::ProfileHelper::IsSigninProfile(profile)) { -+ pref_proxy_config_tracker_.reset( -+ ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState( -+ g_browser_process->local_state())); -+ } -+#endif // defined(OS_CHROMEOS) -+ -+ if (!pref_proxy_config_tracker_) { -+ pref_proxy_config_tracker_ = -+ ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile( -+ profile->GetPrefs(), g_browser_process->local_state()); -+ } -+ -+ proxy_config_service_ = ProxyServiceFactory::CreateProxyConfigService( -+ pref_proxy_config_tracker_.get(), nullptr); -+} -+ -+void ProxyConfigMessageHandler::OnProxyConfigChanged( -+ const net::ProxyConfigWithAnnotation& config, -+ net::ProxyConfigService::ConfigAvailability availability) { -+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || -+ !BrowserThread::IsThreadInitialized(BrowserThread::UI)); -+ -+ base::Value::Dict state; -+ bool pending = false; -+ switch (availability) { -+ case net::ProxyConfigService::CONFIG_VALID: -+ encodeConfig(config.value(), state); -+ break; -+ case net::ProxyConfigService::CONFIG_UNSET: -+ state.SetByDottedPath("config.rules.type", base::Value("none")); -+ break; -+ case net::ProxyConfigService::CONFIG_PENDING: -+ //NOTE: this can only happen when triggered manually first time -+ pending = true; -+ break; -+ } -+ state.Set("pending", base::Value(pending)); -+ -+ // call Javascript function -+ web_ui()->CallJavascriptFunctionUnsafe("ProxyConfigView.getInstance().onProxyConfigChanged", -+ state.Clone()); -+} -+ -+const std::string omitDirect(const std::string pacString) { -+ if (pacString == "DIRECT") { -+ return ""; -+ } -+ return pacString; -+} -+ -+void ProxyConfigMessageHandler::encodeConfig(const net::ProxyConfig& config, base::Value::Dict& state) { -+ // when automatic settings are enabled they take precedence over manual settings -+ // automatic settings are either the "auto-detect" flag or the existance of a PAC URL -+ -+ state.SetByDottedPath("config.auto_detect", base::Value(config.auto_detect())); -+ -+ auto rules = config.proxy_rules(); -+ if (config.has_pac_url()) { -+ state.SetByDottedPath("config.pac_url", base::Value(config.pac_url().spec())); -+ state.SetByDottedPath("config.pac_mandatory", base::Value(config.pac_mandatory())); -+ state.SetByDottedPath("config.rules.type", base::Value("none")); -+ state.SetByDottedPath("config.rules.bypass_rules", base::Value(rules.bypass_rules.ToString())); -+ state.SetByDottedPath("config.rules.reverse_bypass", base::Value(rules.reverse_bypass)); -+ return; -+ } -+ -+ const char *type; -+ switch (rules.type) { -+ case net::ProxyConfig::ProxyRules::Type::EMPTY: -+ type = "direct"; -+ break; -+ case net::ProxyConfig::ProxyRules::Type::PROXY_LIST: -+ type = "list"; -+ -+ state.SetByDottedPath("config.rules.single_proxies", base::Value(omitDirect(rules.single_proxies.ToPacString()))); -+ break; -+ case net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME: -+ type = "list_per_scheme"; -+ -+ state.SetByDottedPath("config.rules.proxies_for_http", base::Value(omitDirect(rules.proxies_for_http.ToPacString()))); -+ state.SetByDottedPath("config.rules.proxies_for_https", base::Value(omitDirect(rules.proxies_for_https.ToPacString()))); -+ state.SetByDottedPath("config.rules.proxies_for_ftp", base::Value(omitDirect(rules.proxies_for_ftp.ToPacString()))); -+ state.SetByDottedPath("config.rules.fallback_proxies", base::Value(omitDirect(rules.fallback_proxies.ToPacString()))); -+ break; -+ default: -+ NOTREACHED(); -+ } -+ state.SetByDottedPath("config.rules.type", base::Value(type)); -+ state.SetByDottedPath("config.rules.bypass_rules", base::Value(rules.bypass_rules.ToString())); -+ state.SetByDottedPath("config.rules.reverse_bypass", base::Value(rules.reverse_bypass)); -+} -+ -+ProxyConfigMessageHandler::~ProxyConfigMessageHandler() { -+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || -+ !BrowserThread::IsThreadInitialized(BrowserThread::UI)); -+ if (is_observing_) { -+ proxy_config_service_->RemoveObserver(this); -+ } -+ pref_proxy_config_tracker_->DetachFromPrefService(); -+} -+ -+void ProxyConfigMessageHandler::RegisterMessages() { -+ DCHECK_CURRENTLY_ON(BrowserThread::UI); -+ -+ web_ui()->RegisterMessageCallback( -+ "enableNotifyUIWithState", -+ base::BindRepeating(&ProxyConfigMessageHandler::OnEnableNotifyUIWithState, -+ base::Unretained(this))); -+ web_ui()->RegisterMessageCallback( -+ "apply", -+ base::BindRepeating(&ProxyConfigMessageHandler::OnApply, -+ base::Unretained(this))); -+ web_ui()->RegisterMessageCallback( -+ "clear", -+ base::BindRepeating(&ProxyConfigMessageHandler::OnClear, -+ base::Unretained(this))); -+} -+ -+// The proxy configuration UI is not notified of state changes until this function runs. -+// After this function, OnProxyConfigChanged() will be called on all proxy state changes. -+void ProxyConfigMessageHandler::OnEnableNotifyUIWithState( -+ const base::Value::List& list) { -+ DCHECK_CURRENTLY_ON(BrowserThread::UI); -+ -+ if (!is_observing_) { -+ is_observing_ = true; -+ proxy_config_service_->AddObserver(this); -+ } -+ -+ net::ProxyConfigWithAnnotation config; -+ auto availability = proxy_config_service_->GetLatestProxyConfig(&config); -+ -+ const PrefService::Preference* const pref = -+ pref_service_->FindPreference(proxy_config::prefs::kProxy); -+ ProxyConfigDictionary proxy_dict(pref->GetValue()->GetDict().Clone()); -+ ProxyPrefs::ProxyMode mode; -+ if (!proxy_dict.GetMode(&mode) || mode == ProxyPrefs::MODE_SYSTEM) { -+ availability = net::ProxyConfigService::CONFIG_UNSET; -+ } -+ -+ OnProxyConfigChanged(config, availability); -+} -+ -+void ProxyConfigMessageHandler::OnClear(const base::Value::List& list) { -+ DCHECK_CURRENTLY_ON(BrowserThread::UI); -+ -+ const base::Value::Dict cfg = ProxyConfigDictionary::CreateSystem(); -+ pref_service_->SetDict(proxy_config::prefs::kProxy, cfg.Clone()); -+ pref_service_->CommitPendingWrite(); -+ OnEnableNotifyUIWithState(list); -+} -+ -+void ProxyConfigMessageHandler::OnApply(const base::Value::List& list) { -+ DCHECK_CURRENTLY_ON(BrowserThread::UI); -+ -+ if ((list.size() != 1) || !list[0].is_dict()) { -+ return; -+ } -+ -+ const base::Value::Dict& config = list[0].GetDict(); -+ -+ if (config.FindBool("auto_detect").value_or(false)) { -+ apply(net::ProxyConfig::CreateAutoDetect()); -+ return; -+ } -+ -+ if (const std::string* pacURL = config.FindString("pac_url")) { -+ std::optional pacMandatory = config.FindBool("pac_mandatory"); -+ auto proxyConfig = net::ProxyConfig::CreateFromCustomPacURL( -+ GURL(*pacURL)); -+ proxyConfig.set_pac_mandatory(pacMandatory.value_or(false)); -+ apply(proxyConfig); -+ return; -+ } -+ -+ const base::Value::Dict* rules = config.FindDict("rules"); -+ if (rules == nullptr) -+ return; -+ -+ net::ProxyConfig proxyConfig; -+ bool readBypass = false; -+ -+ const std::string* type = rules->FindString("type"); -+ if (type == nullptr) -+ return; -+ -+ if (*type == "list") { -+ const std::string* single_proxies = rules->FindString("single_proxies"); -+ if (single_proxies == nullptr) -+ return; -+ proxyConfig.proxy_rules().type = net::ProxyConfig::ProxyRules::Type::PROXY_LIST; -+ proxyConfig.proxy_rules().single_proxies.SetFromPacString(*single_proxies); -+ readBypass = true; -+ } else if (*type == "list_per_scheme") { -+ const std::string* http = rules->FindString("proxies_for_http"); -+ const std::string* https = rules->FindString("proxies_for_https"); -+ const std::string* ftp = rules->FindString("proxies_for_ftp"); -+ const std::string* fallback = rules->FindString("fallback_proxies"); -+ -+ proxyConfig.proxy_rules().type = net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME; -+ if (http) -+ proxyConfig.proxy_rules().proxies_for_http.SetFromPacString(*http); -+ if (https) -+ proxyConfig.proxy_rules().proxies_for_https.SetFromPacString(*https); -+ if (ftp) -+ proxyConfig.proxy_rules().proxies_for_ftp.SetFromPacString(*ftp); -+ if (fallback) -+ proxyConfig.proxy_rules().fallback_proxies.SetFromPacString(*fallback); -+ readBypass = true; -+ } else if (*type == "direct") { -+ proxyConfig.proxy_rules().type = net::ProxyConfig::ProxyRules::Type::EMPTY; -+ } else if (*type == "none") { -+ base::Value::List empty; -+ OnClear(empty); -+ return; -+ } else { -+ // invalid type -+ LOG(WARNING) << "invalid proxy configuration type"; -+ return; -+ } -+ -+ // bypass rules and reverse flag are common to both list types of proxy rules -+ if (readBypass) { -+ const std::string* bypass_rules = rules->FindString("bypass_rules"); -+ if (bypass_rules == nullptr) -+ return; -+ -+ std::optional reverse_bypass = rules->FindBool("reverse_bypass"); -+ -+ proxyConfig.proxy_rules().bypass_rules.ParseFromString(*bypass_rules); -+ proxyConfig.proxy_rules().reverse_bypass = reverse_bypass.value_or(false); -+ } -+ -+ apply(proxyConfig); -+} -+ -+void ProxyConfigMessageHandler::apply(const net::ProxyConfig& proxyConfig) { -+ if (proxyConfig.auto_detect()) { -+ const base::Value::Dict cfg = ProxyConfigDictionary::CreateAutoDetect(); -+ pref_service_->SetDict(proxy_config::prefs::kProxy, cfg.Clone()); -+ } else if (proxyConfig.has_pac_url()) { -+ const base::Value::Dict cfg = ProxyConfigDictionary::CreatePacScript(proxyConfig.pac_url().spec(), proxyConfig.pac_mandatory()); -+ pref_service_->SetDict(proxy_config::prefs::kProxy, cfg.Clone()); -+ } else if (proxyConfig.proxy_rules().type == net::ProxyConfig::ProxyRules::Type::EMPTY) { -+ const base::Value::Dict cfg = ProxyConfigDictionary::CreateDirect(); -+ pref_service_->SetDict(proxy_config::prefs::kProxy, cfg.Clone()); -+ } else { -+ auto proxyRulesAsString = proxyConfig.proxy_rules().ToString(); -+ auto bypassRulesAsString = proxyConfig.proxy_rules().bypass_rules.ToString(); -+ -+ // fixed servers -+ const base::Value::Dict cfg = ProxyConfigDictionary::CreateFixedServers(proxyRulesAsString, -+ bypassRulesAsString, proxyConfig.proxy_rules().reverse_bypass); -+ pref_service_->SetDict(proxy_config::prefs::kProxy, cfg.Clone()); -+ } -+ pref_service_->CommitPendingWrite(); -+ -+ base::Value::List empty; -+ OnEnableNotifyUIWithState(empty); -+} -+ -+} // namespace -+ -+ProxyConfigUI::ProxyConfigUI(content::WebUI* web_ui) : WebUIController(web_ui) { -+ Profile* profile = Profile::FromWebUI(web_ui); -+ -+ web_ui->AddMessageHandler(std::make_unique(profile)); -+ -+ // Set up the chrome://proxy/ source. -+ content::WebUIDataSource* source = -+ content::WebUIDataSource::CreateAndAdd(web_ui->GetWebContents()->GetBrowserContext(), -+ chrome::kChromeUIProxyConfigHost); -+ -+ source->UseStringsJs(); -+ source->AddResourcePath("proxy_config.js", IDR_PROXY_CONFIG_JS); -+ source->SetDefaultResource(IDR_PROXY_CONFIG_HTML); -+} -diff --git a/chrome/browser/ui/webui/proxy_config_ui.h b/chrome/browser/ui/webui/proxy_config_ui.h -new file mode 100644 ---- /dev/null -+++ b/chrome/browser/ui/webui/proxy_config_ui.h -@@ -0,0 +1,41 @@ -+/* -+ 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 . -+*/ -+ -+#ifndef CHROME_BROWSER_UI_WEBUI_PROXY_CONFIG_UI_H_ -+#define CHROME_BROWSER_UI_WEBUI_PROXY_CONFIG_UI_H_ -+ -+#include "chrome/common/webui_url_constants.h" -+#include "content/public/browser/web_ui_controller.h" -+#include "content/public/browser/webui_config.h" -+ -+// The WebUI for chrome://proxy/. -+class ProxyConfigUI : public content::WebUIController { -+ public: -+ ProxyConfigUI(const ProxyConfigUI&) = delete; -+ ProxyConfigUI& operator=(const ProxyConfigUI&) = delete; -+ explicit ProxyConfigUI(content::WebUI* web_ui); -+}; -+ -+class ProxyConfigUIConfig -+ : public content::DefaultWebUIConfig { -+ public: -+ ProxyConfigUIConfig() -+ : DefaultWebUIConfig(content::kChromeUIScheme, -+ chrome::kChromeUIProxyConfigHost) {} -+}; -+ -+#endif // CHROME_BROWSER_UI_WEBUI_PROXY_CONFIG_UI_H_ -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 -@@ -53,6 +53,7 @@ bool IsSystemWebUIHost(std::string_view host) { - kChromeUILockScreenNetworkHost, - kChromeUILockScreenStartReauthHost, - kChromeUIMobileSetupHost, -+ kChromeUIProxyConfigHost, - kChromeUIMultiDeviceSetupHost, - kChromeUINetworkHost, - kChromeUINotificationTesterHost, -@@ -74,6 +75,7 @@ bool IsSystemWebUIHost(std::string_view host) { - // These hosts will also be suggested by BuiltinProvider. - base::span ChromeURLHosts() { - static constexpr auto kChromeURLHosts = std::to_array({ -+ kChromeUIProxyConfigHost, - kChromeUIAboutHost, - kChromeUIAccessibilityHost, - kChromeUIActorInternalsHost, -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 -@@ -190,6 +190,8 @@ inline constexpr char kChromeUINetInternalsHost[] = "net-internals"; - inline constexpr char kChromeUINetInternalsURL[] = "chrome://net-internals/"; - inline constexpr char kChromeUINewTabHost[] = "newtab"; - inline constexpr char kChromeUINewTabFooterHost[] = "newtab-footer"; -+inline constexpr char16_t kChromeUIProxyConfigURL16[] = u"chrome://proxy/"; -+inline constexpr char kChromeUIProxyConfigHost[] = "proxy"; - inline constexpr char kChromeUINewTabPageHost[] = "new-tab-page"; - inline constexpr char kChromeUINewTabPageThirdPartyHost[] = - "new-tab-page-third-party"; -diff --git a/components/proxy_config/pref_proxy_config_tracker_impl.cc b/components/proxy_config/pref_proxy_config_tracker_impl.cc ---- a/components/proxy_config/pref_proxy_config_tracker_impl.cc -+++ b/components/proxy_config/pref_proxy_config_tracker_impl.cc -@@ -253,14 +253,14 @@ PrefProxyConfigTrackerImpl::GetEffectiveProxyConfig( - // static - void PrefProxyConfigTrackerImpl::RegisterPrefs(PrefRegistrySimple* registry) { - registry->RegisterDictionaryPref(proxy_config::prefs::kProxy, -- ProxyConfigDictionary::CreateSystem()); -+ ProxyConfigDictionary::CreateDirect()); - } - - // static - void PrefProxyConfigTrackerImpl::RegisterProfilePrefs( - PrefRegistrySimple* registry) { - registry->RegisterDictionaryPref(proxy_config::prefs::kProxy, -- ProxyConfigDictionary::CreateSystem()); -+ ProxyConfigDictionary::CreateDirect()); - registry->RegisterBooleanPref(proxy_config::prefs::kUseSharedProxies, false); - } - -@@ -405,6 +405,7 @@ bool PrefProxyConfigTrackerImpl::PrefConfigToNetConfig( - if (proxy_dict.GetBypassList(&proxy_bypass)) { - proxy_config.proxy_rules().bypass_rules.ParseFromString(proxy_bypass); - } -+ proxy_config.proxy_rules().reverse_bypass = proxy_dict.HasReverseBypass(); - *config = net::ProxyConfigWithAnnotation( - proxy_config, kSettingsProxyConfigTrafficAnnotation); - return true; -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 -@@ -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"; -+// Boolean telling whether to reverse the meaning of the bypass list. -+const char kProxyReverseBypass[] = "reverse_bypass"; - - } // namespace - -@@ -76,6 +78,14 @@ bool ProxyConfigDictionary::HasBypassList() const { - return dict_.Find(kProxyBypassList); - } - -+bool ProxyConfigDictionary::HasReverseBypass() const { -+ const base::Value* value = dict_.Find(kProxyReverseBypass); -+ if (!value || !value->is_bool()) { -+ return false; -+ } -+ return value->GetBool(); -+} -+ - const base::Value::Dict& ProxyConfigDictionary::GetDictionary() const { - return dict_; - } -@@ -83,13 +93,13 @@ const base::Value::Dict& ProxyConfigDictionary::GetDictionary() const { - // static - base::Value::Dict ProxyConfigDictionary::CreateDirect() { - return CreateDictionary(ProxyPrefs::MODE_DIRECT, std::string(), false, -- std::string(), std::string()); -+ std::string(), std::string(), false); - } - - // static - base::Value::Dict ProxyConfigDictionary::CreateAutoDetect() { - return CreateDictionary(ProxyPrefs::MODE_AUTO_DETECT, std::string(), false, -- std::string(), std::string()); -+ std::string(), std::string(), false); - } - - // static -@@ -97,16 +107,17 @@ base::Value::Dict ProxyConfigDictionary::CreatePacScript( - const std::string& pac_url, - bool pac_mandatory) { - return CreateDictionary(ProxyPrefs::MODE_PAC_SCRIPT, pac_url, pac_mandatory, -- std::string(), std::string()); -+ std::string(), std::string(), false); - } - - // static - base::Value::Dict ProxyConfigDictionary::CreateFixedServers( - const std::string& proxy_server, -- const std::string& bypass_list) { -+ const std::string& bypass_list, -+ bool reverse_bypass) { - if (!proxy_server.empty()) { - return CreateDictionary(ProxyPrefs::MODE_FIXED_SERVERS, std::string(), -- false, proxy_server, bypass_list); -+ false, proxy_server, bypass_list, reverse_bypass); - } else { - return CreateDirect(); - } -@@ -115,7 +126,7 @@ base::Value::Dict ProxyConfigDictionary::CreateFixedServers( - // static - base::Value::Dict ProxyConfigDictionary::CreateSystem() { - return CreateDictionary(ProxyPrefs::MODE_SYSTEM, std::string(), false, -- std::string(), std::string()); -+ std::string(), std::string(), false); - } - - // static -@@ -124,7 +135,8 @@ base::Value::Dict ProxyConfigDictionary::CreateDictionary( - const std::string& pac_url, - bool pac_mandatory, - const std::string& proxy_server, -- const std::string& bypass_list) { -+ const std::string& bypass_list, -+ bool reverse_bypass) { - base::Value::Dict dict; - dict.Set(kProxyMode, base::Value(ProxyModeToString(mode))); - if (!pac_url.empty()) { -@@ -133,8 +145,10 @@ base::Value::Dict ProxyConfigDictionary::CreateDictionary( - } - if (!proxy_server.empty()) - dict.Set(kProxyServer, base::Value(proxy_server)); -- if (!bypass_list.empty()) -+ if (!bypass_list.empty()) { - dict.Set(kProxyBypassList, base::Value(bypass_list)); -+ dict.Set(kProxyReverseBypass, base::Value(reverse_bypass)); -+ } - return dict; - } - -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 -@@ -42,6 +42,7 @@ class PROXY_CONFIG_EXPORT ProxyConfigDictionary { - bool GetProxyServer(std::string* out) const; - bool GetBypassList(std::string* out) const; - bool HasBypassList() const; -+ bool HasReverseBypass() const; - - const base::Value::Dict& GetDictionary() const; - -@@ -50,7 +51,8 @@ class PROXY_CONFIG_EXPORT ProxyConfigDictionary { - static base::Value::Dict CreatePacScript(const std::string& pac_url, - bool pac_mandatory); - static base::Value::Dict CreateFixedServers(const std::string& proxy_server, -- const std::string& bypass_list); -+ const std::string& bypass_list, -+ bool reverse_bypass); - static base::Value::Dict CreateSystem(); - - // Encodes the proxy server as "=://". -@@ -66,7 +68,8 @@ class PROXY_CONFIG_EXPORT ProxyConfigDictionary { - const std::string& pac_url, - bool pac_mandatory, - const std::string& proxy_server, -- const std::string& bypass_list); -+ const std::string& bypass_list, -+ bool reverse_bypass); - - base::Value::Dict 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 -@@ -378,7 +378,7 @@ void ProxyPolicyHandler::ApplyPolicySettings(const PolicyMap& policies, - set_proxy_pref_value(ProxyConfigDictionary::CreateFixedServers( - server->GetString(), bypass_list && bypass_list->is_string() - ? bypass_list->GetString() -- : std::string())); -+ : std::string(), false)); - } - break; - } -diff --git a/net/proxy_resolution/pac_file_fetcher_impl.cc b/net/proxy_resolution/pac_file_fetcher_impl.cc ---- a/net/proxy_resolution/pac_file_fetcher_impl.cc -+++ b/net/proxy_resolution/pac_file_fetcher_impl.cc -@@ -359,14 +359,6 @@ bool PacFileFetcherImpl::ConsumeBytesRead(URLRequest* request, int num_bytes) { - return false; - } - -- // Enforce maximum size bound. -- if (num_bytes + bytes_read_so_far_.size() > -- static_cast(max_response_bytes_)) { -- result_code_ = ERR_FILE_TOO_BIG; -- request->Cancel(); -- return false; -- } -- - bytes_read_so_far_.append(buf_->data(), num_bytes); - return true; - } -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 -@@ -133,7 +133,7 @@ void ProxyConfig::ProxyRules::ParseFromString(std::string_view proxy_rules, - url_scheme, &single_proxies, ProxyServer::SCHEME_HTTP, - allow_bracketed_proxy_chains, is_quic_allowed); - type = Type::PROXY_LIST; -- return; -+ continue; - } - - // Trim whitespace off the url scheme. -@@ -164,6 +164,57 @@ void ProxyConfig::ProxyRules::ParseFromString(std::string_view proxy_rules, - } - } - -+std::string ProxyConfig::ProxyRules::ToString() const { -+ if (type == Type::PROXY_LIST) { -+ std::string proxy_list; -+ for (const auto& proxy_chain : single_proxies.AllChains()) { -+ if (proxy_chain.length()) { -+ net::ProxyServer proxy_server = proxy_chain.GetProxyServer(/*chain_index=*/0); -+ proxy_list += ProxyServerToProxyUri(proxy_server) + ";"; -+ } -+ } -+ // remove last semicolon -+ if (proxy_list.length() != 0 ) { -+ proxy_list.pop_back(); -+ } -+ return proxy_list; -+ } else if (type == Type::PROXY_LIST_PER_SCHEME) { -+ // start to build a per-scheme list -+ std::string list; -+ for (const auto& proxy_chain : proxies_for_http.AllChains()) { -+ if (proxy_chain.length()) { -+ net::ProxyServer proxy_server = proxy_chain.First(); -+ list += "http=" + ProxyServerToProxyUri(proxy_server) + ";"; -+ } -+ } -+ for (const auto& proxy_chain : proxies_for_https.AllChains()) { -+ if (proxy_chain.length()) { -+ net::ProxyServer proxy_server = proxy_chain.First(); -+ list += "https=" + ProxyServerToProxyUri(proxy_server) + ";"; -+ } -+ } -+ for (const auto& proxy_chain : proxies_for_ftp.AllChains()) { -+ if (proxy_chain.length()) { -+ net::ProxyServer proxy_server = proxy_chain.First(); -+ list += "ftp=" + ProxyServerToProxyUri(proxy_server) + ";"; -+ } -+ } -+ for (const auto& proxy_chain : fallback_proxies.AllChains()) { -+ if (proxy_chain.length()) { -+ net::ProxyServer proxy_server = proxy_chain.First(); -+ list += "socks=" + ProxyServerToProxyUri(proxy_server) + ";"; -+ } -+ } -+ if (list.length() != 0 ) { -+ // remove last semicolon -+ list.pop_back(); -+ } -+ return list; -+ } else { -+ return ""; -+ } -+} -+ - const ProxyList* ProxyConfig::ProxyRules::MapUrlSchemeToProxyList( - const std::string& url_scheme) const { - const ProxyList* proxy_server_list = -diff --git a/net/proxy_resolution/proxy_config.h b/net/proxy_resolution/proxy_config.h ---- a/net/proxy_resolution/proxy_config.h -+++ b/net/proxy_resolution/proxy_config.h -@@ -107,6 +107,9 @@ class NET_EXPORT ProxyConfig { - void ParseFromString(std::string_view proxy_rules, - bool allow_bracketed_proxy_chains = false, - bool is_quic_allowed = false); -+ // Returns the proxy rules in a format that can be parsed by ParseFromString; -+ // all information except bypass rules is used. -+ std::string ToString() const; - - // Returns one of {&proxies_for_http, &proxies_for_https, &proxies_for_ftp, - // &fallback_proxies}, or NULL if there is no proxy to use. --- diff --git a/build/cromite_patches/Add-an-always-incognito-mode.patch b/build/cromite_patches/Add-an-always-incognito-mode.patch deleted file mode 100644 index 71b68aa7..00000000 --- a/build/cromite_patches/Add-an-always-incognito-mode.patch +++ /dev/null @@ -1,2241 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Sat, 2 Oct 2021 13:20:36 +0200 -Subject: Add an always-incognito mode - -Add a preference that causes all new tabs and all clicked links to launch in incognito. -Make sure initial incognito status is correctly recognized. -Enable incognito custom tabs and fix crashes for incognito/custom tab intents -Use a native flag to correctly start new tabs on app startup - -Add history, recents, offlinepages and send to home screen support for always incognito. -History, recent tabs and offline pages require the INCOGNITO_TAB_HISTORY_ENABLED -flag turned on. -IncognitoPlaceholder is also deactivated, both in the phone and tablet version. -The relative tests are also present. - -based on the original work by Ryan Archer -Major contributions by uazo. -See also: https://github.com/bromite/bromite/pull/1427 - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - chrome/android/chrome_java_resources.gni | 1 + - chrome/android/chrome_java_sources.gni | 2 + - .../java/res/xml/incognito_preferences.xml | 37 ++++ - .../java/res/xml/privacy_preferences.xml | 5 + - .../AlwaysIncognitoLinkInterceptor.java | 54 ++++++ - .../chrome/browser/ChromeTabbedActivity.java | 25 ++- - .../chrome/browser/app/ChromeActivity.java | 4 + - .../AppMenuPropertiesDelegateImpl.java | 7 +- - .../ChromeContextMenuPopulator.java | 6 +- - .../CustomTabActivityLifecycleUmaTracker.java | 31 ---- - .../CustomTabAppMenuPropertiesDelegate.java | 4 + - .../CustomTabIntentDataProvider.java | 10 + - .../browser/download/DownloadUtils.java | 13 +- - .../history/HistoryContentManager.java | 9 +- - .../browser/history/HistoryManager.java | 27 ++- - .../chrome/browser/history/HistoryPage.java | 16 ++ - .../native_page/NativePageFactory.java | 4 +- - .../chrome/browser/ntp/RecentTabsManager.java | 28 ++- - .../privacy/settings/IncognitoSettings.java | 175 ++++++++++++++++++ - .../settings/FragmentDependencyProvider.java | 4 + - .../HistoricalTabModelObserver.java | 5 +- - .../tab/tab_restore/HistoricalTabSaver.java | 2 +- - .../tab_restore/HistoricalTabSaverImpl.java | 17 +- - .../TabbedAppMenuPropertiesDelegate.java | 4 +- - .../tabbed_mode/TabbedRootUiCoordinator.java | 4 +- - .../browser/tabmodel/ChromeTabCreator.java | 5 +- - .../tabmodel/TabModelSelectorImpl.java | 3 + - .../browser/tabmodel/TabPersistentStore.java | 9 + - .../browser/toolbar/ToolbarManager.java | 3 +- - .../webapps/WebappIntentDataProvider.java | 15 ++ - .../browser/android/historical_tab_saver.cc | 24 ++- - .../chrome_autocomplete_provider_client.cc | 9 + - .../chrome_autocomplete_provider_client.h | 1 + - .../remote_suggestions_service_factory.cc | 5 + - .../bookmarks/android/bookmark_bridge.cc | 7 + - .../host_content_settings_map_factory.cc | 22 ++- - chrome/browser/history/history_tab_helper.cc | 20 ++ - chrome/browser/history/history_tab_helper.h | 10 +- - .../android/offline_page_bridge.cc | 11 +- - .../android/offline_page_model_factory.cc | 20 +- - .../android/request_coordinator_factory.cc | 33 +++- - .../offline_page_model_factory.h | 1 + - .../offline_pages/recent_tab_helper.cc | 31 +++- - .../browser/offline_pages/recent_tab_helper.h | 5 + - .../request_coordinator_factory.h | 4 +- - chrome/browser/prefs/browser_prefs.cc | 5 + - chrome/browser/profiles/profile_selections.cc | 10 + - chrome/browser/profiles/profile_selections.h | 7 +- - .../browser/ui/android/native_page/BUILD.gn | 2 + - .../browser/ui/native_page/NativePage.java | 17 +- - .../browser/omnibox/LocationBarMediator.java | 8 + - .../strings/android_chrome_strings.grd | 25 +++ - .../browser/toolbar/LocationBarModel.java | 4 +- - chrome/browser/ui/messages/android/BUILD.gn | 1 + - .../snackbar/INeedSnackbarManager.java | 28 +++ - .../search_engine_tab_helper.cc | 6 + - chrome/common/pref_names.h | 6 + - .../browser/content_settings_pref_provider.cc | 6 +- - .../browser/content_settings_pref_provider.h | 2 + - .../core/browser/host_content_settings_map.cc | 4 +- - .../core/browser/host_content_settings_map.h | 3 + - .../browser/autocomplete_provider_client.cc | 4 + - .../browser/autocomplete_provider_client.h | 1 + - .../omnibox/browser/base_search_provider.cc | 2 +- - components/omnibox/browser/search_provider.cc | 3 +- - .../add-an-always-incognito-mode.inc | 13 ++ - .../add-an-always-incognito-mode.inc | 1 + - .../add-an-always-incognito-mode.inc | 3 + - .../add-an-always-incognito-mode.inc | 1 + - 69 files changed, 791 insertions(+), 103 deletions(-) - create mode 100644 chrome/android/java/res/xml/incognito_preferences.xml - create mode 100644 chrome/android/java/src/org/chromium/chrome/browser/AlwaysIncognitoLinkInterceptor.java - create mode 100644 chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/IncognitoSettings.java - create mode 100644 chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/INeedSnackbarManager.java - create mode 100644 cromite_flags/chrome/browser/about_flags_cc/add-an-always-incognito-mode.inc - create mode 100644 cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/add-an-always-incognito-mode.inc - create mode 100644 cromite_flags/components/offline_pages/core/offline_page_feature_cc/add-an-always-incognito-mode.inc - create mode 100644 cromite_flags/components/offline_pages/core/offline_page_feature_h/add-an-always-incognito-mode.inc - -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 -@@ -638,6 +638,7 @@ chrome_java_resources = [ - "java/res/xml/main_preferences.xml", - "java/res/xml/manage_sync_preferences.xml", - "java/res/xml/personalize_google_services_preferences.xml", -+ "java/res/xml/incognito_preferences.xml", - "java/res/xml/privacy_preferences.xml", - "java/res/xml/search_widget_info.xml", - "java/res/xml/tracing_preferences.xml", -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 -@@ -5,6 +5,7 @@ - import("//content/public/common/features.gni") - - chrome_java_sources = [ -+ "java/src/org/chromium/chrome/browser/AlwaysIncognitoLinkInterceptor.java", - "java/src/com/google/android/apps/chrome/appwidget/bookmarks/BookmarkThumbnailWidgetProvider.java", - "java/src/org/chromium/chrome/browser/ActivityTabProvider.java", - "java/src/org/chromium/chrome/browser/ActivityUtils.java", -@@ -925,6 +926,7 @@ chrome_java_sources = [ - "java/src/org/chromium/chrome/browser/privacy/settings/PasswordEchoSettingHandlerFactory.java", - "java/src/org/chromium/chrome/browser/privacy/settings/PrivacyPreferencesManagerImpl.java", - "java/src/org/chromium/chrome/browser/privacy/settings/PrivacySettings.java", -+ "java/src/org/chromium/chrome/browser/privacy/settings/IncognitoSettings.java", - "java/src/org/chromium/chrome/browser/privacy_sandbox/CctHandler.java", - "java/src/org/chromium/chrome/browser/privacy_sandbox/ChromeTrackingProtectionDelegate.java", - "java/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandbox3pcdRollbackMessageController.java", -diff --git a/chrome/android/java/res/xml/incognito_preferences.xml b/chrome/android/java/res/xml/incognito_preferences.xml -new file mode 100644 ---- /dev/null -+++ b/chrome/android/java/res/xml/incognito_preferences.xml -@@ -0,0 +1,37 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -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 -@@ -90,6 +90,11 @@ found in the LICENSE file. - android:key="secure_dns" - android:title="@string/settings_secure_dns_title" - android:fragment="org.chromium.chrome.browser.privacy.secure_dns.SecureDnsSettings" /> -+ - -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/AlwaysIncognitoLinkInterceptor.java b/chrome/android/java/src/org/chromium/chrome/browser/AlwaysIncognitoLinkInterceptor.java -new file mode 100644 ---- /dev/null -+++ b/chrome/android/java/src/org/chromium/chrome/browser/AlwaysIncognitoLinkInterceptor.java -@@ -0,0 +1,54 @@ -+/* This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+package org.chromium.chrome.browser; -+ -+import android.content.SharedPreferences; -+import org.chromium.base.ContextUtils; -+ -+import org.chromium.components.user_prefs.UserPrefs; -+import org.chromium.components.prefs.PrefService; -+import org.chromium.chrome.browser.profiles.Profile; -+import org.chromium.chrome.browser.profiles.ProfileManager; -+import org.chromium.chrome.browser.preferences.Pref; -+import org.chromium.base.Log; -+ -+import androidx.annotation.Nullable; -+ -+/** -+ * A {@link TabObserver} that implements the always-incognito preference behavior for links. -+ */ -+public class AlwaysIncognitoLinkInterceptor { -+ -+ private static final String TAG = "AlwaysIncognito"; -+ public static final String PREF_ALWAYS_INCOGNITO = "always_incognito"; -+ -+ private static @Nullable Boolean cachedIsAlwaysIncognito = null; -+ -+ public static boolean isAlwaysIncognito() { -+ if (cachedIsAlwaysIncognito != null) return cachedIsAlwaysIncognito; -+ cachedIsAlwaysIncognito = ContextUtils.getAppSharedPreferences() -+ .getBoolean(PREF_ALWAYS_INCOGNITO, false); -+ return cachedIsAlwaysIncognito; -+ } -+ -+ public static void setAlwaysIncognito(boolean enabled) { -+ UserPrefs.get(ProfileManager.getLastUsedRegularProfile()) -+ .setBoolean(Pref.ALWAYS_INCOGNITO_ENABLED, enabled); -+ -+ SharedPreferences.Editor sharedPreferenceEditor = ContextUtils.getAppSharedPreferences().edit(); -+ sharedPreferenceEditor.putBoolean("always_incognito", enabled); -+ sharedPreferenceEditor.apply(); -+ } -+ -+ public static void migrateSettingToNative() { -+ if (isAlwaysIncognito()) { -+ PrefService prefService = UserPrefs.get(ProfileManager.getLastUsedRegularProfile()); -+ if (!prefService.getBoolean(Pref.ALWAYS_INCOGNITO_ENABLED)) { -+ Log.i(TAG, "Pref migration from java to native"); -+ prefService.setBoolean(Pref.ALWAYS_INCOGNITO_ENABLED, true); -+ } -+ } -+ } -+} -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 -@@ -71,6 +71,10 @@ import org.chromium.build.annotations.Nullable; - import org.chromium.build.annotations.UsedByReflection; - import org.chromium.cc.input.BrowserControlsState; - import org.chromium.chrome.R; -+import org.chromium.components.prefs.PrefService; -+import org.chromium.components.user_prefs.UserPrefs; -+import org.chromium.chrome.browser.preferences.Pref; -+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; - import org.chromium.chrome.browser.IntentHandler.ExternalAppId; - import org.chromium.chrome.browser.IntentHandler.TabOpenType; - import org.chromium.chrome.browser.app.ChromeActivity; -@@ -837,15 +841,20 @@ public class ChromeTabbedActivity extends ChromeActivity { - } - - // For saving non-incognito tab closures for Recent Tabs. -- mHistoricalTabModelObserver = -- new HistoricalTabModelObserver( -- mTabModelSelector -+ boolean alwaysIncognito = AlwaysIncognitoLinkInterceptor.isAlwaysIncognito(); -+ PrefService prefService = UserPrefs.get(ProfileManager.getLastUsedRegularProfile()); -+ boolean historyEnabledInIncognito = -+ prefService.getBoolean(Pref.INCOGNITO_TAB_HISTORY_ENABLED); -+ if ((alwaysIncognito && historyEnabledInIncognito) || !alwaysIncognito) { -+ mHistoricalTabModelObserver = -+ new HistoricalTabModelObserver( -+ mTabModelSelector - .getTabGroupModelFilterProvider() -- .getTabGroupModelFilter(false)); -- mHistoricalTabModelObserver.addSecondaryTabModelSupplier( -- ArchivedTabModelOrchestrator.getForProfile(currentTabModel.getProfile()) -+ .getTabGroupModelFilter(alwaysIncognito)); -+ mHistoricalTabModelObserver.addSecondaryTabModelSupplier( -+ ArchivedTabModelOrchestrator.getForProfile(currentTabModel.getProfile()) - ::getTabModel); -- -+ } - // Defer creation of this helper so it triggers after TabGroupModelFilter observers. - mUndoRefocusHelper = - new UndoRefocusHelper( -@@ -3299,7 +3308,7 @@ public class ChromeTabbedActivity extends ChromeActivity { - - // We determine SupportedProfileType in onPreCreate(). - // We determine the model as soon as possible so every systems get initialized coherently. -- boolean startIncognito = -+ boolean startIncognito = AlwaysIncognitoLinkInterceptor.isAlwaysIncognito() || - (mSupportedProfileType == SupportedProfileType.OFF_THE_RECORD) - || (mSupportedProfileType == SupportedProfileType.MIXED - && savedInstanceState != null -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 -@@ -100,6 +100,7 @@ import org.chromium.chrome.browser.compositor.layouts.content.TabContentManagerH - import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager; - import org.chromium.chrome.browser.device.DeviceClassManager; - import org.chromium.chrome.browser.devtools.DevToolsWindowAndroid; -+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; - import org.chromium.chrome.browser.dom_distiller.DomDistillerUiUtils; - import org.chromium.chrome.browser.dom_distiller.ReaderModeManager; - import org.chromium.chrome.browser.download.DownloadManagerService; -@@ -2076,6 +2077,9 @@ public abstract class ChromeActivity extends AsyncInitializationActivity - throw new IllegalStateException( - "Attempting to access TabCreator before initialization"); - } -+ if (AlwaysIncognitoLinkInterceptor.isAlwaysIncognito()) { -+ incognito = true; -+ } - return mTabCreatorManagerSupplier.get().getTabCreator(incognito); - } - -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 -@@ -92,6 +92,8 @@ import java.util.Iterator; - import java.util.List; - import java.util.function.Supplier; - -+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; -+ - /** - * Base implementation of {@link AppMenuPropertiesDelegate} that handles hiding and showing menu - * items based on activity state. -@@ -635,8 +637,9 @@ public abstract class AppMenuPropertiesDelegateImpl implements AppMenuProperties - && !isNativePage - && !isFileScheme - && !isContentScheme -- && !isIncognito -- && !url.isEmpty(); -+ && !url.isEmpty() -+ && (!isIncognito || -+ AlwaysIncognitoLinkInterceptor.isAlwaysIncognito()); - } - - /** -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 -@@ -41,6 +41,7 @@ import org.chromium.base.shared_preferences.SharedPreferencesManager; - import org.chromium.build.annotations.NullMarked; - import org.chromium.build.annotations.Nullable; - import org.chromium.chrome.R; -+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; - import org.chromium.chrome.browser.bookmarks.BookmarkUtils; - import org.chromium.chrome.browser.contextmenu.ChromeContextMenuItem.Item; - import org.chromium.chrome.browser.contextmenu.ContextMenuCoordinator.ContextMenuItemType; -@@ -430,6 +431,9 @@ public class ChromeContextMenuPopulator implements ContextMenuPopulator { - mShowEphemeralTabNewLabel = null; - mCustomActionMap.clear(); - -+ boolean always_incognito = -+ AlwaysIncognitoLinkInterceptor.isAlwaysIncognito(); -+ - List groupedItems = new ArrayList<>(); - - if (mParams.isPage() && shouldShowEmptySpaceContextMenu()) { -@@ -501,7 +505,7 @@ public class ChromeContextMenuPopulator implements ContextMenuPopulator { - } - } - if (FirstRunStatus.getFirstRunFlowComplete()) { -- if (!mItemDelegate.isIncognito() -+ if ((always_incognito || !mItemDelegate.isIncognito()) - && UrlUtilities.isDownloadableScheme(mParams.getLinkUrl())) { - linkGroup.add( - createListItem( -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivityLifecycleUmaTracker.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivityLifecycleUmaTracker.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivityLifecycleUmaTracker.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivityLifecycleUmaTracker.java -@@ -68,37 +68,6 @@ public class CustomTabActivityLifecycleUmaTracker - private boolean mIsInitialResume = true; - - private void recordIncognitoLaunchReason() { -- // TODO(crbug.com/352525607): Separate Ephemeral and Incognito CCT metrics. -- @BrowserServicesIntentDataProvider.IncognitoCctCallerId -- int incognitoCctCallerId = mIntentDataProvider.getFeatureIdForMetricsCollection(); -- -- RecordHistogram.recordEnumeratedHistogram( -- "CustomTabs.IncognitoCctCallerId", -- incognitoCctCallerId, -- BrowserServicesIntentDataProvider.IncognitoCctCallerId.NUM_ENTRIES); -- -- // Record which 1P app launched Incognito CCT. -- if (incognitoCctCallerId -- == BrowserServicesIntentDataProvider.IncognitoCctCallerId.GOOGLE_APPS) { -- String sendersPackageName = mIntentDataProvider.getClientPackageName(); -- @IntentHandler.ExternalAppId -- int externalId = IntentHandler.mapPackageToExternalAppId(sendersPackageName); -- if (externalId != IntentHandler.ExternalAppId.OTHER) { -- RecordHistogram.recordEnumeratedHistogram( -- "CustomTabs.ClientAppId.Incognito", -- externalId, -- IntentHandler.ExternalAppId.NUM_ENTRIES); -- } else { -- // Using package name didn't give any meaningful insight on who launched the -- // Incognito CCT, falling back to check if they provided EXTRA_APPLICATION_ID. -- var intent = assertNonNull(mIntentDataProvider.getIntent()); -- externalId = IntentHandler.determineExternalIntentSource(intent, mActivity); -- RecordHistogram.recordEnumeratedHistogram( -- "CustomTabs.ClientAppId.Incognito", -- externalId, -- IntentHandler.ExternalAppId.NUM_ENTRIES); -- } -- } - } - - private void recordUserAction() { -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 -@@ -21,6 +21,7 @@ import org.chromium.build.annotations.NullMarked; - import org.chromium.build.annotations.Nullable; - import org.chromium.chrome.R; - import org.chromium.chrome.browser.ActivityTabProvider; -+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; - import org.chromium.chrome.browser.DefaultBrowserInfo; - import org.chromium.chrome.browser.app.appmenu.AppMenuPropertiesDelegateImpl; - import org.chromium.chrome.browser.bookmarks.BookmarkModel; -@@ -224,6 +225,9 @@ public class CustomTabAppMenuPropertiesDelegate extends AppMenuPropertiesDelegat - openInChromeItemVisible = false; - tryAddingReadAloud = false; - } -+ if (AlwaysIncognitoLinkInterceptor.isAlwaysIncognito()) { -+ downloadItemVisible = true; -+ } - - boolean isNativePage = - url.getScheme().equals(UrlConstants.CHROME_SCHEME) -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java -@@ -105,6 +105,9 @@ import org.chromium.components.embedder_support.util.UrlConstants; - import org.chromium.device.mojom.ScreenOrientationLockType; - import org.chromium.net.NetId; - -+import org.chromium.base.ContextUtils; -+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; -+ - import java.lang.annotation.Retention; - import java.lang.annotation.RetentionPolicy; - import java.util.ArrayList; -@@ -1287,6 +1290,13 @@ public class CustomTabIntentDataProvider extends BrowserServicesIntentDataProvid - return getInitialActivityWidth() > 0; - } - -+ @Override -+ public @CustomTabProfileType int getCustomTabMode() { -+ return AlwaysIncognitoLinkInterceptor.isAlwaysIncognito() -+ ? CustomTabProfileType.INCOGNITO -+ : CustomTabProfileType.REGULAR; -+ } -+ - @Override - public boolean isPartialCustomTab() { - return isPartialHeightCustomTab() || isPartialWidthCustomTab(); -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 -@@ -39,6 +39,7 @@ import org.chromium.base.Log; - import org.chromium.build.annotations.NullMarked; - import org.chromium.build.annotations.Nullable; - import org.chromium.chrome.R; -+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; - import org.chromium.chrome.browser.ChromeTabbedActivity; - import org.chromium.chrome.browser.IntentHandler; - import org.chromium.chrome.browser.app.download.home.DownloadActivityLauncher; -@@ -82,6 +83,10 @@ import org.chromium.url.GURL; - - import java.io.File; - -+import org.chromium.components.prefs.PrefService; -+import org.chromium.components.user_prefs.UserPrefs; -+import org.chromium.chrome.browser.preferences.Pref; -+ - /** A class containing some utility static methods. */ - @NullMarked - public class DownloadUtils { -@@ -292,7 +297,13 @@ public class DownloadUtils { - public static boolean isAllowedToDownloadPage(@Nullable Tab tab) { - if (tab == null) return false; - -- if (tab.isIncognito() -+ boolean historyEnabledInIncognito = false; -+ if (AlwaysIncognitoLinkInterceptor.isAlwaysIncognito()) { -+ PrefService prefService = UserPrefs.get(ProfileManager.getLastUsedRegularProfile()); -+ historyEnabledInIncognito = -+ prefService.getBoolean(Pref.INCOGNITO_TAB_HISTORY_ENABLED); -+ } -+ if (tab.isIncognito() && !historyEnabledInIncognito - && !ChromeFeatureList.isEnabled( - ChromeFeatureList.ENABLE_SAVE_PACKAGE_FOR_OFF_THE_RECORD)) { - return false; -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryContentManager.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryContentManager.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryContentManager.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryContentManager.java -@@ -308,8 +308,9 @@ public class HistoryContentManager implements SignInStateObserver, PrefObserver - mHistoryAdapter.generateFooterItems(); - - // Listen to changes in sign in state. -- assumeNonNull(IdentityServicesProvider.get().getSigninManager(profile)) -- .addSignInStateObserver(this); -+ // getSigninManager is null in incognito -+ if (IdentityServicesProvider.get().getSigninManager(profile) != null) -+ IdentityServicesProvider.get().getSigninManager(profile).addSignInStateObserver(this); - - // Create PrefChangeRegistrar to receive notifications on preference changes. - mPrefChangeRegistrar = PrefServiceUtil.createFor(profile); -@@ -386,8 +387,8 @@ public class HistoryContentManager implements SignInStateObserver, PrefObserver - mHistoryAdapter.onDestroyed(); - mLargeIconBridge.destroy(); - mLargeIconBridge = null; -- assumeNonNull(IdentityServicesProvider.get().getSigninManager(mProfile)) -- .removeSignInStateObserver(this); -+ if (IdentityServicesProvider.get().getSigninManager(mProfile) != null) -+ IdentityServicesProvider.get().getSigninManager(mProfile).removeSignInStateObserver(this); - mPrefChangeRegistrar.destroy(); - if (mHistorySyncPromoCoordinator != null) { - mHistorySyncPromoCoordinator.destroy(); -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 -@@ -61,6 +61,14 @@ import java.util.List; - import java.util.function.Function; - import java.util.function.Supplier; - -+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; -+import org.chromium.chrome.browser.profiles.Profile; -+import org.chromium.chrome.browser.profiles.ProfileManager; -+import org.chromium.base.ContextUtils; -+import org.chromium.components.prefs.PrefService; -+import org.chromium.components.user_prefs.UserPrefs; -+import org.chromium.chrome.browser.preferences.Pref; -+ - /** Combines and manages the different UI components of browsing history. */ - @NullMarked - public class HistoryManager -@@ -166,7 +174,7 @@ public class HistoryManager - - mUmaRecorder.recordOpenHistory(); - // If incognito placeholder is shown, we don't need to create History UI elements. -- if (mIsIncognito) { -+ if (shouldShowIncognitoPlaceholder()) { - mSelectableListLayout = null; - mRootView = getIncognitoHistoryPlaceholderView(); - return; -@@ -451,9 +459,22 @@ public class HistoryManager - onBackPressStateChanged(); - } - -+ public boolean isIncognito() { return mIsIncognito; } -+ -+ public boolean shouldShowIncognitoPlaceholder() { -+ if (mIsIncognito && -+ AlwaysIncognitoLinkInterceptor.isAlwaysIncognito()) { -+ PrefService prefService = UserPrefs.get(ProfileManager.getLastUsedRegularProfile()); -+ boolean historyEnabledInIncognito = -+ prefService.getBoolean(Pref.INCOGNITO_TAB_HISTORY_ENABLED); -+ if (historyEnabledInIncognito) return false; -+ } -+ return mIsIncognito; -+ } -+ - /** Called when the activity/native page is destroyed. */ - public void onDestroyed() { -- if (mIsIncognito) { -+ if (shouldShowIncognitoPlaceholder()) { - // If Incognito placeholder is shown no need to call any destroy method. - return; - } -@@ -514,7 +535,7 @@ public class HistoryManager - * @return True if manager handles this event, false if it decides to ignore. - */ - private boolean onBackPressed() { -- if (mIsIncognito || mSelectableListLayout == null) { -+ if (shouldShowIncognitoPlaceholder() || mSelectableListLayout == null) { - // If Incognito placeholder is shown, the back press should handled by HistoryActivity. - return false; - } -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 -@@ -20,6 +20,14 @@ import org.chromium.components.embedder_support.util.UrlConstants; - - import java.util.function.Supplier; - -+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; -+import org.chromium.chrome.browser.profiles.Profile; -+import org.chromium.chrome.browser.profiles.ProfileManager; -+import org.chromium.base.ContextUtils; -+import org.chromium.components.prefs.PrefService; -+import org.chromium.components.user_prefs.UserPrefs; -+import org.chromium.chrome.browser.preferences.Pref; -+ - /** Native page for managing browsing history. */ - @NullMarked - public class HistoryPage extends BasicNativePage { -@@ -49,6 +57,14 @@ public class HistoryPage extends BasicNativePage { - String url) { - super(host); - -+ if (profile.isOffTheRecord() && -+ AlwaysIncognitoLinkInterceptor.isAlwaysIncognito()) { -+ PrefService prefService = UserPrefs.get(ProfileManager.getLastUsedRegularProfile()); -+ boolean historyEnabledInIncognito = -+ prefService.getBoolean(Pref.INCOGNITO_TAB_HISTORY_ENABLED); -+ if (historyEnabledInIncognito == true) profile = profile.getOriginalProfile(); -+ } -+ - Uri uri = Uri.parse(url); - assert UrlConstants.HISTORY_HOST.equals(uri.getHost()); - -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java -@@ -25,6 +25,7 @@ import org.chromium.base.supplier.OneshotSupplier; - import org.chromium.build.annotations.NullMarked; - import org.chromium.build.annotations.Nullable; - import org.chromium.chrome.R; -+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; - import org.chromium.chrome.browser.app.ChromeActivity; - import org.chromium.chrome.browser.app.download.home.DownloadPage; - import org.chromium.chrome.browser.back_press.BackPressManager; -@@ -396,7 +397,8 @@ public class NativePageFactory { - - NativePage page; - -- switch (NativePage.nativePageType(gurl, candidatePage, isIncognito, pdfInfo != null)) { -+ boolean isAlwaysIncognito = AlwaysIncognitoLinkInterceptor.isAlwaysIncognito(); -+ switch (NativePage.nativePageType(gurl, candidatePage, isIncognito, pdfInfo != null, isAlwaysIncognito)) { - case NativePageType.NONE: - return null; - case NativePageType.CANDIDATE: -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 -@@ -44,6 +44,15 @@ import org.chromium.components.signin.metrics.SigninAccessPoint; - import org.chromium.components.sync.SyncService; - import org.chromium.url.GURL; - -+import android.content.Intent; -+import android.provider.Browser; -+import android.net.Uri; -+import org.chromium.base.ContextUtils; -+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; -+import org.chromium.chrome.browser.IntentHandler; -+import org.chromium.ui.mojom.WindowOpenDisposition; -+import org.chromium.components.embedder_support.util.UrlUtilities; -+ - import java.util.HashMap; - import java.util.List; - import java.util.Map; -@@ -113,7 +122,8 @@ public class RecentTabsManager - Profile profile, - Context context, - Runnable showHistoryManager) { -- mProfile = profile; -+ mProfile = profile.getOriginalProfile(); -+ profile = mProfile; - mActiveTab = tab; - mTabModelSelector = tabModelSelector; - mShowHistoryManager = showHistoryManager; -@@ -302,6 +312,22 @@ public class RecentTabsManager - */ - public void openRecentlyClosedTab(RecentlyClosedTab tab, int windowDisposition) { - if (mIsDestroyed) return; -+ if (AlwaysIncognitoLinkInterceptor.isAlwaysIncognito()) { -+ // allow only http/https urls -+ if (!UrlUtilities.isHttpOrHttps(tab.getUrl())) return; -+ -+ Context context = ContextUtils.getApplicationContext(); -+ Intent intent = new Intent(Intent.ACTION_VIEW, -+ Uri.parse(tab.getUrl().getSpec())); -+ intent.putExtra(Browser.EXTRA_APPLICATION_ID, context.getPackageName()); -+ if (windowDisposition != WindowOpenDisposition.CURRENT_TAB) { -+ intent.putExtra(IntentHandler.EXTRA_OPEN_NEW_INCOGNITO_TAB, true); -+ } -+ intent.setPackage(context.getPackageName()); -+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); -+ IntentHandler.startActivityForTrustedIntent(intent); -+ return; -+ } - mTabSessionIdsRestored.put(tab.getSessionId(), true); - RecordUserAction.record("MobileRecentTabManagerRecentTabOpened"); - // Window disposition will select which tab to open. -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/IncognitoSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/IncognitoSettings.java -new file mode 100644 ---- /dev/null -+++ b/chrome/android/java/src/org/chromium/chrome/browser/privacy/settings/IncognitoSettings.java -@@ -0,0 +1,175 @@ -+/* -+ 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 . -+*/ -+ -+package org.chromium.chrome.browser.privacy.settings; -+ -+import android.os.Bundle; -+import android.content.Context; -+import android.content.Intent; -+import android.provider.Browser; -+import android.net.Uri; -+import android.view.Menu; -+import android.view.MenuInflater; -+import android.view.MenuItem; -+ -+import androidx.preference.Preference; -+import androidx.preference.PreferenceFragmentCompat; -+import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat; -+ -+import org.chromium.base.supplier.ObservableSupplier; -+import org.chromium.base.supplier.ObservableSupplierImpl; -+import java.util.function.Supplier; -+ -+import org.chromium.chrome.R; -+import org.chromium.chrome.browser.preferences.Pref; -+import org.chromium.chrome.browser.profiles.Profile; -+import org.chromium.chrome.browser.profiles.ProfileManager; -+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; -+import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; -+import org.chromium.chrome.browser.ui.messages.snackbar.INeedSnackbarManager; -+import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar; -+import org.chromium.chrome.browser.lifetime.ApplicationLifetime; -+import org.chromium.chrome.browser.settings.ChromeBaseSettingsFragment; -+ -+import org.chromium.components.browser_ui.settings.ChromeSwitchPreference; -+import org.chromium.components.browser_ui.settings.SettingsUtils; -+import org.chromium.components.browser_ui.settings.SettingsFragment; -+import org.chromium.components.prefs.PrefService; -+import org.chromium.components.user_prefs.UserPrefs; -+ -+/** -+ * Fragment to keep track of the all the always incognito related preferences. -+ */ -+public class IncognitoSettings -+ extends ChromeBaseSettingsFragment implements Preference.OnPreferenceChangeListener, -+ INeedSnackbarManager { -+ private Supplier mSnackbarManagerSupplier; -+ private Snackbar mSnackbar; -+ -+ private static final String PREF_ALWAYS_INCOGNITO = "always_incognito"; -+ private static final String PREF_INCOGNITO_TAB_HISTORY = "incognito_history"; -+ private static final String PREF_INCOGNITO_SAVE_SITE_SETTING = "incognito_save_site_setting"; -+ -+ private final PrefService prefService = UserPrefs.get(ProfileManager.getLastUsedRegularProfile()); -+ private final ObservableSupplierImpl mPageTitle = new ObservableSupplierImpl<>(); -+ -+ @Override -+ public ObservableSupplier getPageTitle() { -+ return mPageTitle; -+ } -+ -+ @Override -+ public @SettingsFragment.AnimationType int getAnimationType() { -+ return SettingsFragment.AnimationType.PROPERTY; -+ } -+ -+ @Override -+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { -+ mPageTitle.set(getString(R.string.incognito_settings_title)); -+ SettingsUtils.addPreferencesFromResource(this, R.xml.incognito_preferences); -+ setHasOptionsMenu(true); -+ updatePreferences(); -+ } -+ -+ @Override -+ public void onResume() { -+ super.onResume(); -+ updatePreferences(); -+ } -+ -+ public void updatePreferences() { -+ ChromeSwitchPreference alwaysIncognitoPref = -+ (ChromeSwitchPreference) findPreference(PREF_ALWAYS_INCOGNITO); -+ alwaysIncognitoPref.setChecked( -+ prefService.getBoolean(Pref.ALWAYS_INCOGNITO_ENABLED)); -+ alwaysIncognitoPref.setOnPreferenceChangeListener(this); -+ -+ mSnackbar = Snackbar.make(getActivity().getString(R.string.ui_relaunch_notice), -+ new SnackbarManager.SnackbarController() { -+ @Override -+ public void onDismissNoAction(Object actionData) { } -+ -+ @Override -+ public void onAction(Object actionData) { -+ ApplicationLifetime.terminate(true); -+ } -+ }, Snackbar.TYPE_NOTIFICATION, Snackbar.UMA_UNKNOWN) -+ .setDefaultLines(false) -+ .setAction(getActivity().getString(R.string.relaunch), -+ /*actionData*/null) -+ .setDuration(/*durationMs*/70000); -+ -+ ChromeSwitchPreference historyInIncognitoPref = -+ (ChromeSwitchPreference) findPreference(PREF_INCOGNITO_TAB_HISTORY); -+ historyInIncognitoPref.setChecked( -+ prefService.getBoolean(Pref.INCOGNITO_TAB_HISTORY_ENABLED)); -+ historyInIncognitoPref.setOnPreferenceChangeListener(this); -+ -+ ChromeSwitchPreference saveSiteSettingsPref = -+ (ChromeSwitchPreference) findPreference(PREF_INCOGNITO_SAVE_SITE_SETTING); -+ saveSiteSettingsPref.setChecked( -+ prefService.getBoolean(Pref.INCOGNITO_SAVE_SITE_SETTING_ENABLED)); -+ saveSiteSettingsPref.setOnPreferenceChangeListener(this); -+ } -+ -+ @Override -+ public boolean onPreferenceChange(Preference preference, Object newValue) { -+ String key = preference.getKey(); -+ if (PREF_ALWAYS_INCOGNITO.equals(key)) { -+ AlwaysIncognitoLinkInterceptor.setAlwaysIncognito((boolean) newValue); -+ } else if (PREF_INCOGNITO_TAB_HISTORY.equals(key)) { -+ prefService.setBoolean(Pref.INCOGNITO_TAB_HISTORY_ENABLED, (boolean) newValue); -+ } else if (PREF_INCOGNITO_SAVE_SITE_SETTING.equals(key)) { -+ prefService.setBoolean(Pref.INCOGNITO_SAVE_SITE_SETTING_ENABLED, (boolean) newValue); -+ } -+ if (!mSnackbarManagerSupplier.get().isShowing()) { -+ mSnackbarManagerSupplier.get().showSnackbar(mSnackbar); -+ } -+ return true; -+ } -+ -+ @Override -+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { -+ menu.clear(); -+ MenuItem help = -+ menu.add(Menu.NONE, R.id.menu_id_targeted_help, Menu.NONE, R.string.menu_help); -+ help.setIcon(VectorDrawableCompat.create( -+ getResources(), R.drawable.ic_help_and_feedback, getActivity().getTheme())); -+ } -+ -+ @Override -+ public boolean onOptionsItemSelected(MenuItem item) { -+ if (item.getItemId() == R.id.menu_id_targeted_help) { -+ Context context = getContext(); -+ -+ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/bromite/bromite/wiki/AlwaysIncognito")); -+ // 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); -+ return true; -+ } -+ return false; -+ } -+ -+ @Override -+ public void setSnackbarManagerSupplier(Supplier manager) { -+ mSnackbarManagerSupplier = manager; -+ } -+} -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/FragmentDependencyProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/FragmentDependencyProvider.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/settings/FragmentDependencyProvider.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/FragmentDependencyProvider.java -@@ -50,6 +50,7 @@ import org.chromium.chrome.browser.sync.settings.AccountManagementFragment; - import org.chromium.chrome.browser.sync.settings.GoogleServicesSettings; - import org.chromium.chrome.browser.sync.settings.ManageSyncSettings; - import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; -+import org.chromium.chrome.browser.ui.messages.snackbar.INeedSnackbarManager; - import org.chromium.components.browser_ui.accessibility.AccessibilitySettings; - import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; - import org.chromium.components.browser_ui.settings.FragmentSettingsNavigation; -@@ -229,6 +230,9 @@ public class FragmentDependencyProvider extends FragmentManager.FragmentLifecycl - SigninAndHistorySyncActivityLauncherImpl.get(), - new SettingsCustomTabLauncherImpl())); - } -+ if (fragment instanceof INeedSnackbarManager) { -+ ((INeedSnackbarManager)fragment).setSnackbarManagerSupplier(mSnackbarManagerSupplier); -+ } - if (fragment instanceof AccountManagementFragment) { - ((AccountManagementFragment) fragment) - .setSnackbarManagerSupplier(mSnackbarManagerSupplier); -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/tab_restore/HistoricalTabModelObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/tab_restore/HistoricalTabModelObserver.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/tab/tab_restore/HistoricalTabModelObserver.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/tab_restore/HistoricalTabModelObserver.java -@@ -32,6 +32,8 @@ import java.util.List; - import java.util.Set; - import java.util.function.Supplier; - -+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; -+ - /** A tab model observer for managing bulk closures. */ - @NullMarked - public class HistoricalTabModelObserver implements TabModelObserver { -@@ -81,9 +83,10 @@ public class HistoricalTabModelObserver implements TabModelObserver { - if (tabs.isEmpty() || !canRestore) return; - - if (tabs.size() == 1) { -+ boolean is_always_incognito = AlwaysIncognitoLinkInterceptor.isAlwaysIncognito(); - Tab tab = tabs.get(0); - if (!isTabGroupWithOneTab(tab)) { -- mHistoricalTabSaver.createHistoricalTab(tab); -+ mHistoricalTabSaver.createHistoricalTab(tab, is_always_incognito); - return; - } - } -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/tab_restore/HistoricalTabSaver.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/tab_restore/HistoricalTabSaver.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/tab/tab_restore/HistoricalTabSaver.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/tab_restore/HistoricalTabSaver.java -@@ -34,7 +34,7 @@ public interface HistoricalTabSaver { - * - * @param tab The {@link Tab} to create an entry for. - */ -- void createHistoricalTab(Tab tab); -+ void createHistoricalTab(Tab tab, boolean is_always_incognito); - - /** - * Creates a Group or Tab entry in TabRestoreService. -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/tab_restore/HistoricalTabSaverImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/tab_restore/HistoricalTabSaverImpl.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/tab/tab_restore/HistoricalTabSaverImpl.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/tab_restore/HistoricalTabSaverImpl.java -@@ -30,6 +30,8 @@ import java.util.Collections; - import java.util.List; - import java.util.function.Supplier; - -+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; -+ - /** Creates historical entries in TabRestoreService. */ - @NullMarked - @JNINamespace("historical_tab_saver") -@@ -87,10 +89,10 @@ public class HistoricalTabSaverImpl implements HistoricalTabSaver { - } - - @Override -- public void createHistoricalTab(Tab tab) { -+ public void createHistoricalTab(Tab tab, boolean is_always_incognito) { - if (!shouldSave(tab)) return; - -- createHistoricalTabInternal(tab); -+ createHistoricalTabInternal(tab, is_always_incognito); - } - - @Override -@@ -151,7 +153,7 @@ public class HistoricalTabSaverImpl implements HistoricalTabSaver { - - // If there is only a single valid tab remaining save it individually. - if (validEntries.size() == 1 && validEntries.get(0).isSingleTab()) { -- createHistoricalTabInternal(allTabs.get(0)); -+ createHistoricalTabInternal(allTabs.get(0), false); - return; - } - -@@ -191,14 +193,15 @@ public class HistoricalTabSaverImpl implements HistoricalTabSaver { - CollectionUtil.integerCollectionToIntArray(savedStateVersions)); - } - -- private void createHistoricalTabInternal(Tab tab) { -+ private void createHistoricalTabInternal(Tab tab, boolean is_always_incognito) { - RecordHistogram.recordEnumeratedHistogram( - "Tabs.RecentlyClosed.HistoricalSaverCloseType", - HistoricalSaverCloseType.TAB, - HistoricalSaverCloseType.COUNT); - HistoricalTabSaverImplJni.get() - .createHistoricalTab( -- tab, getWebContentsState(tab).buffer(), getWebContentsState(tab).version()); -+ tab, getWebContentsState(tab).buffer(), getWebContentsState(tab).version(), -+ is_always_incognito); - } - - /** -@@ -206,7 +209,7 @@ public class HistoricalTabSaverImpl implements HistoricalTabSaver { - * internal Chrome scheme, about:blank, or a native page and it cannot be incognito. - */ - private boolean shouldSave(Tab tab) { -- if (tab.isIncognito()) return false; -+ if (tab.isIncognito() && !AlwaysIncognitoLinkInterceptor.isAlwaysIncognito()) return false; - // Check the secondary tab model to see if the tab was moved instead of deleted. - if (tabIdExistsInSecondaryModel(tab.getId())) return false; - -@@ -294,7 +297,7 @@ public class HistoricalTabSaverImpl implements HistoricalTabSaver { - - @NativeMethods - interface Natives { -- void createHistoricalTab(Tab tab, ByteBuffer state, int savedStateVersion); -+ void createHistoricalTab(Tab tab, ByteBuffer state, int savedStateVersion, boolean is_always_incognito); - - void createHistoricalGroup( - TabModel model, -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java -@@ -27,6 +27,7 @@ import org.chromium.build.annotations.Contract; - import org.chromium.build.annotations.NullMarked; - import org.chromium.build.annotations.Nullable; - import org.chromium.chrome.R; -+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; - import org.chromium.chrome.browser.ActivityTabProvider; - import org.chromium.chrome.browser.ai.AiAssistantService; - import org.chromium.chrome.browser.app.appmenu.AppMenuPropertiesDelegateImpl; -@@ -241,7 +242,8 @@ public class TabbedAppMenuPropertiesDelegate extends AppMenuPropertiesDelegateIm - - // When the feature is enabled, show either "New Incognito tab" in incognito mode - // or "New tab" in normal mode. When the feature is disabled, show both. -- if (!IncognitoUtils.shouldOpenIncognitoAsWindow() || !isIncognitoShowing()) { -+ boolean always_incognito = AlwaysIncognitoLinkInterceptor.isAlwaysIncognito(); -+ if (!always_incognito || !IncognitoUtils.shouldOpenIncognitoAsWindow() || !isIncognitoShowing()) { - modelList.add(buildNewTabItem()); - } - if (!IncognitoUtils.shouldOpenIncognitoAsWindow() || isIncognitoShowing()) { -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 -@@ -210,6 +210,8 @@ import org.chromium.content_public.common.ContentSwitches; - import org.chromium.ui.UiUtils; - import org.chromium.ui.base.ActivityWindowAndroid; - import org.chromium.ui.base.DeviceFormFactor; -+import org.chromium.base.ContextUtils; -+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; - import org.chromium.ui.base.IntentRequestTracker; - import org.chromium.ui.base.LocalizationUtils; - import org.chromium.ui.display.DisplayUtil; -@@ -1281,7 +1283,7 @@ public class TabbedRootUiCoordinator extends RootUiCoordinator { - () -> { - mTabCreatorManagerSupplier - .get() -- .getTabCreator(/* incognito= */ false) -+ .getTabCreator(AlwaysIncognitoLinkInterceptor.isAlwaysIncognito()) - .launchUrl( - NewTabPageUtils.encodeNtpUrl( - NewTabPageLaunchOrigin.WEB_FEED), -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java -@@ -56,6 +56,10 @@ import org.chromium.url.GURL; - import java.util.Collections; - import java.util.function.Supplier; - -+import org.chromium.base.ContextUtils; -+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; -+import org.chromium.chrome.browser.tab.TabObserver; -+ - /** This class creates various kinds of new tabs and adds them to the right {@link TabModel}. */ - @NullMarked - public class ChromeTabCreator extends TabCreator -@@ -587,7 +591,6 @@ public class ChromeTabCreator extends TabCreator - // TODO(crbug.com/40691614): Clean up the launches from SearchActivity/Chrome. - public @Nullable Tab launchUrlFromExternalApp( - LoadUrlParams loadUrlParams, String appId, boolean forceNewTab, Intent intent) { -- assert !mIncognito; - // Don't re-use tabs for intents from Chrome. Note that this can be spoofed so shouldn't be - // relied on for anything security sensitive. - boolean isLaunchedFromChrome = TextUtils.equals(appId, mActivity.getPackageName()); -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelSelectorImpl.java -@@ -20,6 +20,7 @@ import org.chromium.build.annotations.Initializer; - import org.chromium.build.annotations.NullMarked; - import org.chromium.build.annotations.Nullable; - import org.chromium.chrome.browser.app.tabwindow.TabWindowManagerSingleton; -+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; - import org.chromium.chrome.browser.flags.ActivityType; - import org.chromium.chrome.browser.flags.ChromeFeatureList; - import org.chromium.chrome.browser.multiwindow.MultiInstanceManager; -@@ -139,6 +140,8 @@ public class TabModelSelectorImpl extends TabModelSelectorBase implements TabMod - ProfileProvider profileProvider = mProfileProviderSupplier.get(); - assert profileProvider != null; - -+ AlwaysIncognitoLinkInterceptor.migrateSettingToNative(); -+ - TabCreator regularTabCreator = getTabCreatorManager().getTabCreator(false); - TabCreator incognitoTabCreator = getTabCreatorManager().getTabCreator(true); - mRecentlyClosedBridge = -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 -@@ -61,6 +61,8 @@ import org.chromium.components.browser_ui.util.ConversionUtils; - import org.chromium.components.embedder_support.util.UrlUtilities; - import org.chromium.content_public.browser.LoadUrlParams; - -+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; -+ - import java.io.BufferedInputStream; - import java.io.ByteArrayInputStream; - import java.io.DataInputStream; -@@ -837,6 +839,13 @@ public class TabPersistentStore { - } - } - } -+ if (AlwaysIncognitoLinkInterceptor.isAlwaysIncognito()) { -+ if (!isIncognito) { -+ Log.w(TAG, "Failed to restore tab: not in incognito mode."); -+ return; -+ } -+ } -+ - TabModel model = mTabModelSelector.getModel(isIncognito); - - if (model.isIncognito() != isIncognito) { -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java -@@ -50,6 +50,7 @@ import org.chromium.base.supplier.OneshotSupplierImpl; - import org.chromium.cc.input.BrowserControlsState; - import org.chromium.chrome.R; - import org.chromium.chrome.browser.ActivityTabProvider; -+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; - import org.chromium.chrome.browser.IntentHandler; - import org.chromium.chrome.browser.app.tabwindow.TabWindowManagerSingleton; - import org.chromium.chrome.browser.back_press.BackPressManager; -@@ -869,7 +870,7 @@ public class ToolbarManager - return ret; - } - }, -- mToolbarPositionSupplier); -+ mToolbarPositionSupplier, AlwaysIncognitoLinkInterceptor.isAlwaysIncognito()); - mControlContainer = controlContainer; - mToolbarHairline = mControlContainer.findViewById(R.id.toolbar_hairline); - -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 -@@ -33,6 +33,8 @@ import org.chromium.components.browser_ui.widget.TintedDrawable; - import org.chromium.device.mojom.ScreenOrientationLockType; - import org.chromium.ui.util.ColorUtils; - -+import org.chromium.chrome.browser.AlwaysIncognitoLinkInterceptor; -+ - /** Stores info about a web app. */ - @NullMarked - public class WebappIntentDataProvider extends BrowserServicesIntentDataProvider { -@@ -47,6 +49,8 @@ public class WebappIntentDataProvider extends BrowserServicesIntentDataProvider - private final ColorProviderImpl mDarkColorProvider; - private @DisplayMode.EnumType int mResolvedDisplayMode = DisplayMode.UNDEFINED; - -+ private boolean mIsIncognito = false; -+ - /** Returns the toolbar color to use if a custom color is not specified by the webapp. */ - public static int getDefaultToolbarColor() { - return Color.WHITE; -@@ -82,6 +86,10 @@ public class WebappIntentDataProvider extends BrowserServicesIntentDataProvider - mWebappExtras = webappExtras; - mWebApkExtras = webApkExtras; - mActivityType = (webApkExtras != null) ? ActivityType.WEB_APK : ActivityType.WEBAPP; -+ -+ if (AlwaysIncognitoLinkInterceptor.isAlwaysIncognito()) { -+ mIsIncognito = true; -+ } - } - - @Override -@@ -177,6 +185,13 @@ public class WebappIntentDataProvider extends BrowserServicesIntentDataProvider - return mWebApkExtras; - } - -+ @Override -+ public @CustomTabProfileType int getCustomTabMode() { -+ return mIsIncognito -+ ? CustomTabProfileType.INCOGNITO -+ : CustomTabProfileType.REGULAR; -+ } -+ - @Override - public @ScreenOrientationLockType.EnumType int getDefaultOrientation() { - return mWebappExtras.orientation; -diff --git a/chrome/browser/android/historical_tab_saver.cc b/chrome/browser/android/historical_tab_saver.cc ---- a/chrome/browser/android/historical_tab_saver.cc -+++ b/chrome/browser/android/historical_tab_saver.cc -@@ -33,6 +33,11 @@ - // Must come after all headers that specialize FromJniType() / ToJniType(). - #include "chrome/android/chrome_jni_headers/HistoricalTabSaverImpl_jni.h" - -+#include "chrome/common/pref_names.h" -+#include "components/prefs/pref_registry_simple.h" -+#include "components/prefs/pref_service.h" -+#include "historical_tab_saver.h" -+ - using base::android::JavaParamRef; - using base::android::JavaRef; - using base::android::ScopedJavaLocalRef; -@@ -101,7 +106,8 @@ std::vector> StringsToUuids( - - void CreateHistoricalTab( - TabAndroid* tab_android, -- WebContentsStateByteBuffer web_contents_state_byte_buffer) { -+ WebContentsStateByteBuffer web_contents_state_byte_buffer, -+ bool is_always_incognito) { - if (!tab_android) { - return; - } -@@ -112,9 +118,14 @@ void CreateHistoricalTab( - return; - } - -+ auto* profile = Profile::FromBrowserContext(scoped_web_contents->web_contents()->GetBrowserContext()); -+ if (is_always_incognito) { -+ if (profile->GetOriginalProfile()->GetPrefs()->GetBoolean(prefs::kIncognitoTabHistoryEnabled)) -+ profile = profile->GetOriginalProfile(); -+ } -+ - sessions::TabRestoreService* service = -- TabRestoreServiceFactory::GetForProfile(Profile::FromBrowserContext( -- scoped_web_contents->web_contents()->GetBrowserContext())); -+ TabRestoreServiceFactory::GetForProfile(profile); - if (!service) { - return; - } -@@ -178,7 +189,7 @@ void CreateHistoricalBulkClosure( - per_tab_optional_tab_group_ids, - std::vector> tabs, - std::vector web_contents_state) { -- DCHECK(model); -+ if (!model) return; - DCHECK_EQ(tab_group_ids.size(), group_titles.size()); - DCHECK_EQ(tab_group_ids.size(), group_colors.size()); - DCHECK_EQ(tab_group_ids.size(), tab_group_ids.size()); -@@ -292,11 +303,12 @@ static void JNI_HistoricalTabSaverImpl_CreateHistoricalTab( - JNIEnv* env, - const JavaParamRef& jtab_android, - const JavaParamRef& state, -- jint saved_state_version) { -+ jint saved_state_version, -+ jboolean is_always_incognito) { - WebContentsStateByteBuffer web_contents_state = WebContentsStateByteBuffer( - ScopedJavaLocalRef(state), (int)saved_state_version); - CreateHistoricalTab(TabAndroid::GetNativeTab(env, jtab_android), -- std::move(web_contents_state)); -+ std::move(web_contents_state), is_always_incognito); - } - - static void JNI_HistoricalTabSaverImpl_CreateHistoricalGroup( -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 -@@ -461,6 +461,15 @@ ChromeAutocompleteProviderClient::GetAimEligibilityService() const { - return AimEligibilityServiceFactory::GetForProfile(profile_); - } - -+bool ChromeAutocompleteProviderClient::IsAlwaysIncognitoEnabled() const { -+#if BUILDFLAG(IS_ANDROID) -+ if (profile_->GetPrefs()->GetBoolean(prefs::kAlwaysIncognitoEnabled)) { -+ return true; -+ } -+#endif -+ return false; -+} -+ - bool ChromeAutocompleteProviderClient::IsOffTheRecord() const { - return profile_->IsOffTheRecord(); - } -diff --git a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.h b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.h ---- a/chrome/browser/autocomplete/chrome_autocomplete_provider_client.h -+++ b/chrome/browser/autocomplete/chrome_autocomplete_provider_client.h -@@ -99,6 +99,7 @@ class ChromeAutocompleteProviderClient : public AutocompleteProviderClient { - AimEligibilityService* GetAimEligibilityService() const override; - - bool IsOffTheRecord() const override; -+ bool IsAlwaysIncognitoEnabled() const override; - bool IsIncognitoProfile() const override; - bool IsGuestSession() const override; - bool SearchSuggestEnabled() const override; -diff --git a/chrome/browser/autocomplete/remote_suggestions_service_factory.cc b/chrome/browser/autocomplete/remote_suggestions_service_factory.cc ---- a/chrome/browser/autocomplete/remote_suggestions_service_factory.cc -+++ b/chrome/browser/autocomplete/remote_suggestions_service_factory.cc -@@ -4,6 +4,7 @@ - - #include "chrome/browser/autocomplete/remote_suggestions_service_factory.h" - -+#include "build/build_config.h" - #include "base/no_destructor.h" - #include "chrome/browser/autocomplete/document_suggestions_service_factory.h" - #include "chrome/browser/autocomplete/enterprise_search_aggregator_suggestions_service_factory.h" -@@ -43,9 +44,13 @@ RemoteSuggestionsServiceFactory::RemoteSuggestionsServiceFactory() - : ProfileKeyedServiceFactory( - "RemoteSuggestionsService", - ProfileSelections::Builder() -+#if BUILDFLAG(IS_ANDROID) -+ .WithRegular(ProfileSelection::kOriginalOnlyAndAlwaysIncognito) -+#else - // Service is needed in OTR profiles (Incognito and Guest). - .WithRegular(ProfileSelection::kOwnInstance) - .WithGuest(ProfileSelection::kOwnInstance) -+#endif - // TODO(crbug.com/41488885): Check if this service is needed for - // Ash Internals. - .WithAshInternals(ProfileSelection::kOriginalOnly) -diff --git a/chrome/browser/bookmarks/android/bookmark_bridge.cc b/chrome/browser/bookmarks/android/bookmark_bridge.cc ---- a/chrome/browser/bookmarks/android/bookmark_bridge.cc -+++ b/chrome/browser/bookmarks/android/bookmark_bridge.cc -@@ -37,6 +37,7 @@ - #include "base/strings/strcat.h" - #include "base/strings/utf_string_conversions.h" - #include "base/uuid.h" -+#include "chrome/common/pref_names.h" - #include "chrome/browser/bookmarks/bookmark_model_factory.h" - #include "chrome/browser/bookmarks/managed_bookmark_service_factory.h" - #include "chrome/browser/commerce/shopping_service_factory.h" -@@ -214,6 +215,12 @@ ScopedJavaLocalRef JNI_BookmarkBridge_NativeGetForProfile( - if (!profile) - return nullptr; - -+#if BUILDFLAG(IS_ANDROID) -+ if (profile->GetOriginalProfile() -+ ->GetPrefs()->GetBoolean(prefs::kAlwaysIncognitoEnabled)) { -+ profile = profile->GetOriginalProfile(); -+ } -+#endif - BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile); - if (!model) - return nullptr; -diff --git a/chrome/browser/content_settings/host_content_settings_map_factory.cc b/chrome/browser/content_settings/host_content_settings_map_factory.cc ---- a/chrome/browser/content_settings/host_content_settings_map_factory.cc -+++ b/chrome/browser/content_settings/host_content_settings_map_factory.cc -@@ -17,6 +17,7 @@ - #include "chrome/browser/search_engines/template_url_service_factory.h" - #include "chrome/browser/supervised_user/supervised_user_settings_service_factory.h" - #include "chrome/common/buildflags.h" -+#include "chrome/common/pref_names.h" - #include "components/content_settings/core/browser/content_settings_pref_provider.h" - #include "components/content_settings/core/browser/host_content_settings_map.h" - #include "components/permissions/features.h" -@@ -117,9 +118,25 @@ scoped_refptr - GetForProfile(original_profile); - - bool should_record_metrics = profiles::IsRegularUserProfile(profile); -+ bool always_incognito_enabled = false; -+ bool force_save_site_settings = false; -+ -+#if BUILDFLAG(IS_ANDROID) -+ PrefService* prefService = original_profile->GetPrefs(); -+ if (prefService->GetBoolean(prefs::kAlwaysIncognitoEnabled)) { -+ always_incognito_enabled = true; -+ } -+ -+ if (prefService->GetBoolean(prefs::kIncognitoSaveSiteSettingEnabled)) { -+ profile = original_profile; -+ force_save_site_settings = true; -+ } -+#endif -+ - scoped_refptr settings_map(new HostContentSettingsMap( - profile->GetPrefs(), -- profile->IsOffTheRecord() || profile->IsGuestSession(), -+ !force_save_site_settings && (profile->IsOffTheRecord() || profile->IsGuestSession()), -+ force_save_site_settings, - /*store_last_modified=*/true, profile->ShouldRestoreOldSessionCookies(), - should_record_metrics)); - -@@ -137,6 +154,9 @@ scoped_refptr - std::move(component_extension_provider)); - #endif // BUILDFLAG(IS_CHROMEOS) - -+ if (always_incognito_enabled) -+ return settings_map; -+ - #if BUILDFLAG(ENABLE_EXTENSIONS) - // These must be registered before before the HostSettings are passed over to - // the IOThread. Simplest to do this on construction. -diff --git a/chrome/browser/history/history_tab_helper.cc b/chrome/browser/history/history_tab_helper.cc ---- a/chrome/browser/history/history_tab_helper.cc -+++ b/chrome/browser/history/history_tab_helper.cc -@@ -48,6 +48,9 @@ - #include "components/feed/core/v2/public/feed_api.h" // nogncheck - #include "components/feed/core/v2/public/feed_service.h" // nogncheck - #include "content/public/browser/web_contents.h" -+#include "chrome/common/pref_names.h" -+#include "components/prefs/pref_registry_simple.h" -+#include "components/prefs/pref_service.h" - #else - #include "chrome/browser/ui/browser.h" - #include "chrome/browser/ui/browser_finder.h" -@@ -614,6 +617,13 @@ void HistoryTabHelper::TitleWasSet(NavigationEntry* entry) { - history::HistoryService* HistoryTabHelper::GetHistoryService() { - Profile* profile = - Profile::FromBrowserContext(web_contents()->GetBrowserContext()); -+ -+#if BUILDFLAG(IS_ANDROID) -+ if (profile->GetOriginalProfile()->GetPrefs()->GetBoolean(prefs::kIncognitoTabHistoryEnabled)) { -+ return HistoryServiceFactory::GetForProfile(profile, ServiceAccessType::IMPLICIT_ACCESS); -+ } -+#endif -+ - if (profile->IsOffTheRecord()) - return nullptr; - -@@ -621,6 +631,16 @@ history::HistoryService* HistoryTabHelper::GetHistoryService() { - profile, ServiceAccessType::IMPLICIT_ACCESS); - } - -+// static -+void HistoryTabHelper::RegisterProfilePrefs(PrefRegistrySimple* registry) { -+#if BUILDFLAG(IS_ANDROID) -+ registry->RegisterBooleanPref(prefs::kIncognitoTabHistoryEnabled, -+ /*default_value=*/false); -+ registry->RegisterBooleanPref(prefs::kIncognitoSaveSiteSettingEnabled, -+ /*default_value=*/false); -+#endif -+} -+ - void HistoryTabHelper::WebContentsDestroyed() { - translate_observation_.Reset(); - -diff --git a/chrome/browser/history/history_tab_helper.h b/chrome/browser/history/history_tab_helper.h ---- a/chrome/browser/history/history_tab_helper.h -+++ b/chrome/browser/history/history_tab_helper.h -@@ -17,6 +17,8 @@ - #include "components/translate/core/browser/translate_driver.h" - #include "content/public/browser/web_contents_observer.h" - #include "content/public/browser/web_contents_user_data.h" -+#include "components/prefs/pref_registry_simple.h" -+#include "components/prefs/pref_service.h" - - namespace history { - struct HistoryAddPageArgs; -@@ -59,6 +61,11 @@ class HistoryTabHelper - std::optional GetAppId() { return app_id_; } - #endif - -+ static void RegisterProfilePrefs(PrefRegistrySimple* registry); -+ -+ // Helper function to return the history service. May return null. -+ history::HistoryService* GetHistoryService(); -+ - private: - explicit HistoryTabHelper(content::WebContents* web_contents); - friend class content::WebContentsUserData; -@@ -101,9 +108,6 @@ class HistoryTabHelper - void OnLanguageDetermined( - const translate::LanguageDetectionDetails& details) override; - -- // Helper function to return the history service. May return null. -- history::HistoryService* GetHistoryService(); -- - // Returns true if our observed web contents is an eligible tab. - bool IsEligibleTab(const history::HistoryAddPageArgs& add_page_args) const; - -diff --git a/chrome/browser/offline_pages/android/offline_page_bridge.cc b/chrome/browser/offline_pages/android/offline_page_bridge.cc ---- a/chrome/browser/offline_pages/android/offline_page_bridge.cc -+++ b/chrome/browser/offline_pages/android/offline_page_bridge.cc -@@ -45,6 +45,9 @@ - #include "content/public/browser/web_contents.h" - #include "net/base/filename_util.h" - #include "url/android/gurl_android.h" -+#include "components/prefs/pref_registry_simple.h" -+#include "components/prefs/pref_service.h" -+#include "chrome/common/pref_names.h" - - // Must come after all headers that specialize FromJniType() / ToJniType(). - #include "chrome/android/chrome_jni_headers/OfflinePageBridge_jni.h" -@@ -731,9 +734,15 @@ void OfflinePageBridge::GetPageByOfflineIdDone( - } - - if (offline_page_model_->IsArchiveInInternalDir(offline_page->file_path)) { -+ bool is_trusted = true; -+ // in always incognito, never trust input file (show file name in url) -+ ProfileKey* profile_key = ProfileKey::FromSimpleFactoryKey(key_); -+ if (profile_key->GetPrefs()->GetBoolean(prefs::kIncognitoTabHistoryEnabled)) -+ is_trusted = false; -+ - ValidateFileCallback(launch_location, j_callback_obj, - offline_page->offline_id, offline_page->url, -- offline_page->file_path, true /* is_trusted*/); -+ offline_page->file_path, is_trusted); - return; - } - -diff --git a/chrome/browser/offline_pages/android/offline_page_model_factory.cc b/chrome/browser/offline_pages/android/offline_page_model_factory.cc ---- a/chrome/browser/offline_pages/android/offline_page_model_factory.cc -+++ b/chrome/browser/offline_pages/android/offline_page_model_factory.cc -@@ -23,6 +23,9 @@ - #include "components/keyed_service/core/simple_dependency_manager.h" - #include "components/offline_pages/core/model/offline_page_model_taskified.h" - #include "components/offline_pages/core/offline_page_metadata_store.h" -+#include "components/prefs/pref_registry_simple.h" -+#include "components/prefs/pref_service.h" -+#include "chrome/common/pref_names.h" - - namespace offline_pages { - -@@ -54,13 +57,15 @@ std::unique_ptr OfflinePageModelFactory::BuildServiceInstanceFor( - scoped_refptr background_task_runner = - base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()}); - -+ ProfileKey* profile_key = ProfileKey::FromSimpleFactoryKey(key)->GetOriginalKey(); -+ - base::FilePath store_path = -- key->GetPath().Append(chrome::kOfflinePageMetadataDirname); -+ profile_key->GetPath().Append(chrome::kOfflinePageMetadataDirname); - std::unique_ptr metadata_store( - new OfflinePageMetadataStore(background_task_runner, store_path)); - - base::FilePath persistent_archives_dir = -- key->GetPath().Append(chrome::kOfflinePageArchivesDirname); -+ profile_key->GetPath().Append(chrome::kOfflinePageArchivesDirname); - // If base::PathService::Get returns false, the temporary_archives_dir will be - // empty, and no temporary pages will be saved during this chrome lifecycle. - base::FilePath temporary_archives_dir; -@@ -69,7 +74,6 @@ std::unique_ptr OfflinePageModelFactory::BuildServiceInstanceFor( - temporary_archives_dir.Append(chrome::kOfflinePageArchivesDirname); - } - -- ProfileKey* profile_key = ProfileKey::FromSimpleFactoryKey(key); - auto archive_manager = std::make_unique( - temporary_archives_dir, persistent_archives_dir, - DownloadPrefs::GetDefaultDownloadDirectory(), background_task_runner, -@@ -87,4 +91,14 @@ std::unique_ptr OfflinePageModelFactory::BuildServiceInstanceFor( - return model; - } - -+SimpleFactoryKey* OfflinePageModelFactory::GetKeyToUse( -+ SimpleFactoryKey* key) const { -+ ProfileKey* profile_key = ProfileKey::FromSimpleFactoryKey(key); -+ if (profile_key->GetPrefs()->GetBoolean(prefs::kIncognitoTabHistoryEnabled) == false) { -+ return SimpleKeyedServiceFactory::GetKeyToUse(key); -+ } -+ -+ return profile_key->GetOriginalKey(); -+} -+ - } // namespace offline_pages -diff --git a/chrome/browser/offline_pages/android/request_coordinator_factory.cc b/chrome/browser/offline_pages/android/request_coordinator_factory.cc ---- a/chrome/browser/offline_pages/android/request_coordinator_factory.cc -+++ b/chrome/browser/offline_pages/android/request_coordinator_factory.cc -@@ -19,6 +19,7 @@ - #include "chrome/browser/ui/android/tab_model/tab_model.h" - #include "chrome/browser/ui/android/tab_model/tab_model_list.h" - #include "chrome/common/chrome_constants.h" -+#include "components/keyed_service/content/browser_context_dependency_manager.h" - #include "components/offline_pages/core/background/offliner.h" - #include "components/offline_pages/core/background/offliner_policy.h" - #include "components/offline_pages/core/background/request_coordinator.h" -@@ -28,6 +29,11 @@ - #include "components/offline_pages/core/offline_page_feature.h" - #include "content/public/browser/web_contents.h" - -+#include "chrome/browser/profiles/incognito_helpers.h" -+#include "components/prefs/pref_registry_simple.h" -+#include "components/prefs/pref_service.h" -+#include "chrome/common/pref_names.h" -+ - namespace network { - class NetworkQualityTracker; - } -@@ -65,14 +71,9 @@ class ActiveTabInfo : public RequestCoordinator::ActiveTabInfo { - } // namespace - - RequestCoordinatorFactory::RequestCoordinatorFactory() -- : ProfileKeyedServiceFactory( -+ : BrowserContextKeyedServiceFactory( - "OfflineRequestCoordinator", -- ProfileSelections::Builder() -- .WithRegular(ProfileSelection::kOriginalOnly) -- // TODO(crbug.com/40257657): Check if this service is needed in -- // Guest mode. -- .WithGuest(ProfileSelection::kOriginalOnly) -- .Build()) { -+ BrowserContextDependencyManager::GetInstance()) { - // Depends on OfflinePageModelFactory in SimpleDependencyManager. - } - -@@ -92,6 +93,12 @@ RequestCoordinator* RequestCoordinatorFactory::GetForBrowserContext( - std::unique_ptr - RequestCoordinatorFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { -+ if (context->IsOffTheRecord() && -+ Profile::FromBrowserContext(context)->GetOriginalProfile() -+ ->GetPrefs()->GetBoolean(prefs::kIncognitoTabHistoryEnabled) == false) { -+ // do not track history in incognito mode if preference is disabled -+ return nullptr; -+ } - std::unique_ptr policy(new OfflinerPolicy()); - std::unique_ptr offliner; - OfflinePageModel* model = -@@ -122,4 +129,16 @@ RequestCoordinatorFactory::BuildServiceInstanceForBrowserContext( - std::make_unique(profile)); - } - -+content::BrowserContext* -+RequestCoordinatorFactory::GetBrowserContextToUse( -+ content::BrowserContext* context) const { -+ if (Profile::FromBrowserContext(context)->GetOriginalProfile() -+ ->GetPrefs()->GetBoolean(prefs::kIncognitoTabHistoryEnabled) == false) { -+ return BrowserContextKeyedServiceFactory::GetBrowserContextToUse(context); -+ } -+ -+ return GetBrowserContextRedirectedInIncognito(context); -+} -+ -+ - } // namespace offline_pages -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 -@@ -48,6 +48,7 @@ class OfflinePageModelFactory : public SimpleKeyedServiceFactory { - - std::unique_ptr BuildServiceInstanceFor( - SimpleFactoryKey* key) const override; -+ SimpleFactoryKey* GetKeyToUse(SimpleFactoryKey* key) const override; - }; - - } // 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 -@@ -28,6 +28,11 @@ - #include "content/public/browser/navigation_entry.h" - #include "content/public/browser/navigation_handle.h" - -+#include "chrome/browser/profiles/profile.h" -+#include "components/prefs/pref_registry_simple.h" -+#include "components/prefs/pref_service.h" -+#include "chrome/common/pref_names.h" -+ - namespace { - class DefaultRecentTabHelperDelegate - : public offline_pages::RecentTabHelper::Delegate { -@@ -179,6 +184,14 @@ bool RecentTabHelper::EnsureInitialized() { - // WebContents with its origin as well. - snapshots_enabled_ = !tab_id_.empty() && - !web_contents()->GetBrowserContext()->IsOffTheRecord(); -+ if (!tab_id_.empty() && web_contents()->GetBrowserContext()->IsOffTheRecord()) { -+ if (Profile::FromBrowserContext(web_contents()->GetBrowserContext()) -+ ->GetOriginalProfile() -+ ->GetPrefs()->GetBoolean(prefs::kIncognitoTabHistoryEnabled)) { -+ snapshots_enabled_ = true; -+ incognito_tab_history_enabled_ = true; -+ } -+ } - - if (snapshots_enabled_) { - page_model_ = OfflinePageModelFactory::GetForBrowserContext( -@@ -338,7 +351,8 @@ void RecentTabHelper::WebContentsWasHidden() { - GetRecentPagesClientId(), - base::BindOnce(&RecentTabHelper::ContinueSnapshotWithIdsToPurge, - weak_ptr_factory_.GetWeakPtr(), -- last_n_ongoing_snapshot_info_.get())); -+ last_n_ongoing_snapshot_info_.get(), -+ /*user_requested*/ false)); - - last_n_latest_saved_snapshot_info_.reset(); - } -@@ -402,11 +416,12 @@ void RecentTabHelper::SaveSnapshotForDownloads(bool replace_latest) { - downloads_latest_saved_snapshot_info_->request_id, - downloads_latest_saved_snapshot_info_->origin); - std::vector ids{downloads_latest_saved_snapshot_info_->request_id}; -- ContinueSnapshotWithIdsToPurge(downloads_ongoing_snapshot_info_.get(), ids); -+ ContinueSnapshotWithIdsToPurge(downloads_ongoing_snapshot_info_.get(), /*user_requested*/ true, ids); - } else { - // Otherwise go straight to saving the page. - DCHECK(downloads_ongoing_snapshot_info_); - ContinueSnapshotAfterPurge(downloads_ongoing_snapshot_info_.get(), -+ /*user_requested*/ true, - OfflinePageModel::DeletePageResult::SUCCESS); - } - } -@@ -423,6 +438,7 @@ void RecentTabHelper::SaveSnapshotForDownloads(bool replace_latest) { - // for early termination in case of errors. - void RecentTabHelper::ContinueSnapshotWithIdsToPurge( - SnapshotProgressInfo* snapshot_info, -+ bool user_requested, - const std::vector& page_ids) { - DCHECK(snapshot_info); - -@@ -432,13 +448,20 @@ void RecentTabHelper::ContinueSnapshotWithIdsToPurge( - criteria.offline_ids = page_ids; - page_model_->DeletePagesWithCriteria( - criteria, base::BindOnce(&RecentTabHelper::ContinueSnapshotAfterPurge, -- weak_ptr_factory_.GetWeakPtr(), snapshot_info)); -+ weak_ptr_factory_.GetWeakPtr(), snapshot_info, -+ user_requested)); - } - - void RecentTabHelper::ContinueSnapshotAfterPurge( - SnapshotProgressInfo* snapshot_info, -+ bool user_requested, - OfflinePageModel::DeletePageResult result) { -- if (result != OfflinePageModel::DeletePageResult::SUCCESS) { -+ // remove snapshot save of recent tab if always incognito mode is active -+ // so recents tab list is empty at every startup -+ // the user can choose to disable the feature -+ if ((incognito_tab_history_enabled_ || !base::FeatureList::IsEnabled(offline_pages::kOfflinePagesAutoSaveFeature) -+ || result != OfflinePageModel::DeletePageResult::SUCCESS) -+ && !user_requested) { - ReportSnapshotCompleted(snapshot_info, false); - return; - } -diff --git a/chrome/browser/offline_pages/recent_tab_helper.h b/chrome/browser/offline_pages/recent_tab_helper.h ---- a/chrome/browser/offline_pages/recent_tab_helper.h -+++ b/chrome/browser/offline_pages/recent_tab_helper.h -@@ -105,8 +105,10 @@ class RecentTabHelper - - bool EnsureInitialized(); - void ContinueSnapshotWithIdsToPurge(SnapshotProgressInfo* snapshot_info, -+ bool user_requested, - const std::vector& page_ids); - void ContinueSnapshotAfterPurge(SnapshotProgressInfo* snapshot_info, -+ bool user_requested, - OfflinePageModel::DeletePageResult result); - void SavePageCallback(SnapshotProgressInfo* snapshot_info, - OfflinePageModel::SavePageResult result, -@@ -128,6 +130,9 @@ class RecentTabHelper - // Not page-specific. - bool snapshots_enabled_ = false; - -+ // If true, tab history in incognito mode is enabled -+ bool incognito_tab_history_enabled_ = false; -+ - // Snapshot progress information for an ongoing snapshot requested by - // downloads. Null if there's no ongoing request. - std::unique_ptr downloads_ongoing_snapshot_info_; -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 -@@ -18,7 +18,7 @@ namespace offline_pages { - class RequestCoordinator; - - // A factory to create one unique RequestCoordinator. --class RequestCoordinatorFactory : public ProfileKeyedServiceFactory { -+class RequestCoordinatorFactory : public BrowserContextKeyedServiceFactory { - public: - static RequestCoordinatorFactory* GetInstance(); - static RequestCoordinator* GetForBrowserContext( -@@ -36,6 +36,8 @@ class RequestCoordinatorFactory : public ProfileKeyedServiceFactory { - - std::unique_ptr BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const override; -+ content::BrowserContext* GetBrowserContextToUse( -+ content::BrowserContext* context) const override; - }; - - } // 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 -@@ -257,6 +257,7 @@ - - #if BUILDFLAG(IS_ANDROID) - #include "chrome/browser/accessibility/accessibility_prefs/android/accessibility_prefs_controller.h" -+#include "chrome/browser/history/history_tab_helper.h" - #include "chrome/browser/android/ntp/recent_tabs_page_prefs.h" - #include "chrome/browser/android/oom_intervention/oom_intervention_decider.h" - #include "chrome/browser/android/preferences/browser_prefs_android.h" -@@ -2203,6 +2204,10 @@ void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry, - usage_stats::UsageStatsBridge::RegisterProfilePrefs(registry); - variations::VariationsService::RegisterProfilePrefs(registry); - webapps::InstallPromptPrefs::RegisterProfilePrefs(registry); -+ // register incognito pref -+ registry->RegisterBooleanPref(prefs::kAlwaysIncognitoEnabled, -+ /*default_value=*/false); -+ HistoryTabHelper::RegisterProfilePrefs(registry); - #else // BUILDFLAG(IS_ANDROID) - bookmarks_webui::RegisterProfilePrefs(registry); - browser_sync::ForeignSessionHandler::RegisterProfilePrefs(registry); -diff --git a/chrome/browser/profiles/profile_selections.cc b/chrome/browser/profiles/profile_selections.cc ---- a/chrome/browser/profiles/profile_selections.cc -+++ b/chrome/browser/profiles/profile_selections.cc -@@ -5,6 +5,9 @@ - #include "chrome/browser/profiles/profile_selections.h" - - #include "base/memory/ptr_util.h" -+#include "components/prefs/pref_registry_simple.h" -+#include "components/prefs/pref_service.h" -+#include "chrome/common/pref_names.h" - #include "chrome/browser/profiles/profile.h" - #include "components/profile_metrics/browser_profile_type.h" - -@@ -112,6 +115,13 @@ Profile* ProfileSelections::ApplyProfileSelection(Profile* profile) const { - return nullptr; - case ProfileSelection::kOriginalOnly: - return profile->IsOffTheRecord() ? nullptr : profile; -+#if BUILDFLAG(IS_ANDROID) -+ case ProfileSelection::kOriginalOnlyAndAlwaysIncognito: -+ return profile->IsOffTheRecord() && -+ !(profile->GetOriginalProfile() -+ ->GetPrefs() -+ ->GetBoolean(prefs::kAlwaysIncognitoEnabled)) ? nullptr : profile; -+#endif - case ProfileSelection::kOwnInstance: - return profile; - case ProfileSelection::kRedirectedToOriginal: -diff --git a/chrome/browser/profiles/profile_selections.h b/chrome/browser/profiles/profile_selections.h ---- a/chrome/browser/profiles/profile_selections.h -+++ b/chrome/browser/profiles/profile_selections.h -@@ -6,7 +6,7 @@ - #define CHROME_BROWSER_PROFILES_PROFILE_SELECTIONS_H_ - - #include -- -+#include "build/build_config.h" - class Profile; - - // A helper function that checks whether Keyed Services should be created for -@@ -25,6 +25,11 @@ bool AreKeyedServicesDisabledForProfileByDefault(const Profile* profile); - enum class ProfileSelection { - kNone, // Original: No Profile -- OTR: No Profile - kOriginalOnly, // Original: Self -- OTR: No Profile -+#if BUILDFLAG(IS_ANDROID) -+ kOriginalOnlyAndAlwaysIncognito, -+ // Original: Self -- OTR: Self (with AlwaysIncognito ON) -+ // -- OTR: No Profile (with AlwaysIncognito OFF) -+#endif - kOwnInstance, // Original: Self -- OTR: Self - kRedirectedToOriginal, // Original: Self -- OTR: Original - kOffTheRecordOnly // Original: No Profile -- OTR: Self -diff --git a/chrome/browser/ui/android/native_page/BUILD.gn b/chrome/browser/ui/android/native_page/BUILD.gn ---- a/chrome/browser/ui/android/native_page/BUILD.gn -+++ b/chrome/browser/ui/android/native_page/BUILD.gn -@@ -31,6 +31,8 @@ robolectric_library("junit") { - - deps = [ - ":java", -+ "//base:base_java", -+ "//components/embedder_support/android:util_java", - "//base:base_junit_test_support", - "//third_party/android_deps:org_mockito_mockito_core_java", - "//third_party/junit", -diff --git a/chrome/browser/ui/android/native_page/java/src/org/chromium/chrome/browser/ui/native_page/NativePage.java b/chrome/browser/ui/android/native_page/java/src/org/chromium/chrome/browser/ui/native_page/NativePage.java ---- a/chrome/browser/ui/android/native_page/java/src/org/chromium/chrome/browser/ui/native_page/NativePage.java -+++ b/chrome/browser/ui/android/native_page/java/src/org/chromium/chrome/browser/ui/native_page/NativePage.java -@@ -17,6 +17,8 @@ import org.chromium.url.GURL; - import java.lang.annotation.Retention; - import java.lang.annotation.RetentionPolicy; - -+import org.chromium.base.ContextUtils; -+ - /** An interface for pages that will be using Android views instead of html/rendered Web content. */ - @NullMarked - public interface NativePage { -@@ -187,7 +189,8 @@ public interface NativePage { - */ - static boolean isNativePageUrl(GURL url, boolean isIncognito, boolean hasPdfDownload) { - return url != null -- && nativePageType(url, null, isIncognito, hasPdfDownload) != NativePageType.NONE; -+ && nativePageType(url, null, isIncognito, hasPdfDownload, /*isAlwaysIncognito*/ false) -+ != NativePageType.NONE; - } - - /** -@@ -197,7 +200,7 @@ public interface NativePage { - * not have chrome or chrome-native scheme. - */ - static boolean isChromePageUrl(GURL url, boolean isIncognito) { -- return url != null && chromePageType(url, null, isIncognito) != NativePageType.NONE; -+ return url != null && chromePageType(url, null, isIncognito, /*isAlwaysIncognito*/false) != NativePageType.NONE; - } - - /** -@@ -211,7 +214,8 @@ public interface NativePage { - GURL url, - @Nullable NativePage candidatePage, - boolean isIncognito, -- boolean hasPdfDownload) { -+ boolean hasPdfDownload, -+ boolean isAlwaysIncognito) { - if (hasPdfDownload) { - // For navigation with associated pdf download (e.g. open a pdf link), pdf page should - // be created. -@@ -229,7 +233,7 @@ public interface NativePage { - // created after the pdf document is re-downloaded in other parts of the code. - return NativePageType.NONE; - } else { -- return chromePageType(url, candidatePage, isIncognito); -+ return chromePageType(url, candidatePage, isIncognito, isAlwaysIncognito); - } - } - -@@ -241,7 +245,7 @@ public interface NativePage { - * which do not have chrome or chrome-native scheme. - */ - private static @NativePageType int chromePageType( -- GURL url, @Nullable NativePage candidatePage, boolean isIncognito) { -+ GURL url, @Nullable NativePage candidatePage, boolean isIncognito, boolean isAlwaysIncognito) { - String host = url.getHost(); - String scheme = url.getScheme(); - if (!UrlConstants.CHROME_NATIVE_SCHEME.equals(scheme) -@@ -261,7 +265,8 @@ public interface NativePage { - return NativePageType.DOWNLOADS; - } else if (UrlConstants.HISTORY_HOST.equals(host)) { - return NativePageType.HISTORY; -- } else if (UrlConstants.RECENT_TABS_HOST.equals(host) && !isIncognito) { -+ } else if (UrlConstants.RECENT_TABS_HOST.equals(host) && -+ (!isIncognito || isAlwaysIncognito)) { - return NativePageType.RECENT_TABS; - } else if (UrlConstants.EXPLORE_HOST.equals(host)) { - return NativePageType.EXPLORE; -diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java ---- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java -+++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarMediator.java -@@ -99,6 +99,11 @@ import org.chromium.ui.interpolators.Interpolators; - import org.chromium.ui.modaldialog.ModalDialogManager; - import org.chromium.url.GURL; - -+import org.chromium.components.user_prefs.UserPrefs; -+import org.chromium.components.prefs.PrefService; -+import org.chromium.chrome.browser.profiles.ProfileManager; -+import org.chromium.chrome.browser.preferences.Pref; -+ - import java.util.ArrayList; - import java.util.List; - import java.util.function.BooleanSupplier; -@@ -448,6 +453,9 @@ class LocationBarMediator - if (!DeviceFormFactor.isNonMultiDisplayContextOnTablet(mContext)) return; - Tab tab = mLocationBarDataProvider.getTab(); - if (tab == null) return; -+ PrefService prefService = UserPrefs.get(ProfileManager.getLastUsedRegularProfile()); -+ boolean historyEnabledInIncognito = -+ prefService.getBoolean(Pref.INCOGNITO_TAB_HISTORY_ENABLED); - boolean onNtp = UrlUtilities.isNtpUrl(tab.getUrl()); - - if (ChromeAccessibilityUtil.get().isAccessibilityEnabled() -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 -@@ -6669,6 +6669,31 @@ To change this setting, BEGIN_LINKdelete the Chrome d - - Cookies, cache, and other site data - -+ -+ -+ Always incognito mode -+ -+ -+ Incognito navigation settings -+ -+ -+ Always open links in incognito -+ -+ -+ Opens links in incognito tabs when you click on new tab or on a link -+ -+ -+ Enable history -+ -+ -+ Record history even in incognito mode -+ -+ -+ Remember site settings -+ -+ -+ Remember site settings changes in incognito mode -+ - - <link1>Search history</link1> and <link2>other forms of activity</link2> may be saved in your Google Account - -diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java ---- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java -+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/LocationBarModel.java -@@ -167,6 +167,7 @@ public class LocationBarModel implements ToolbarDataProvider, LocationBarDataPro - protected GURL mVisibleGurl = GURL.emptyGURL(); - protected String mFormattedFullUrl; - protected String mUrlForDisplay; -+ private boolean mIsAlwaysIncognito; - - // notifyUrlChanged and notifySecurityStateChanged are usually called 3 times across a same - // document navigation. The first call is usually necessary, which updates the UrlBar to reflect -@@ -191,7 +192,8 @@ public class LocationBarModel implements ToolbarDataProvider, LocationBarDataPro - NewTabPageDelegate newTabPageDelegate, - UrlFormatter urlFormatter, - OfflineStatus offlineStatus, -- ObservableSupplier<@ControlsPosition Integer> toolbarPositionSupplier) { -+ ObservableSupplier<@ControlsPosition Integer> toolbarPositionSupplier, -+ boolean isAlwaysIncognito) { - mContext = context; - mNtpDelegate = newTabPageDelegate; - mUrlFormatter = urlFormatter; -diff --git a/chrome/browser/ui/messages/android/BUILD.gn b/chrome/browser/ui/messages/android/BUILD.gn ---- a/chrome/browser/ui/messages/android/BUILD.gn -+++ b/chrome/browser/ui/messages/android/BUILD.gn -@@ -27,6 +27,7 @@ android_library("java") { - srcjar_deps = [ ":jni_headers" ] - sources = [ - "java/src/org/chromium/chrome/browser/ui/messages/infobar/SimpleConfirmInfoBarBuilder.java", -+ "java/src/org/chromium/chrome/browser/ui/messages/snackbar/INeedSnackbarManager.java", - "java/src/org/chromium/chrome/browser/ui/messages/snackbar/Snackbar.java", - "java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarCollection.java", - "java/src/org/chromium/chrome/browser/ui/messages/snackbar/SnackbarManager.java", -diff --git a/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/INeedSnackbarManager.java b/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/INeedSnackbarManager.java -new file mode 100644 ---- /dev/null -+++ b/chrome/browser/ui/messages/android/java/src/org/chromium/chrome/browser/ui/messages/snackbar/INeedSnackbarManager.java -@@ -0,0 +1,28 @@ -+/* -+ 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 . -+*/ -+ -+package org.chromium.chrome.browser.ui.messages.snackbar; -+ -+import java.util.function.Supplier; -+import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; -+ -+/** -+ * An interface that allows using snackbars in the settings -+ */ -+public interface INeedSnackbarManager { -+ void setSnackbarManagerSupplier(Supplier manager); -+} -diff --git a/chrome/browser/ui/search_engines/search_engine_tab_helper.cc b/chrome/browser/ui/search_engines/search_engine_tab_helper.cc ---- a/chrome/browser/ui/search_engines/search_engine_tab_helper.cc -+++ b/chrome/browser/ui/search_engines/search_engine_tab_helper.cc -@@ -12,6 +12,7 @@ - #include "chrome/browser/search_engines/template_url_fetcher_factory.h" - #include "chrome/browser/search_engines/template_url_service_factory.h" - #include "chrome/browser/ui/search_engines/edit_search_engine_controller.h" -+#include "chrome/common/pref_names.h" - #include "chrome/common/url_constants.h" - #include "components/search_engines/template_url.h" - #include "components/search_engines/template_url_fetcher.h" -@@ -165,6 +166,11 @@ void SearchEngineTabHelper::PageHasOpenSearchDescriptionDocument( - - // Download the OpenSearch description document. If this is successful, a - // new keyword will be created when done. -+#if BUILDFLAG(IS_ANDROID) -+ if (profile->GetOriginalProfile()->GetPrefs()->GetBoolean(prefs::kIncognitoTabHistoryEnabled)) { -+ is_off_the_record = false; -+ } -+#endif - TemplateURLFetcherFactory::GetForProfile(profile)->ScheduleDownload( - keyword, osdd_url, entry->GetFavicon().url, - frame->GetLastCommittedOrigin(), url_loader_factory.get(), -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 -@@ -4101,6 +4101,12 @@ inline constexpr char kOutOfProcessSystemDnsResolutionEnabled[] = - "net.out_of_process_system_dns_resolution_enabled"; - #endif // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) - -+#if BUILDFLAG(IS_ANDROID) -+inline constexpr char kAlwaysIncognitoEnabled[] = "always_incognito_enabled"; -+inline constexpr char kIncognitoSaveSiteSettingEnabled[] = "incognito_tab_history_enabled"; -+inline constexpr char kIncognitoTabHistoryEnabled[] = "incognito_site_setting_enabled"; -+#endif -+ - // A list of hostnames to disable HTTPS Upgrades / HTTPS-First Mode warnings on. - inline constexpr char kHttpAllowlist[] = "https_upgrades.policy.http_allowlist"; - -diff --git a/components/content_settings/core/browser/content_settings_pref_provider.cc b/components/content_settings/core/browser/content_settings_pref_provider.cc ---- a/components/content_settings/core/browser/content_settings_pref_provider.cc -+++ b/components/content_settings/core/browser/content_settings_pref_provider.cc -@@ -120,10 +120,12 @@ void PrefProvider::RegisterProfilePrefs( - - PrefProvider::PrefProvider(PrefService* prefs, - bool off_the_record, -+ bool force_save_site_settings, - bool store_last_modified, - bool restore_session) - : prefs_(prefs), - off_the_record_(off_the_record), -+ force_save_site_settings_(force_save_site_settings), - store_last_modified_(store_last_modified), - clock_(base::DefaultClock::GetInstance()) { - TRACE_EVENT_BEGIN("startup", "PrefProvider::PrefProvider"); -@@ -146,11 +148,13 @@ PrefProvider::PrefProvider(PrefService* prefs, - WebsiteSettingsRegistry* website_settings = - WebsiteSettingsRegistry::GetInstance(); - for (const WebsiteSettingsInfo* info : *website_settings) { -+ bool save_site_settings = force_save_site_settings_ && -+ info->incognito_behavior() == WebsiteSettingsInfo::INHERIT_IN_INCOGNITO; - content_settings_prefs_.insert(std::make_pair( - info->type(), - std::make_unique( - info->type(), prefs_, &pref_change_registrar_, info->pref_name(), -- info->partitioned_pref_name(), off_the_record_, restore_session, -+ info->partitioned_pref_name(), off_the_record_ && !save_site_settings, restore_session, - base::BindRepeating(&PrefProvider::Notify, - base::Unretained(this))))); - } -diff --git a/components/content_settings/core/browser/content_settings_pref_provider.h b/components/content_settings/core/browser/content_settings_pref_provider.h ---- a/components/content_settings/core/browser/content_settings_pref_provider.h -+++ b/components/content_settings/core/browser/content_settings_pref_provider.h -@@ -38,6 +38,7 @@ class PrefProvider : public UserModifiableProvider { - - PrefProvider(PrefService* prefs, - bool off_the_record, -+ bool force_save_site_settings, - bool store_last_modified, - bool restore_session); - -@@ -130,6 +131,7 @@ class PrefProvider : public UserModifiableProvider { - raw_ptr prefs_; - - const bool off_the_record_; -+ const bool force_save_site_settings_; - - bool store_last_modified_; - -diff --git a/components/content_settings/core/browser/host_content_settings_map.cc b/components/content_settings/core/browser/host_content_settings_map.cc ---- a/components/content_settings/core/browser/host_content_settings_map.cc -+++ b/components/content_settings/core/browser/host_content_settings_map.cc -@@ -288,6 +288,7 @@ struct ContentSettingEntry { - - HostContentSettingsMap::HostContentSettingsMap(PrefService* prefs, - bool is_off_the_record, -+ bool force_save_site_settings, - bool store_last_modified, - bool restore_session, - bool should_record_metrics) -@@ -297,6 +298,7 @@ HostContentSettingsMap::HostContentSettingsMap(PrefService* prefs, - #endif - prefs_(prefs), - is_off_the_record_(is_off_the_record), -+ force_save_site_settings_(force_save_site_settings), - store_last_modified_(store_last_modified), - allow_invalid_secondary_pattern_for_testing_(false), - clock_(base::DefaultClock::GetInstance()) { -@@ -310,7 +312,7 @@ HostContentSettingsMap::HostContentSettingsMap(PrefService* prefs, - policy_provider->AddObserver(this); - - auto pref_provider_ptr = std::make_unique( -- prefs_, is_off_the_record_, store_last_modified_, restore_session); -+ prefs_, is_off_the_record_, force_save_site_settings_, store_last_modified_, restore_session); - pref_provider_ = pref_provider_ptr.get(); - content_settings_providers_[ProviderType::kPrefProvider] = - std::move(pref_provider_ptr); -diff --git a/components/content_settings/core/browser/host_content_settings_map.h b/components/content_settings/core/browser/host_content_settings_map.h ---- a/components/content_settings/core/browser/host_content_settings_map.h -+++ b/components/content_settings/core/browser/host_content_settings_map.h -@@ -84,6 +84,7 @@ class HostContentSettingsMap : public content_settings::Observer, - // profile or a guest session. - HostContentSettingsMap(PrefService* prefs, - bool is_off_the_record, -+ bool force_save_site_settings, - bool store_last_modified, - bool restore_session, - bool should_record_metrics); -@@ -551,6 +552,8 @@ class HostContentSettingsMap : public content_settings::Observer, - // Whether this settings map is for an incognito or guest session. - bool is_off_the_record_; - -+ bool force_save_site_settings_ = false; -+ - // Whether ContentSettings in the PrefProvider will store a last_modified - // timestamp. - bool store_last_modified_; -diff --git a/components/omnibox/browser/autocomplete_provider_client.cc b/components/omnibox/browser/autocomplete_provider_client.cc ---- a/components/omnibox/browser/autocomplete_provider_client.cc -+++ b/components/omnibox/browser/autocomplete_provider_client.cc -@@ -81,3 +81,7 @@ AutocompleteProviderClient::GetGeminiPrototypeOmniboxService() const { - return nullptr; - } - #endif // BUILDFLAG(IS_IOS) -+ -+bool AutocompleteProviderClient::IsAlwaysIncognitoEnabled() const { -+ return false; -+} -diff --git a/components/omnibox/browser/autocomplete_provider_client.h b/components/omnibox/browser/autocomplete_provider_client.h ---- a/components/omnibox/browser/autocomplete_provider_client.h -+++ b/components/omnibox/browser/autocomplete_provider_client.h -@@ -161,6 +161,7 @@ class AutocompleteProviderClient : public OmniboxAction::Client { - virtual bool IsOffTheRecord() const = 0; - virtual bool IsIncognitoProfile() const = 0; - virtual bool IsGuestSession() const = 0; -+ virtual bool IsAlwaysIncognitoEnabled() const = 0; - - virtual bool SearchSuggestEnabled() const = 0; - -diff --git a/components/omnibox/browser/base_search_provider.cc b/components/omnibox/browser/base_search_provider.cc ---- a/components/omnibox/browser/base_search_provider.cc -+++ b/components/omnibox/browser/base_search_provider.cc -@@ -401,7 +401,7 @@ bool BaseSearchProvider::CanSendSuggestRequest( - - // Don't make a suggest request if in incognito mode; unless for the Lens - // searchboxes. -- if (client->IsOffTheRecord() && -+ if (client->IsOffTheRecord() && !client->IsAlwaysIncognitoEnabled() && - !omnibox::IsLensSearchbox(page_classification)) { - return false; - } -diff --git a/components/omnibox/browser/search_provider.cc b/components/omnibox/browser/search_provider.cc ---- a/components/omnibox/browser/search_provider.cc -+++ b/components/omnibox/browser/search_provider.cc -@@ -921,7 +921,8 @@ std::unique_ptr SearchProvider::CreateSuggestLoader( - // is required. - // Request for suggestions in OTR contexts is not allowed; except for the Lens - // searchboxes. -- DCHECK(!client()->IsOffTheRecord() || -+ if (!client()->IsAlwaysIncognitoEnabled()) -+ DCHECK(!client()->IsOffTheRecord() || - omnibox::IsLensSearchbox(input.current_page_classification())); - return client() - ->GetRemoteSuggestionsService(/*create_if_necessary=*/true) -diff --git a/cromite_flags/chrome/browser/about_flags_cc/add-an-always-incognito-mode.inc b/cromite_flags/chrome/browser/about_flags_cc/add-an-always-incognito-mode.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/chrome/browser/about_flags_cc/add-an-always-incognito-mode.inc -@@ -0,0 +1,13 @@ -+#ifdef FLAG_SECTION -+ -+#if BUILDFLAG(IS_ANDROID) -+ -+ {"offline-pages-auto-save", -+ "Enables autosave of offline page", -+ "Enables autosave of offline page, as automatic switching in case " -+ "the device goes offline.", kOsAndroid, -+ FEATURE_VALUE_TYPE(offline_pages::kOfflinePagesAutoSaveFeature)}, -+ -+#endif -+ -+#endif -diff --git a/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/add-an-always-incognito-mode.inc b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/add-an-always-incognito-mode.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/add-an-always-incognito-mode.inc -@@ -0,0 +1 @@ -+SET_CROMITE_FEATURE_ENABLED(kCCTIncognitoAvailableToThirdParty); -diff --git a/cromite_flags/components/offline_pages/core/offline_page_feature_cc/add-an-always-incognito-mode.inc b/cromite_flags/components/offline_pages/core/offline_page_feature_cc/add-an-always-incognito-mode.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/components/offline_pages/core/offline_page_feature_cc/add-an-always-incognito-mode.inc -@@ -0,0 +1,3 @@ -+CROMITE_FEATURE(kOfflinePagesAutoSaveFeature, -+ "OfflinePagesAutoSaveEnabled", -+ base::FEATURE_DISABLED_BY_DEFAULT); -diff --git a/cromite_flags/components/offline_pages/core/offline_page_feature_h/add-an-always-incognito-mode.inc b/cromite_flags/components/offline_pages/core/offline_page_feature_h/add-an-always-incognito-mode.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/components/offline_pages/core/offline_page_feature_h/add-an-always-incognito-mode.inc -@@ -0,0 +1 @@ -+BASE_DECLARE_FEATURE(kOfflinePagesAutoSaveFeature); --- diff --git a/build/cromite_patches/Add-autoplay-site-setting.patch b/build/cromite_patches/Add-autoplay-site-setting.patch deleted file mode 100644 index de521ad9..00000000 --- a/build/cromite_patches/Add-autoplay-site-setting.patch +++ /dev/null @@ -1,343 +0,0 @@ -From: uazo -Date: Sat, 7 Nov 2020 21:59:18 +0000 -Subject: Add autoplay site setting - -Original License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html -Require: Content-settings-infrastructure.patch ---- - .../res/drawable-hdpi/settings_autoplay.png | Bin 0 -> 456 bytes - .../res/drawable-mdpi/settings_autoplay.png | Bin 0 -> 296 bytes - .../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 - .../impl/BromiteAutoplayContentSetting.java | 93 ++++++++++++++++++ - .../bromite_content_settings/autoplay.grdp | 21 ++++ - .../bromite_content_settings/autoplay.inc | 12 +++ - .../core/browser/content_settings_registry.cc | 2 +- - .../core/html/media/autoplay_policy.cc | 14 +++ - .../core/html/media/autoplay_policy.h | 4 + - 11 files changed, 145 insertions(+), 1 deletion(-) - 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 - create mode 100644 components/browser_ui/site_settings/android/java/res/drawable-xxhdpi/settings_autoplay.png - create mode 100644 components/browser_ui/site_settings/android/java/res/drawable-xxxhdpi/settings_autoplay.png - create mode 100644 components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/impl/BromiteAutoplayContentSetting.java - create mode 100644 components/browser_ui/strings/bromite_content_settings/autoplay.grdp - create mode 100644 components/content_settings/core/browser/bromite_content_settings/autoplay.inc - -diff --git a/components/browser_ui/site_settings/android/java/res/drawable-hdpi/settings_autoplay.png b/components/browser_ui/site_settings/android/java/res/drawable-hdpi/settings_autoplay.png -new file mode 100644 -index 0000000000000000000000000000000000000000..a8a9265f14cd8445ad1f55845099e60dc3c4edf1 -GIT binary patch -literal 456 -zcmV;(0XP1MP) -zv2MaJ5QYmZs7m@68Tt%)0T}7#GcJmh4B69}fh}W`x!sUhd4N1chpY%8u@-es;cQTy -zGbWY1VQ**q%l&uuT^{am%=;qbIaI7>hvTfF;<*Ut{eMAbL!QB&HFUzBXR~2P41Zx8 -z)>!6-O>RP(9xN_j-$FSZiy-wPUj)-Jl(4<5Et;Mc!dwn%v3G5VXX+fR6 -zfpz3x+Y|Y)K6`aNHVw{qdv4}^DAdl0F;gIV|-Tf!x{>CqV{oZM{Igf1s0000m&@A# - -literal 0 -HcmV?d00001 - -diff --git a/components/browser_ui/site_settings/android/java/res/drawable-mdpi/settings_autoplay.png b/components/browser_ui/site_settings/android/java/res/drawable-mdpi/settings_autoplay.png -new file mode 100644 -index 0000000000000000000000000000000000000000..49fa10d44f4007532d0d03d15fdcb1a715857e96 -GIT binary patch -literal 296 -zcmV+@0oVSCP)ST5R5=Hk+X;yg9#|y{3AI^L4jN_0yR^lp_9hQ%}W9}t45wTQfw*%xg4TCAk}wycgV>|Ky0000fy;5RRo0wX?Hwh9Zw(#Vgp}9uO@kj!GT?W_XdLp-A4qiidDg@B~=L$xN`2Fo6Ry -zoC`9!!WnNX*>%6WZ+~v@;l6HTnG5Pb03nIUF_Q>F2&iK&{=v0ABR=d&Dwa&+>$CpO -zN8o1rOjQOd%dgDu@oJ0JqvZU3NJ!T~_A+ -zw>7k!d)Tk%U1PSM!@i8g3Qx?K@4o3Chv27xSRb|1lL*LZCn{;7NuQNv676eW3vl6flwYSMx=l(G+1kL4+N%tlEhfAQy}(nDFWr -zbXw{Z4tCiO1OTTBcDW68nyP>kgahDIfn8VxO;uQ6Yd8Q-71auD*mMx(DnrEqaHQ#wV`gM2wnZ5*JY22WGzg(js{SktOi -z^lWxu_H1_Y+jaYe^U~wOk$z>$zx3sgE%FC1e02PlFgl8cUvcTd1Q~vNjPEQT-j%AMEx!+_@2>y=002ovPDHLkV1fY;_gnw~ - -literal 0 -HcmV?d00001 - -diff --git a/components/browser_ui/site_settings/android/java/res/drawable-xxhdpi/settings_autoplay.png b/components/browser_ui/site_settings/android/java/res/drawable-xxhdpi/settings_autoplay.png -new file mode 100644 -index 0000000000000000000000000000000000000000..7fceb8c2b546970a3720e8ab225799aa03895b7f -GIT binary patch -literal 792 -zcmV+z1LypSP)VsP6)iEx2tCzs -zN?!=Ys;Vvm+R!dxZSbnPR`u*)=$?G~q+QDONj}}54UDQIpq+dnupUkhrgMXd90~(9 -z>D-*sHYV1z%eSyr=BeO3;m5&Ge2@~l(oA;)6G#{m)`C=tNtmpB)?rp!gtK?*J1gwU@xCMXrLcRedOG_Aoa>~>!hiCJ{ojT&^9q|2A6eswfXXRwNew}jUlw`DpvbTS<8sy~{`pMeAwZ6%yL!Xy$ -zN2*G=JTQ;lS${M|)Hzo?siK0Up2cT1|*=)t}wk-{0CUjdxjX0fI83Mf&Ybo(3S(znzBU#@89zg#sfKk^r7!;A&m>sd-zwDXs+niu)Z|Ao(> -z;TfMn@`obY`5%hfKBYBiHdqh(w`25gSn1i))3E8OQ(Krf&Sz(7oXMvd@I-#RfhTrA -zML#uC<7*jKp)UCfqsuC_%t(wck71K;$=5J$u~{A)viWQYSLEv(xME8~Gk$Frr{wD& -zI9;0^#@?^uf&63!9@uK4#y8Tm7iz{GPOt-V=gT=S+ekOkUbdWb=Rw%P3EhS2?={j1 -znNJh=@$S+WRQC#g>V2o{6{t=Z?|z3LG~wtMZ-y=hF8Pd>n~yV_n@0=J13_GRGrG;6 -z!}Wm096J^ -zi6*pop5R{>=jCZ_r}{L`gMViY9x2#y;<%R48&%;r*r_TXTLH$uVB1MRu#FdSHKn7? -z`-}(CeD>8zNbpUBfCq&DBPizKc3=Bf2#S%UBhDc1I|)nBzrdE{;{7Yp^VBj!$TQBx -zU|S+zz^3T;B^;-eQx(qzY{qtLVzw3S*uwXXPwGdTn6<_H_N*cX4be2o$8UU5g&+nP -ztP-!%(B(t6s4>q!uz#qm24HoQ*AmGxMfcqM;3rOm2koVsD>M`&n>zm4?vwt*x~f|!wop&79@E9>Qn-8+GpV^zc}AJ -zFAqSSO71+T*$FqG_g1BxlLw$qrE-qb>xHV|o^zsEc>wBE^0J)HeYgSrw55wDS3~zX{EoY-``m=49hBUsaw;r=* -z+}2~(e82VBHh+(@{oX!+2n#ThdxByg0maD|^ghF~58(`dil|N~cLlAek3rFLSGLCO -ib6hJ{tXQ#P#rX?0El=KlH_u1_0000. -+*/ -+ -+package org.chromium.components.browser_ui.site_settings.impl; -+ -+import org.chromium.components.browser_ui.site_settings.R; -+ -+import org.chromium.components.browser_ui.site_settings.BromiteCustomContentSetting; -+import org.chromium.components.browser_ui.site_settings.ContentSettingsResources; -+import org.chromium.components.browser_ui.site_settings.SiteSettingsCategory; -+import org.chromium.components.content_settings.ContentSetting; -+import org.chromium.components.content_settings.ContentSettingsType; -+import org.chromium.content_public.browser.BrowserContextHandle; -+ -+import androidx.annotation.Nullable; -+import androidx.preference.Preference; -+import androidx.preference.PreferenceScreen; -+ -+import java.util.ArrayList; -+ -+public class BromiteAutoplayContentSetting extends BromiteCustomContentSetting { -+ public BromiteAutoplayContentSetting() { -+ super(/*contentSettingsType*/ ContentSettingsType.AUTOPLAY, -+ /*defaultEnabledValue*/ ContentSetting.ALLOW, -+ /*defaultDisabledValue*/ ContentSetting.BLOCK, -+ /*allowException*/ true, -+ /*preferenceKey*/ "autoplay", -+ /*profilePrefKey*/ "autoplay"); -+ } -+ -+ @Override -+ public ContentSettingsResources.ResourceItem getResourceItem() { -+ return new ContentSettingsResources.ResourceItem( -+ /*icon*/ R.drawable.settings_autoplay, -+ /*title*/ R.string.autoplay_permission_title, -+ /*defaultEnabledValue*/ getDefaultEnabledValue(), -+ /*defaultDisabledValue*/ getDefaultDisabledValue(), -+ /*enabledSummary*/ R.string.website_settings_category_autoplay_enabled, -+ /*disabledSummary*/ R.string.website_settings_category_autoplay_disabled, -+ /*summaryOverrideForScreenReader*/ 0); -+ } -+ -+ @Override -+ public int getCategorySummary(@Nullable @ContentSetting int value) { -+ switch (value) { -+ case ContentSetting.ALLOW: -+ return R.string.website_settings_category_autoplay_enabled; -+ case ContentSetting.BLOCK: -+ return R.string.website_settings_category_autoplay_disabled; -+ default: -+ return 0; -+ } -+ } -+ -+ @Override -+ public int getCategoryDescription() { -+ return R.string.website_settings_add_site_description_autoplay; -+ } -+ -+ @Override -+ public boolean requiresTriStateContentSetting() { -+ return false; -+ } -+ -+ @Override -+ public boolean showOnlyDescriptions() { -+ return true; -+ } -+ -+ @Override -+ public int getAddExceptionDialogMessage() { -+ return R.string.website_settings_category_autoplay_enabled; -+ } -+ -+ @Override -+ public @Nullable Boolean considerException(SiteSettingsCategory category, @ContentSetting int value) { -+ return value != ContentSetting.BLOCK; -+ } -+} -diff --git a/components/browser_ui/strings/bromite_content_settings/autoplay.grdp b/components/browser_ui/strings/bromite_content_settings/autoplay.grdp -new file mode 100644 ---- /dev/null -+++ b/components/browser_ui/strings/bromite_content_settings/autoplay.grdp -@@ -0,0 +1,21 @@ -+ -+ -+ -+ Autoplay -+ -+ -+ Allow autoplay for a specific site. -+ -+ -+ Allow sites to automatically play muted videos -+ -+ -+ Autoplay disabled -+ -+ -+ Allowed to autoplay -+ -+ -+ Not allowed to autoplay -+ -+ -diff --git a/components/content_settings/core/browser/bromite_content_settings/autoplay.inc b/components/content_settings/core/browser/bromite_content_settings/autoplay.inc -new file mode 100644 ---- /dev/null -+++ b/components/content_settings/core/browser/bromite_content_settings/autoplay.inc -@@ -0,0 +1,12 @@ -+ content_settings::WebsiteSettingsRegistry::GetInstance() -+ ->GetMutable(ContentSettingsType::AUTOPLAY) -+ ->set_show_into_info_page() -+ .set_desktop_ui() -+ .set_is_renderer_content_setting() -+ .set_title_ui(IDS_AUTOPLAY_PERMISSION_TITLE) -+ .set_description_ui(IDS_WEBSITE_SETTINGS_ADD_SITE_DESCRIPTION_AUTOPLAY) -+ .set_allowed_ui(IDS_WEBSITE_SETTINGS_CATEGORY_AUTOPLAY_ENABLED) -+ .set_blocked_ui(IDS_WEBSITE_SETTINGS_CATEGORY_AUTOPLAY_DISABLED) -+ .set_allowed_exceptions_ui(IDS_SETTINGS_SITE_SETTINGS_AUTOPLAY_ALLOWED_EXCEPTIONS) -+ .set_blocked_exceptions_ui(IDS_SETTINGS_SITE_SETTINGS_AUTOPLAY_BLOCKED_EXCEPTIONS) -+ .set_mid_sentence_ui(IDS_AUTOPLAY_PERMISSION_TITLE); -diff --git a/components/content_settings/core/browser/content_settings_registry.cc b/components/content_settings/core/browser/content_settings_registry.cc ---- a/components/content_settings/core/browser/content_settings_registry.cc -+++ b/components/content_settings/core/browser/content_settings_registry.cc -@@ -255,7 +255,7 @@ void ContentSettingsRegistry::Init() { - ContentSettingsInfo::INHERIT_IN_INCOGNITO, - PermissionSettingsInfo::EXCEPTIONS_ON_SECURE_ORIGINS_ONLY); - -- Register(ContentSettingsType::AUTOPLAY, "autoplay", CONTENT_SETTING_ALLOW, -+ Register(ContentSettingsType::AUTOPLAY, "autoplay", CONTENT_SETTING_BLOCK, - WebsiteSettingsInfo::UNSYNCABLE, /*allowlisted_primary_schemes=*/{}, - /*valid_settings=*/{CONTENT_SETTING_ALLOW, CONTENT_SETTING_BLOCK}, - WebsiteSettingsInfo::TOP_ORIGIN_ONLY_SCOPE, -diff --git a/third_party/blink/renderer/core/html/media/autoplay_policy.cc b/third_party/blink/renderer/core/html/media/autoplay_policy.cc ---- a/third_party/blink/renderer/core/html/media/autoplay_policy.cc -+++ b/third_party/blink/renderer/core/html/media/autoplay_policy.cc -@@ -9,6 +9,7 @@ - #include "third_party/blink/public/mojom/autoplay/autoplay.mojom-blink.h" - #include "third_party/blink/public/mojom/frame/lifecycle.mojom-blink.h" - #include "third_party/blink/public/mojom/webpreferences/web_preferences.mojom-blink.h" -+#include "third_party/blink/public/platform/web_content_settings_client.h" - #include "third_party/blink/public/platform/web_media_player.h" - #include "third_party/blink/public/web/web_local_frame.h" - #include "third_party/blink/public/web/web_local_frame_client.h" -@@ -346,6 +347,8 @@ void AutoplayPolicy::TryUnlockingUserGesture() { - } - - bool AutoplayPolicy::IsGestureNeededForPlayback() const { -+ if (!IsAutoplayAllowedPerSettings()) -+ return true; - if (!IsLockedPendingUserGesture()) - return false; - -@@ -457,6 +460,17 @@ void AutoplayPolicy::MaybeSetAutoplayInitiated() { - } - } - -+bool AutoplayPolicy::IsAutoplayAllowedPerSettings() const { -+ LocalFrame* frame = element_->GetDocument().GetFrame(); -+ if (!frame) -+ return false; -+ if (auto* settings_client = frame->GetContentSettingsClient()) { -+ return settings_client->AllowContentSetting( -+ ContentSettingsType::AUTOPLAY, /*default_value*/ false); -+ } -+ return true; -+} -+ - bool AutoplayPolicy::ShouldAutoplay() { - 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 ---- a/third_party/blink/renderer/core/html/media/autoplay_policy.h -+++ b/third_party/blink/renderer/core/html/media/autoplay_policy.h -@@ -148,6 +148,10 @@ class CORE_EXPORT AutoplayPolicy final - // should use, if checking to see if an action is allowed. - bool IsLockedPendingUserGesture() const; - -+ // Return true if and only if the settings allow autoplay of media on this -+ // frame. -+ bool IsAutoplayAllowedPerSettings() const; -+ - bool IsAutoplayingMutedInternal(bool muted) const; - bool IsOrWillBeAutoplayingMutedInternal(bool muted) const; - --- diff --git a/build/cromite_patches/Add-bookmark-import-export-actions.patch b/build/cromite_patches/Add-bookmark-import-export-actions.patch deleted file mode 100644 index c07ea764..00000000 --- a/build/cromite_patches/Add-bookmark-import-export-actions.patch +++ /dev/null @@ -1,1650 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Wed, 1 Aug 2018 09:19:40 +0200 -Subject: Add bookmark import/export actions - -Add bookmark import/export actions in bookmarks activity and page -Reduce permissions needed for bookmarks import/export -Completely remove contacts picker permission from the file dialog - -Requires: Adds-support-for-writing-URIs.patch -Requires: Restore-BookmarkToolbar-setCurrentFolder.patch - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - chrome/android/java/AndroidManifest.xml | 1 - - .../menu/bookmark_toolbar_menu_improved.xml | 14 + - .../browser/TabbedModeTabDelegateFactory.java | 5 +- - .../app/bookmarks/BookmarkActivity.java | 32 ++ - .../native_page/NativePageFactory.java | 9 +- - chrome/browser/BUILD.gn | 11 +- - .../bookmarks/android/bookmark_bridge.cc | 197 ++++++++++++ - .../bookmarks/android/bookmark_bridge.h | 30 +- - .../browser/bookmarks/BookmarkBridge.java | 39 +++ - .../browser/bookmarks/BookmarkDelegate.java | 10 + - .../bookmarks/BookmarkManagerCoordinator.java | 9 + - .../bookmarks/BookmarkManagerMediator.java | 283 ++++++++++++++++++ - .../browser/bookmarks/BookmarkPage.java | 9 +- - .../browser/bookmarks/BookmarkToolbar.java | 27 ++ - .../bookmarks/BookmarkToolbarMediator.java | 4 + - .../bookmarks/BookmarkToolbarProperties.java | 8 +- - .../bookmarks/BookmarkToolbarViewBinder.java | 6 + - .../dialogs/DownloadLocationCustomView.java | 8 +- - .../DownloadLocationDialogCoordinator.java | 10 +- - .../flags/android/chrome_feature_list.cc | 1 + - .../browser/flags/ChromeFeatureList.java | 1 + - chrome/browser/importer/profile_writer.cc | 10 + - chrome/browser/importer/profile_writer.h | 6 + - .../preferences/ChromePreferenceKeys.java | 3 + - .../strings/android_chrome_strings.grd | 18 ++ - chrome/utility/BUILD.gn | 7 + - .../importer/bookmarks_file_importer.cc | 4 + - .../headless_select_file_dialog.cc | 4 + - .../content/content_bookmark_parser_utils.cc | 3 + - .../add-bookmark-import-export-actions.inc | 12 + - .../add-bookmark-import-export-actions.inc | 4 + - .../add-bookmark-import-export-actions.inc | 1 + - .../chromium/ui/base/SelectFileDialog.java | 24 +- - .../java/strings/android_ui_strings.grd | 3 + - ui/shell_dialogs/select_file_dialog.h | 2 + - .../select_file_dialog_android.cc | 6 + - ui/shell_dialogs/select_file_dialog_android.h | 2 + - ui/shell_dialogs/select_file_dialog_linux.cc | 4 + - ui/shell_dialogs/select_file_dialog_linux.h | 2 + - ui/shell_dialogs/select_file_dialog_win.cc | 5 + - 40 files changed, 810 insertions(+), 24 deletions(-) - create mode 100644 cromite_flags/chrome/browser/about_flags_cc/add-bookmark-import-export-actions.inc - create mode 100644 cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/add-bookmark-import-export-actions.inc - create mode 100644 cromite_flags/chrome/browser/flags/android/chrome_feature_list_h/add-bookmark-import-export-actions.inc - -diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml ---- a/chrome/android/java/AndroidManifest.xml -+++ b/chrome/android/java/AndroidManifest.xml -@@ -62,7 +62,6 @@ by a child template that "extends" this file. - - -- - - - -diff --git a/chrome/android/java/res/menu/bookmark_toolbar_menu_improved.xml b/chrome/android/java/res/menu/bookmark_toolbar_menu_improved.xml ---- a/chrome/android/java/res/menu/bookmark_toolbar_menu_improved.xml -+++ b/chrome/android/java/res/menu/bookmark_toolbar_menu_improved.xml -@@ -51,6 +51,20 @@ found in the LICENSE file. - android:title="@string/create_new_folder" - app:showAsAction="ifRoom" - app:iconTint="@color/default_icon_color_secondary_tint_list" /> -+ -+ - mShareDelegateSupplier; - private final Supplier mEphemeralTabCoordinatorSupplier; -@@ -91,7 +92,7 @@ public class TabbedModeTabDelegateFactory implements TabDelegateFactory { - private final BackPressManager mBackPressManager; - - public TabbedModeTabDelegateFactory( -- Activity activity, -+ ChromeActivity activity, - BrowserControlsVisibilityDelegate appBrowserControlsVisibilityDelegate, - Supplier shareDelegateSupplier, - Supplier ephemeralTabCoordinatorSupplier, -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkActivity.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkActivity.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkActivity.java -@@ -6,6 +6,8 @@ package org.chromium.chrome.browser.app.bookmarks; - - import static org.chromium.build.NullUtil.assumeNonNull; - -+import android.os.Bundle; -+ - import android.content.ComponentName; - import android.content.Intent; - import android.text.TextUtils; -@@ -35,6 +37,9 @@ import org.chromium.components.embedder_support.util.UrlConstants; - import org.chromium.ui.modaldialog.ModalDialogManager; - import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogType; - -+import org.chromium.ui.base.ActivityWindowAndroid; -+import org.chromium.ui.base.IntentRequestTracker; -+ - /** - * The activity that displays the bookmark UI on the phone. It keeps a {@link - * BookmarkManagerCoordinator} inside of it and creates a snackbar manager. This activity should -@@ -50,6 +55,9 @@ public class BookmarkActivity extends SnackbarActivity { - private @Nullable BookmarkOpener mBookmarkOpener; - private @Nullable OnKeyDownHandler mOnKeyDownHandler; - -+ private ActivityWindowAndroid mWindowAndroid; -+ private IntentRequestTracker mIntentRequestTracker; -+ - @Override - protected void onProfileAvailable(Profile profile) { - super.onProfileAvailable(profile); -@@ -82,6 +90,14 @@ public class BookmarkActivity extends SnackbarActivity { - mOnKeyDownHandler = - BackPressHelper.create( - this, getOnBackPressedDispatcher(), mBookmarkManagerCoordinator); -+ -+ final boolean listenToActivityState = true; -+ mIntentRequestTracker = IntentRequestTracker.createFromActivity(this); -+ mWindowAndroid = new ActivityWindowAndroid(this, listenToActivityState, -+ mIntentRequestTracker, /*InsetObserver*/ null, -+ /* trackOcclusion= */ true); -+ mBookmarkManagerCoordinator.setWindow(mWindowAndroid, -+ getModalDialogManagerSupplier().get()); - } - - @Override -@@ -109,6 +125,7 @@ public class BookmarkActivity extends SnackbarActivity { - @Override - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - super.onActivityResult(requestCode, resultCode, data); -+ mWindowAndroid.getIntentRequestTracker().onActivityResult(requestCode, resultCode, data); - if (requestCode == EDIT_BOOKMARK_REQUEST_CODE && resultCode == RESULT_OK) { - assumeNonNull(data); - BookmarkId bookmarkId = -@@ -118,6 +135,21 @@ public class BookmarkActivity extends SnackbarActivity { - } - } - -+ @Override -+ protected void onSaveInstanceState(Bundle outState) { -+ super.onSaveInstanceState(outState); -+ -+ mWindowAndroid.getIntentRequestTracker().saveInstanceState(outState); -+ } -+ -+ @Override -+ public void onRequestPermissionsResult( -+ int requestCode, String[] permissions, int[] grantResults) { -+ if (mWindowAndroid.handlePermissionResult(requestCode, permissions, grantResults)) -+ return; -+ super.onRequestPermissionsResult(requestCode, permissions, grantResults); -+ } -+ - @Override - protected ModalDialogManager createModalDialogManager() { - return new ModalDialogManager(new AppModalPresenter(this), ModalDialogType.APP); -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/native_page/NativePageFactory.java -@@ -25,6 +25,7 @@ import org.chromium.base.supplier.OneshotSupplier; - import org.chromium.build.annotations.NullMarked; - import org.chromium.build.annotations.Nullable; - import org.chromium.chrome.R; -+import org.chromium.chrome.browser.app.ChromeActivity; - import org.chromium.chrome.browser.app.download.home.DownloadPage; - import org.chromium.chrome.browser.back_press.BackPressManager; - import org.chromium.chrome.browser.bookmarks.BookmarkPage; -@@ -76,7 +77,7 @@ import java.util.function.Supplier; - */ - @NullMarked - public class NativePageFactory { -- private final Activity mActivity; -+ private final ChromeActivity mActivity; - private final BottomSheetController mBottomSheetController; - private final BrowserControlsManager mBrowserControlsManager; - private final Supplier<@Nullable Tab> mCurrentTabSupplier; -@@ -100,7 +101,7 @@ public class NativePageFactory { - private final BackPressManager mBackPressManager; - - public NativePageFactory( -- Activity activity, -+ ChromeActivity activity, - BottomSheetController sheetController, - BrowserControlsManager browserControlsManager, - Supplier<@Nullable Tab> currentTabSupplier, -@@ -175,7 +176,7 @@ public class NativePageFactory { - - @VisibleForTesting - static class NativePageBuilder { -- private final Activity mActivity; -+ private final ChromeActivity mActivity; - private final BottomSheetController mBottomSheetController; - private final Supplier mNewTabPageCreationTracker; - private final BrowserControlsManager mBrowserControlsManager; -@@ -284,7 +285,7 @@ public class NativePageFactory { - mTabModelSelector, - mEdgeToEdgeControllerSupplier), - mActivity.getComponentName(), -- mBackPressManager); -+ mBackPressManager, mActivity); - } - - protected NativePage buildDownloadsPage(Tab tab) { -diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn ---- a/chrome/browser/BUILD.gn -+++ b/chrome/browser/BUILD.gn -@@ -205,6 +205,8 @@ static_library("browser") { - "bad_message.h", - "bookmarks/bookmark_model_factory.cc", - "bookmarks/bookmark_model_factory.h", -+ "bookmarks/bookmark_html_writer.cc", -+ "bookmarks/bookmark_html_writer.h", - "bookmarks/chrome_bookmark_client.cc", - "bookmarks/chrome_bookmark_client.h", - "bookmarks/managed_bookmark_service_factory.cc", -@@ -1625,6 +1627,13 @@ static_library("browser") { - "webdata_services/web_data_service_factory.cc", - ] - -+ if (is_android) { -+ sources += [ -+ "importer/profile_writer.cc", -+ "importer/profile_writer.h", -+ ] -+ } -+ - configs += [ - "//build/config/compiler:wexit_time_destructors", - "//build/config:precompiled_headers", -@@ -3715,8 +3724,6 @@ static_library("browser") { - "bookmarks/bookmark_expanded_state_tracker.h", - "bookmarks/bookmark_expanded_state_tracker_factory.cc", - "bookmarks/bookmark_expanded_state_tracker_factory.h", -- "bookmarks/bookmark_html_writer.cc", -- "bookmarks/bookmark_html_writer.h", - "bookmarks/bookmark_merged_surface_ordering_storage.cc", - "bookmarks/bookmark_merged_surface_ordering_storage.h", - "bookmarks/bookmark_merged_surface_service.cc", -diff --git a/chrome/browser/bookmarks/android/bookmark_bridge.cc b/chrome/browser/bookmarks/android/bookmark_bridge.cc ---- a/chrome/browser/bookmarks/android/bookmark_bridge.cc -+++ b/chrome/browser/bookmarks/android/bookmark_bridge.cc -@@ -68,6 +68,28 @@ - #include "content/public/browser/web_contents.h" - #include "url/gurl.h" - -+#include "base/android/content_uri_utils.h" -+#include "base/android/path_utils.h" -+#include "base/strings/utf_string_conversions.h" -+#include "chrome/browser/bookmarks/bookmark_html_writer.h" -+#include "chrome/browser/importer/profile_writer.h" -+#include "chrome/browser/platform_util.h" -+#include "chrome/browser/ui/chrome_select_file_policy.h" -+#include "components/user_data_importer/common/imported_bookmark_entry.h" -+#include "components/user_data_importer/content/content_bookmark_parser.h" -+#include "components/user_data_importer/content/content_bookmark_parser_utils.h" -+#include "chrome/common/url_constants.h" -+#include "components/favicon_base/favicon_usage_data.h" -+#include "components/search_engines/template_url.h" -+#include "components/url_formatter/url_fixer.h" -+#include "ui/android/window_android.h" -+#include "base/task/task_traits.h" -+#include "base/task/thread_pool.h" -+#include "content/public/browser/browser_task_traits.h" -+#include "base/files/file_path.h" -+#include "ui/shell_dialogs/selected_file_info.h" -+#include "ui/shell_dialogs/select_file_dialog.h" -+ - // Must come after all headers that specialize FromJniType() / ToJniType(). - #include "chrome/browser/bookmarks/android/jni_headers/BookmarkBridge_jni.h" - -@@ -296,6 +318,10 @@ BookmarkBridge::~BookmarkBridge() { - partner_bookmarks_shim_observation_.Reset(); - bookmark_model_observation_.Reset(); - profile_observation_.Reset(); -+ // There may be pending file dialogs, we need to tell them that we've gone -+ // away so they don't try and call back to us. -+ if (select_file_dialog_) -+ select_file_dialog_->ListenerDestroyed(); - } - - void BookmarkBridge::Destroy(JNIEnv* env) { -@@ -847,6 +873,177 @@ jint BookmarkBridge::GetTotalBookmarkCount( - return count; - } - -+void BookmarkBridge::ImportBookmarks(JNIEnv* env, -+ const JavaParamRef& obj, -+ const JavaParamRef& java_window) { -+ DCHECK(IsLoaded()); -+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); -+ -+ ui::WindowAndroid* window = -+ ui::WindowAndroid::FromJavaWindowAndroid(java_window); -+ CHECK(window); -+ -+ select_file_dialog_ = ui::SelectFileDialog::Create( -+ this, std::make_unique(nullptr)); -+ -+ //NOTE: extension and description are not used on Android, thus not set -+ ui::SelectFileDialog::FileTypeInfo file_type_info; -+ -+ const std::vector v_accept_types = { u"text/html" }; -+ select_file_dialog_->SetAcceptTypes(v_accept_types); -+ -+ select_file_dialog_->SelectFile( -+ ui::SelectFileDialog::SELECT_OPEN_FILE, -+ std::u16string(), -+ export_path_, -+ &file_type_info, -+ 0, -+ base::FilePath::StringType(), -+ window -+ ); -+} -+ -+void BookmarkBridge::ExportBookmarks(JNIEnv* env, -+ const JavaParamRef& obj, -+ const JavaParamRef& java_window, -+ const JavaParamRef& j_export_path) { -+ DCHECK(IsLoaded()); -+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); -+ -+ ui::WindowAndroid* window = -+ ui::WindowAndroid::FromJavaWindowAndroid(java_window); -+ CHECK(window); -+ -+ std::u16string export_path = -+ base::android::ConvertJavaStringToUTF16(env, j_export_path); -+ -+ export_path_ = base::FilePath::FromUTF16Unsafe(export_path); -+ -+ if (export_path_.empty()) { -+ if (!base::android::GetDownloadsDirectory(&export_path_)) { -+ LOG(ERROR) << "Could not retrieve downloads directory for bookmarks export"; -+ return; -+ } -+ export_path_ = export_path_.Append(FILE_PATH_LITERAL("bookmarks.html")); -+ } -+ -+ bookmark_html_writer::WriteBookmarks(profile_, export_path_, -+ base::BindOnce(&BookmarkBridge::ExportBookmarksEnd, -+ weak_ptr_factory_.GetWeakPtr(), -+ base::android::ScopedJavaGlobalRef(obj), -+ window)); -+} -+ -+void BookmarkBridge::ExportBookmarksEnd(const ScopedJavaGlobalRef& obj, -+ ui::WindowAndroid* window, -+ bookmark_html_writer::Result result) const -+{ -+ auto export_path = export_path_.MaybeAsASCII(); -+ if (result == bookmark_html_writer::Result::kSuccess) { -+ LOG(INFO) << "Bookmarks exported successfully to " << export_path; -+ } else if (result == bookmark_html_writer::Result::kCouldNotCreateFile) { -+ LOG(ERROR) << "Bookmarks export: could not create file " << export_path; -+ } else if (result == bookmark_html_writer::Result::kCouldNotWriteHeader) { -+ LOG(ERROR) << "Bookmarks export: could not write header"; -+ } else if (result == bookmark_html_writer::Result::kCouldNotWriteNodes) { -+ LOG(ERROR) << "Bookmarks export: could not write nodes"; -+ } -+ -+ JNIEnv* env = AttachCurrentThread(); -+ Java_BookmarkBridge_bookmarksExported(env, obj, window->GetJavaObject(), -+ base::android::ConvertUTF8ToJavaString(env, export_path), -+ result == bookmark_html_writer::Result::kSuccess); -+} -+ -+// Attempts to create a TemplateURL from the provided data. |title| is optional. -+// If TemplateURL creation fails, returns null. -+std::unique_ptr CreateTemplateURL(const std::u16string& url, -+ const std::u16string& keyword, -+ const std::u16string& title) { -+ if (url.empty() || keyword.empty()) -+ return nullptr; -+ TemplateURLData data; -+ data.SetKeyword(keyword); -+ // We set short name by using the title if it exists. -+ // Otherwise, we use the shortcut. -+ data.SetShortName(title.empty() ? keyword : title); -+ data.SetURL(TemplateURLRef::DisplayURLToURLRef(url)); -+ return std::make_unique(data); -+} -+ -+void BookmarkBridge::FileSelected(const ui::SelectedFileInfo& file, int index) { -+ base::FilePath path = file.path(); -+ base::ThreadPool::PostTaskAndReplyWithResult( -+ FROM_HERE, {base::TaskPriority::BEST_EFFORT, base::MayBlock()}, -+ base::BindOnce(&BookmarkBridge::FileSelectedImpl, -+ base::Unretained(this), -+ path), -+ base::BindOnce(&BookmarkBridge::FileSelectedImplOnUIThread, -+ base::Unretained(this), -+ path)); -+} -+ -+const std::string BookmarkBridge::FileSelectedImpl(const base::FilePath& path) { -+ base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ); -+ if (!file.IsValid()) { -+ select_file_dialog_->ShowToast("Cannot open bookmarks file for import"); -+ return ""; -+ } -+ -+ auto fileLength = file.GetLength(); -+ if (-1 == fileLength) { -+ select_file_dialog_->ShowToast("Cannot read bookmarks file length"); -+ return ""; -+ } -+ -+ if (fileLength > 10 * 1024 * 1024) { -+ select_file_dialog_->ShowToast("Bookmark file is bigger than 10MB"); -+ return ""; -+ } -+ -+ std::vector buffer(fileLength); -+ if (-1 == file.ReadAtCurrentPos(buffer.data(), fileLength)) { -+ select_file_dialog_->ShowToast("Could not read bookmarks file"); -+ return ""; -+ } -+ -+ if (buffer.empty()) { -+ select_file_dialog_->ShowToast("Empty bookmarks file"); -+ return ""; -+ } -+ -+ std::string contents(buffer.begin(), buffer.end()); -+ return contents; -+} -+ -+void BookmarkBridge::FileSelectedImplOnUIThread(const base::FilePath& path, -+ const std::string& contents) { -+ if (contents.empty()) -+ return; -+ -+ // the following import logic comes from BookmarksFileImporter class -+ user_data_importer::BookmarkParser::ParsedBookmarks parsed_bookmarks = -+ user_data_importer::ParseBookmarksUnsafe(contents); -+ -+ auto *writer = new ProfileWriter(profile_); -+ -+ if (!parsed_bookmarks.bookmarks.empty()) { -+ // adding bookmarks will begin extensive changes to the model -+ writer->AddBookmarksWithModel(bookmark_model_, parsed_bookmarks.bookmarks, u"Imported"); -+ } -+ -+ std::stringstream message; -+ message << "Imported " << parsed_bookmarks.bookmarks.size() << " bookmarks " << -+ " from " << path.MaybeAsASCII(); -+ auto result = message.str(); -+ -+ select_file_dialog_->ShowToast(result); -+ -+ LOG(INFO) << result; -+} -+ -+void BookmarkBridge::FileSelectionCanceled() {} -+ - void BookmarkBridge::SetBookmarkTitle(JNIEnv* env, - jlong id, - jint type, -diff --git a/chrome/browser/bookmarks/android/bookmark_bridge.h b/chrome/browser/bookmarks/android/bookmark_bridge.h ---- a/chrome/browser/bookmarks/android/bookmark_bridge.h -+++ b/chrome/browser/bookmarks/android/bookmark_bridge.h -@@ -20,6 +20,7 @@ - #include "base/strings/utf_string_conversions.h" - #include "base/supports_user_data.h" - #include "chrome/browser/partnerbookmarks/partner_bookmarks_shim.h" -+#include "chrome/browser/bookmarks/bookmark_html_writer.h" - #include "chrome/browser/profiles/profile.h" - #include "chrome/browser/profiles/profile_observer.h" - #include "chrome/browser/reading_list/android/reading_list_manager.h" -@@ -37,6 +38,9 @@ - #include "components/signin/public/identity_manager/identity_manager.h" - #include "url/android/gurl_android.h" - -+#include "components/search_engines/template_url.h" -+#include "ui/shell_dialogs/select_file_dialog.h" -+ - class BookmarkBridgeTest; - - // Values for a bitmask used to refer to a collection of bookmark nodes. -@@ -77,7 +81,8 @@ class BookmarkBridge : public ProfileObserver, - public ReadingListManager::Observer, - public ReadingListModelObserver, - public signin::IdentityManager::Observer, -- public base::SupportsUserData::Data { -+ public base::SupportsUserData::Data, -+ public ui::SelectFileDialog::Listener { - public: - // All of the injected pointers must be non-null and must outlive `this`. - BookmarkBridge(Profile* profile, -@@ -108,6 +113,11 @@ class BookmarkBridge : public ProfileObserver, - - bool IsDoingExtensiveChanges(JNIEnv* env); - -+ // SelectFileDialog::Listener implementation. -+ void FileSelected(const ui::SelectedFileInfo& file, -+ int index) override; -+ void FileSelectionCanceled() override; -+ - jboolean IsEditBookmarksEnabled(JNIEnv* env); - - void LoadEmptyPartnerBookmarkShimForTesting(JNIEnv* env); -@@ -120,6 +130,17 @@ class BookmarkBridge : public ProfileObserver, - jlong id, - jint type); - -+ void ImportBookmarks(JNIEnv* env, -+ const base::android::JavaParamRef& obj, -+ const base::android::JavaParamRef& java_window); -+ -+ void ExportBookmarks(JNIEnv* env, -+ const base::android::JavaParamRef& obj, -+ const base::android::JavaParamRef& java_window, -+ const base::android::JavaParamRef& j_export_path); -+ void ExportBookmarksEnd(const base::android::ScopedJavaGlobalRef& obj, -+ ui::WindowAndroid* window, bookmark_html_writer::Result result) const; -+ - void GetAllFoldersWithDepths( - JNIEnv* env, - const base::android::JavaParamRef& j_folders_obj, -@@ -385,6 +406,8 @@ class BookmarkBridge : public ProfileObserver, - void CreateOrDestroyAccountReadingListManagerIfNeeded(); - - const raw_ptr profile_; // weak -+ base::FilePath export_path_; -+ - base::android::ScopedJavaGlobalRef java_bookmark_model_; - const raw_ptr bookmark_model_; // weak - const raw_ptr -@@ -399,6 +422,7 @@ class BookmarkBridge : public ProfileObserver, - std::unique_ptr - grouped_bookmark_actions_; - PrefChangeRegistrar pref_change_registrar_; -+ scoped_refptr select_file_dialog_; - - // Information about the Partner bookmarks (must check for IsLoaded()). - // This is owned by profile. -@@ -432,6 +456,10 @@ class BookmarkBridge : public ProfileObserver, - base::TimeTicks load_start_time_; - bool loading_notification_sent_ = false; - -+ const std::string FileSelectedImpl(const base::FilePath& path); -+ void FileSelectedImplOnUIThread(const base::FilePath& path, -+ const std::string& contents); -+ - // Weak pointers for creating callbacks that won't call into a destroyed - // object. - base::WeakPtrFactory weak_ptr_factory_; -diff --git a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java ---- a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java -+++ b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java -@@ -36,6 +36,9 @@ import org.chromium.url.GURL; - import java.util.ArrayList; - import java.util.List; - -+import org.chromium.ui.base.WindowAndroid; -+import java.util.function.BiConsumer; -+ - /** - * Provides the communication channel for Android to fetch and manipulate the bookmark model stored - * in native. -@@ -53,6 +56,9 @@ class BookmarkBridge { - private boolean mIsNativeBookmarkModelLoaded; - private boolean mInitializedPartnerBookmarks; - -+ private static final BiConsumer NOOP = (success, bookmarksPath) -> {}; -+ private BiConsumer mOnExportedFunction = NOOP; -+ - // Lazily set pseudo-constants. These should never change at runtime. Used to avoid crossing - // JNI to fetch information. - private @Nullable BookmarkId mRootFolderId; -@@ -500,6 +506,35 @@ class BookmarkBridge { - .getTotalBookmarkCount(mNativeBookmarkBridge, id.getId(), id.getType()); - } - -+ /** -+ * Import bookmarks from a selected file. -+ * @param window The current window of the bookmarks activity or page. -+ */ -+ public void importBookmarks(WindowAndroid window) { -+ assert mIsNativeBookmarkModelLoaded; -+ BookmarkBridgeJni.get().importBookmarks(mNativeBookmarkBridge, -+ BookmarkBridge.this, window); -+ } -+ -+ /** -+ * Export bookmarks to a path selected by the user. -+ * @param window The current window of the bookmarks activity or page. -+ */ -+ public void exportBookmarks(WindowAndroid window, String exportPath, -+ BiConsumer onExportedFunction) { -+ assert mIsNativeBookmarkModelLoaded; -+ mOnExportedFunction = onExportedFunction; -+ BookmarkBridgeJni.get().exportBookmarks(mNativeBookmarkBridge, -+ BookmarkBridge.this, window, exportPath); -+ } -+ -+ @CalledByNative -+ public void bookmarksExported(WindowAndroid window, String bookmarksPath, boolean success) { -+ BiConsumer action = mOnExportedFunction -+ .andThen((x, y) -> mOnExportedFunction = NOOP); -+ action.accept(success, bookmarksPath); -+ } -+ - /** - * Synchronously gets a list of bookmarks that match the specified search query. - * -@@ -1108,6 +1143,10 @@ class BookmarkBridge { - void getChildIds( - long nativeBookmarkBridge, long id, int type, List bookmarksList); - -+ void importBookmarks(long nativeBookmarkBridge, BookmarkBridge caller, WindowAndroid window); -+ void exportBookmarks(long nativeBookmarkBridge, BookmarkBridge caller, WindowAndroid window, -+ String export_path); -+ - BookmarkId getChildAt(long nativeBookmarkBridge, long id, int type, int index); - - int getTotalBookmarkCount(long nativeBookmarkBridge, long id, int type); -diff --git a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkDelegate.java b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkDelegate.java ---- a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkDelegate.java -+++ b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkDelegate.java -@@ -67,6 +67,16 @@ public interface BookmarkDelegate { - /** Shows the search UI. */ - void openSearchUi(); - -+ /** -+ * Imports bookmarks from user-selected file. -+ */ -+ void importBookmarks(); -+ -+ /** -+ * Exports bookmarks to downloads directory. -+ */ -+ void exportBookmarks(); -+ - /** Add an observer to bookmark UI changes. */ - void addUiObserver(BookmarkUiObserver observer); - -diff --git a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java ---- a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java -+++ b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerCoordinator.java -@@ -57,6 +57,8 @@ import org.chromium.components.image_fetcher.ImageFetcherConfig; - import org.chromium.components.image_fetcher.ImageFetcherFactory; - import org.chromium.ui.KeyboardVisibilityDelegate; - import org.chromium.ui.edge_to_edge.EdgeToEdgePadAdjuster; -+import org.chromium.ui.base.ActivityWindowAndroid; -+import org.chromium.ui.modaldialog.ModalDialogManager; - import org.chromium.ui.modaldialog.ModalDialogManager; - import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogType; - import org.chromium.ui.modelutil.MVCListAdapter.ListItem; -@@ -344,6 +346,13 @@ public class BookmarkManagerCoordinator - - // Public API implementation. - -+ /** -+ * Sets the Android window that is used by further intents created by the bookmark activity. -+ */ -+ public void setWindow(ActivityWindowAndroid window, ModalDialogManager modalDialogManager) { -+ mMediator.setWindow(window, modalDialogManager); -+ } -+ - /** Destroys and cleans up itself. This must be called after done using this class. */ - public void onDestroyed() { - RecordUserAction.record("MobileBookmarkManagerClose"); -diff --git a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java ---- a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java -+++ b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManagerMediator.java -@@ -63,6 +63,8 @@ import org.chromium.components.commerce.core.SubscriptionsObserver; - import org.chromium.components.embedder_support.util.UrlConstants; - import org.chromium.components.power_bookmarks.PowerBookmarkMeta; - import org.chromium.components.power_bookmarks.PowerBookmarkType; -+import org.chromium.ui.base.ActivityWindowAndroid; -+import org.chromium.ui.modaldialog.ModalDialogManager; - import org.chromium.ui.accessibility.AccessibilityState; - import org.chromium.ui.base.DeviceFormFactor; - import org.chromium.ui.base.DeviceInput; -@@ -84,6 +86,47 @@ import java.util.function.BooleanSupplier; - import java.util.function.Consumer; - import java.util.function.Predicate; - -+import android.content.Intent; -+import android.content.pm.PackageManager; -+import android.content.DialogInterface; -+import android.content.res.Resources; -+import android.content.ContentResolver; -+import android.net.Uri; -+import android.provider.Browser; -+import android.provider.DocumentsContract; -+import android.Manifest.permission; -+import android.view.View; -+import android.view.LayoutInflater; -+ -+import androidx.appcompat.app.AlertDialog; -+import android.os.Build; -+ -+import java.io.File; -+ -+import org.chromium.base.ContextUtils; -+import org.chromium.base.ContentUriUtils; -+import org.chromium.base.shared_preferences.SharedPreferencesManager; -+import org.chromium.base.task.AsyncTask; -+import org.chromium.chrome.R; -+import org.chromium.chrome.browser.document.ChromeLauncherActivity; -+import org.chromium.chrome.browser.IntentHandler; -+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; -+import org.chromium.chrome.browser.download.DownloadLocationDialogType; -+import org.chromium.chrome.browser.download.settings.DownloadLocationHelperImpl; -+import org.chromium.chrome.browser.download.dialogs.DownloadLocationDialogController; -+import org.chromium.chrome.browser.download.dialogs.DownloadLocationDialogCoordinator; -+import org.chromium.chrome.browser.download.dialogs.DownloadLocationCustomView; -+import org.chromium.chrome.browser.download.DirectoryOption; -+import org.chromium.chrome.browser.profiles.ProfileManager; -+import org.chromium.chrome.browser.preferences.ChromeSharedPreferences; -+import org.chromium.chrome.browser.flags.ChromeFeatureList; -+import org.chromium.ui.base.PageTransition; -+import org.chromium.ui.base.WindowAndroid; -+import org.chromium.ui.modelutil.PropertyModel; -+import org.chromium.ui.modaldialog.ModalDialogManager; -+import org.chromium.ui.modaldialog.ModalDialogProperties; -+import org.chromium.ui.modaldialog.DialogDismissalCause; -+ - /** Responsible for BookmarkManager business logic. */ - // TODO(crbug.com/40256938): Remove BookmarkDelegate if possible. - @NullMarked -@@ -94,6 +137,9 @@ class BookmarkManagerMediator - - private static boolean sPreventLoadingForTesting; - -+ private ActivityWindowAndroid mWindowAndroid; -+ private ModalDialogManager mModalDialogManager; -+ - /** Keeps track of whether drag is enabled / active for bookmark lists. */ - private class BookmarkDragStateDelegate implements DragStateDelegate { - private BookmarkDelegate mBookmarkDelegate; -@@ -655,6 +701,14 @@ class BookmarkManagerMediator - mNativePage = nativePage; - } - -+ /** -+ * Sets the Android window that is used by further intents created by the bookmark activity. -+ */ -+ public void setWindow(ActivityWindowAndroid window, ModalDialogManager modalDialogManager) { -+ mWindowAndroid = window; -+ mModalDialogManager = modalDialogManager; -+ } -+ - /** See BookmarkManager(Coordinator)#updateForUrl */ - void updateForUrl(String url) { - // Bookmark model is null if the manager has been destroyed. -@@ -827,6 +881,235 @@ class BookmarkManagerMediator - } - } - -+ @Override -+ public void importBookmarks() { -+ mBookmarkModel.importBookmarks(mWindowAndroid); -+ } -+ -+ @Override -+ public void exportBookmarks() { -+ if (ChromeFeatureList.isEnabled(ChromeFeatureList.BOOKMARKS_EXPORT_USESAF) || -+ Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) { -+ exportBookmarksImplUseSaf(); -+ } else { -+ exportBookmarksImplUseFile(); -+ } -+ } -+ -+ private void exportBookmarksImplUseSaf() { -+ Context context = mWindowAndroid.getContext().get(); -+ -+ // standard name for boorkmark file -+ final String standardBoorkmarkName = "bookmarks.html"; -+ -+ // use the fileSelector and saf asking user for the file -+ Intent fileSelector = new Intent(Intent.ACTION_CREATE_DOCUMENT); -+ fileSelector.addCategory(Intent.CATEGORY_OPENABLE); -+ fileSelector.setType("text/html"); -+ fileSelector.putExtra(Intent.EXTRA_TITLE, standardBoorkmarkName); -+ fileSelector.setFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | -+ Intent.FLAG_GRANT_READ_URI_PERMISSION | -+ Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); -+ -+ // get last exported uri path, if any -+ SharedPreferencesManager sharedPrefs = ChromeSharedPreferences.getInstance(); -+ String bookmarksPath = sharedPrefs.readString(ChromePreferenceKeys.BOOKMARKS_LAST_EXPORT_URI, standardBoorkmarkName); -+ Uri lastSelectedUri = Uri.parse(bookmarksPath); -+ -+ // prepare delegate for file selector -+ DialogInterface.OnClickListener onClickListener = new DialogInterface.OnClickListener() { -+ @Override -+ public void onClick(DialogInterface dialog, int button) { -+ if (button == AlertDialog.BUTTON_NEGATIVE) { -+ mWindowAndroid.showIntent(fileSelector, -+ new WindowAndroid.IntentCallback() { -+ @Override -+ public void onIntentCompleted(int resultCode, Intent data) { -+ if (data == null) return; -+ Uri filePath = data.getData(); -+ doExportBookmarksImpl(filePath); -+ } -+ }, -+ null); -+ } else { -+ if (dialog!=null) dialog.dismiss(); -+ doExportBookmarksImpl(lastSelectedUri); -+ } -+ } -+ }; -+ -+ // as a workaround for https://issuetracker.google.com/issues/37136466 -+ // ask to overwrite if is a valid uri and the file is present -+ if (DocumentsContract.isDocumentUri(context, lastSelectedUri)) { -+ AsyncTask checkUriTask = new AsyncTask() { -+ boolean uriExists = false; -+ String actualFilePath = null; -+ -+ @Override -+ protected Void doInBackground() { -+ uriExists = ContentUriUtils.contentUriExists(lastSelectedUri.toString()); -+ if (uriExists) { -+ actualFilePath = ContentUriUtils.getFilePathFromContentUri(lastSelectedUri); -+ // get real actual file name on disk -+ if (actualFilePath==null) actualFilePath = lastSelectedUri.toString(); -+ // set file name to last exported file name -+ fileSelector.putExtra(Intent.EXTRA_TITLE, -+ ContentUriUtils.getDisplayName(lastSelectedUri, context, -+ DocumentsContract.Document.COLUMN_DISPLAY_NAME)); -+ } -+ return null; -+ } -+ -+ @Override -+ protected void onPostExecute(Void result) { -+ // check for permissions -+ if (uriExists) { -+ AlertDialog.Builder alert = -+ new AlertDialog.Builder(context, R.style.ThemeOverlay_BrowserUI_AlertDialog); -+ AlertDialog alertDialog = -+ alert.setTitle(R.string.export_bookmarks_alert_title) -+ .setMessage(context.getString(R.string.export_bookmarks_alert_message, actualFilePath)) -+ .setPositiveButton( -+ R.string.export_bookmarks_alert_message_yes, onClickListener) -+ .setNegativeButton(R.string.export_bookmarks_alert_message_no, onClickListener) -+ .create(); -+ alertDialog.getDelegate().setHandleNativeActionModesEnabled(false); -+ -+ // show dialog asking for overwrite -+ alertDialog.show(); -+ return; -+ } else { -+ onClickListener.onClick(null, AlertDialog.BUTTON_NEGATIVE); -+ } -+ } -+ }; -+ checkUriTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); -+ return; -+ } -+ -+ // actually open the file selector -+ onClickListener.onClick(null, AlertDialog.BUTTON_NEGATIVE); -+ } -+ -+ private void exportBookmarksImplUseFile() { -+ Context context = mWindowAndroid.getContext().get(); -+ -+ // standard name for boorkmark file -+ final String standardBoorkmarkName = "bookmarks.html"; -+ -+ // use the download ui and standard file saving -+ DownloadLocationDialogController controller = new DownloadLocationDialogController() { -+ @Override -+ public void onDownloadLocationDialogComplete(String returnedPath, boolean didUserConfirm) {} -+ -+ @Override -+ public void onDownloadLocationDialogCanceled() {} -+ }; -+ -+ DownloadLocationDialogCoordinator dialog = new DownloadLocationDialogCoordinator() { -+ @Override -+ protected void onDirectoryOptionsRetrieved(ArrayList dirs) { -+ if (mDialogModel != null) return; -+ -+ // Actually show the dialog. -+ mCustomView = (DownloadLocationCustomView) LayoutInflater.from(context).inflate( -+ R.layout.download_location_dialog, null); -+ mCustomView.initialize(DownloadLocationDialogType.DEFAULT, /*totalBytes*/ 0, -+ (isChecked) -> {}, -+ new DownloadLocationHelperImpl(mProfile)); -+ mCustomView.setTitle(context.getString(R.string.export_bookmarks_alert_title)); -+ mCustomView.setFileName(standardBoorkmarkName); -+ mCustomView.mDontShowAgain.setVisibility(View.GONE); -+ -+ Resources resources = context.getResources(); -+ mDialogModel = new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS) -+ .with(ModalDialogProperties.CONTROLLER, this) -+ .with(ModalDialogProperties.CUSTOM_VIEW, mCustomView) -+ .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, resources, -+ R.string.export_bookmarks) -+ .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT, resources, -+ R.string.cancel) -+ .build(); -+ -+ mModalDialogManager.showDialog(mDialogModel, ModalDialogManager.ModalDialogType.APP); -+ } -+ -+ @Override -+ public void onDismiss(PropertyModel model, int dismissalCause) { -+ switch (dismissalCause) { -+ case DialogDismissalCause.POSITIVE_BUTTON_CLICKED: -+ { -+ String fileName = mCustomView.getFileName(); -+ String directory = mCustomView.getDirectoryOption().location; -+ if (fileName != null && directory != null) { -+ File file = new File(directory, fileName); -+ -+ if (mWindowAndroid.hasPermission(permission.WRITE_EXTERNAL_STORAGE)) { -+ doExportBookmarksImpl(file.getPath()); -+ } else { -+ String[] requestPermissions = new String[] {permission.WRITE_EXTERNAL_STORAGE}; -+ mWindowAndroid.requestPermissions(requestPermissions, (permissions, grantResults) -> { -+ if (grantResults.length >= 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { -+ doExportBookmarksImpl(file.getPath()); -+ } -+ }); -+ }; -+ } -+ } -+ break; -+ } -+ mDialogModel = null; -+ mCustomView = null; -+ } -+ }; -+ dialog.initialize(controller); -+ dialog.showDialog(context, mModalDialogManager, /*totalBytes*/ 0, -+ DownloadLocationDialogType.DEFAULT, /*suggestedPath*/ "", -+ ProfileManager.getLastUsedRegularProfile()); -+ } -+ -+ private void doExportBookmarksImpl(Uri filePath) { -+ ContentResolver resolver = ContextUtils.getApplicationContext().getContentResolver(); -+ // since we want to persist the uri in settings, ask for persistable permissions -+ resolver.takePersistableUriPermission(filePath, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | -+ Intent.FLAG_GRANT_READ_URI_PERMISSION); -+ -+ doExportBookmarksImpl(filePath.toString()); -+ } -+ -+ private void doExportBookmarksImpl(String filePath) { -+ mBookmarkModel.exportBookmarks(mWindowAndroid, filePath, -+ (success, bookmarksPath) -> { -+ if (!success) { -+ ((Activity)mWindowAndroid.getContext().get()).runOnUiThread(new Runnable() { -+ public void run() { -+ mWindowAndroid.showError(R.string.saving_file_error); -+ } -+ }); -+ } else { -+ SharedPreferencesManager sharedPrefs = ChromeSharedPreferences.getInstance(); -+ sharedPrefs.writeString(ChromePreferenceKeys.BOOKMARKS_LAST_EXPORT_URI, bookmarksPath); -+ -+ Context context = ContextUtils.getApplicationContext(); -+ -+ Intent intent = new Intent(Intent.ACTION_VIEW, -+ ContentUriUtils.isContentUri(bookmarksPath) ? -+ Uri.parse(bookmarksPath) : Uri.parse("file://" + bookmarksPath)); -+ intent.putExtra(Browser.EXTRA_APPLICATION_ID, -+ context.getPackageName()); -+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); -+ intent.putExtra(IntentHandler.EXTRA_PAGE_TRANSITION_TYPE, PageTransition.AUTO_BOOKMARK); -+ -+ // If the bookmark manager is shown in a tab on a phone (rather than in a separate -+ // activity) the component name may be null. Send the intent through -+ // ChromeLauncherActivity instead to avoid crashing. See crbug.com/615012. -+ intent.setClass(context, ChromeLauncherActivity.class); -+ -+ IntentHandler.startActivityForTrustedIntent(intent); -+ } -+ }); -+ } -+ - @Override - public void openSearchUi() { - onSearchTextChangeCallback(""); -diff --git a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPage.java b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPage.java ---- a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPage.java -+++ b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPage.java -@@ -16,6 +16,9 @@ import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; - 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; -+import org.chromium.chrome.browser.app.ChromeActivity; -+import org.chromium.ui.modaldialog.ModalDialogManager; -+import org.chromium.components.browser_ui.modaldialog.AppModalPresenter; - - /** A native page holding a {@link BookmarkManagerCoordinator} on _tablet_. */ - @NullMarked -@@ -37,7 +40,8 @@ public class BookmarkPage extends BasicNativePage { - Profile profile, - NativePageHost host, - @Nullable ComponentName componentName, -- BackPressManager backPressManager) { -+ BackPressManager backPressManager, -+ ChromeActivity activity) { - super(host); - - mTitle = host.getContext().getString(R.string.bookmarks); -@@ -65,6 +69,9 @@ public class BookmarkPage extends BasicNativePage { - backPressManager); - - mBookmarkManagerCoordinator.setBasicNativePage(this); -+ mBookmarkManagerCoordinator.setWindow(activity.getWindowAndroid(), -+ new ModalDialogManager( -+ new AppModalPresenter(activity), ModalDialogManager.ModalDialogType.APP)); - initWithView(mBookmarkManagerCoordinator.getView()); - } - -diff --git a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbar.java b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbar.java ---- a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbar.java -+++ b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbar.java -@@ -102,6 +102,17 @@ public class BookmarkToolbar extends SelectableListToolbar - setOnMenuItemClickListener(dragEnabled ? null : this); - } - -+ private Runnable mImportBookmarkRunnable; -+ private Runnable mExportBookmarkRunnable; -+ -+ void setImportBookmarkRunnable(Runnable runnable) { -+ mImportBookmarkRunnable = runnable; -+ } -+ -+ void setExportBookmarkRunnable(Runnable runnable) { -+ mExportBookmarkRunnable = runnable; -+ } -+ - void setEditButtonVisible(boolean visible) { - mEditButtonVisible = visible; - getMenu().findItem(R.id.edit_menu_id).setVisible(visible); -@@ -178,6 +189,12 @@ public class BookmarkToolbar extends SelectableListToolbar - - void setCurrentFolder(BookmarkId folder) { - mCurrentFolder = mBookmarkModel.getBookmarkById(folder); -+ enableImportExportMenu(); -+ } -+ -+ void enableImportExportMenu() { -+ getMenu().findItem(R.id.import_menu_id).setVisible(true); -+ getMenu().findItem(R.id.export_menu_id).setVisible(true); - } - - void setNavigateBackRunnable(Runnable navigateBackRunnable) { -@@ -202,6 +219,13 @@ public class BookmarkToolbar extends SelectableListToolbar - @Override - public boolean onMenuItemClick(MenuItem menuItem) { - hideOverflowMenu(); -+ if (menuItem.getItemId() == R.id.import_menu_id) { -+ mImportBookmarkRunnable.run(); -+ return true; -+ } else if (menuItem.getItemId() == R.id.export_menu_id) { -+ mExportBookmarkRunnable.run(); -+ return true; -+ } - return assumeNonNull(mMenuIdClickedFunction).apply(menuItem.getItemId()); - } - -@@ -222,6 +246,9 @@ public class BookmarkToolbar extends SelectableListToolbar - protected void showNormalView() { - super.showNormalView(); - -+ getMenu().findItem(R.id.import_menu_id).setVisible(mCurrentFolder != null); -+ getMenu().findItem(R.id.export_menu_id).setVisible(mCurrentFolder != null); -+ - // SelectableListToolbar will show/hide the entire group. - setEditButtonVisible(mEditButtonVisible); - setNewFolderButtonVisible(mNewFolderButtonVisible); -diff --git a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarMediator.java b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarMediator.java ---- a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarMediator.java -+++ b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarMediator.java -@@ -139,6 +139,10 @@ class BookmarkToolbarMediator - mBookmarkDelegate = bookmarkDelegate; - mModel.set( - BookmarkToolbarProperties.NAVIGATE_BACK_RUNNABLE, this::onNavigateBack); -+ mModel.set( -+ BookmarkToolbarProperties.IMPORT_BOOKMARK_RUNNABLE, mBookmarkDelegate::importBookmarks); -+ mModel.set( -+ BookmarkToolbarProperties.EXPORT_BOOKMARK_RUNNABLE, mBookmarkDelegate::exportBookmarks); - mBookmarkDelegate.addUiObserver(this); - mBookmarkDelegate.notifyStateChange(this); - }); -diff --git a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarProperties.java b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarProperties.java ---- a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarProperties.java -+++ b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarProperties.java -@@ -86,6 +86,10 @@ class BookmarkToolbarProperties { - - static final WritableObjectPropertyKey NEXT_FOCUSABLE_VIEW = - new WritableObjectPropertyKey<>(); -+ static final WritableObjectPropertyKey IMPORT_BOOKMARK_RUNNABLE = -+ new WritableObjectPropertyKey<>(); -+ static final WritableObjectPropertyKey EXPORT_BOOKMARK_RUNNABLE = -+ new WritableObjectPropertyKey<>(); - - static final PropertyKey[] ALL_KEYS = { - SELECTION_DELEGATE, -@@ -114,6 +118,8 @@ class BookmarkToolbarProperties { - SELECTION_MODE_SHOW_MOVE, - SELECTION_MODE_SHOW_MARK_READ, - SELECTION_MODE_SHOW_MARK_UNREAD, -- NEXT_FOCUSABLE_VIEW -+ NEXT_FOCUSABLE_VIEW, -+ IMPORT_BOOKMARK_RUNNABLE, -+ EXPORT_BOOKMARK_RUNNABLE - }; - } -diff --git a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarViewBinder.java b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarViewBinder.java ---- a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarViewBinder.java -+++ b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarViewBinder.java -@@ -56,6 +56,12 @@ class BookmarkToolbarViewBinder { - model.get(BookmarkToolbarProperties.CHECKED_VIEW_MENU_ID)); - } else if (key == BookmarkToolbarProperties.CURRENT_FOLDER) { - bookmarkToolbar.setCurrentFolder(model.get(BookmarkToolbarProperties.CURRENT_FOLDER)); -+ } else if (key == BookmarkToolbarProperties.IMPORT_BOOKMARK_RUNNABLE) { -+ bookmarkToolbar.setImportBookmarkRunnable( -+ model.get(BookmarkToolbarProperties.IMPORT_BOOKMARK_RUNNABLE)); -+ } else if (key == BookmarkToolbarProperties.EXPORT_BOOKMARK_RUNNABLE) { -+ bookmarkToolbar.setExportBookmarkRunnable( -+ model.get(BookmarkToolbarProperties.EXPORT_BOOKMARK_RUNNABLE)); - } else if (key == BookmarkToolbarProperties.NAVIGATE_BACK_RUNNABLE) { - bookmarkToolbar.setNavigateBackRunnable( - model.get(BookmarkToolbarProperties.NAVIGATE_BACK_RUNNABLE)); -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 -@@ -50,7 +50,7 @@ public class DownloadLocationCustomView extends ScrollView - private TextView mFileSize; - private Spinner mFileLocation; - private TextView mLocationAvailableSpace; -- private CheckBox mDontShowAgain; -+ public CheckBox mDontShowAgain; - private @DownloadLocationDialogType int mDialogType; - private long mTotalBytes; - private @Nullable Callback mOnClickedCallback; -@@ -75,7 +75,7 @@ public class DownloadLocationCustomView extends ScrollView - mDontShowAgain = findViewById(R.id.show_again_checkbox); - } - -- void initialize( -+ public void initialize( - @DownloadLocationDialogType int dialogType, - long totalBytes, - Callback onClickedCallback, -@@ -133,7 +133,7 @@ public class DownloadLocationCustomView extends ScrollView - /** - * @return The text that the user inputted as the name of the file. - */ -- @Nullable String getFileName() { -+ @Nullable public String getFileName() { - if (mFileName == null || mFileName.getText() == null) return null; - return mFileName.getText().toString(); - } -@@ -141,7 +141,7 @@ public class DownloadLocationCustomView extends ScrollView - /** - * @return The file path based on what the user selected as the location of the file. - */ -- @Nullable DirectoryOption getDirectoryOption() { -+ @Nullable public DirectoryOption getDirectoryOption() { - if (mFileLocation == null) return null; - DirectoryOption selected = (DirectoryOption) mFileLocation.getSelectedItem(); - return selected; -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 -@@ -43,13 +43,13 @@ import java.util.ArrayList; - @NullMarked - public class DownloadLocationDialogCoordinator implements ModalDialogProperties.Controller { - private DownloadLocationDialogController mController; -- private @Nullable PropertyModel mDialogModel; -+ protected @Nullable PropertyModel mDialogModel; - private @Nullable PropertyModel mDownloadLocationDialogModel; - private @Nullable - PropertyModelChangeProcessor - mPropertyModelChangeProcessor; -- private @Nullable DownloadLocationCustomView mCustomView; -- private @Nullable ModalDialogManager mModalDialogManager; -+ protected @Nullable DownloadLocationCustomView mCustomView; -+ protected @Nullable ModalDialogManager mModalDialogManager; - - private long mTotalBytes; - private @DownloadLocationDialogType int mDialogType; -@@ -57,7 +57,7 @@ public class DownloadLocationDialogCoordinator implements ModalDialogProperties. - private @Nullable Context mContext; - - private boolean mHasMultipleDownloadLocations; -- private @Nullable Profile mProfile; -+ protected @Nullable Profile mProfile; - - private boolean mLocationDialogManaged; - -@@ -154,7 +154,7 @@ public class DownloadLocationDialogCoordinator implements ModalDialogProperties. - * Called after retrieved the download directory options. - * @param dirs An list of available download directories. - */ -- private void onDirectoryOptionsRetrieved(ArrayList dirs) { -+ protected void onDirectoryOptionsRetrieved(ArrayList dirs) { - assertNonNull(mContext); - assertNonNull(mModalDialogManager); - assertNonNull(mSuggestedPath); -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 -@@ -255,6 +255,7 @@ const base::Feature* const kFeaturesExposedToJava[] = { - &kBatchTabRestore, - &kBlockIntentsWhileLocked, - &kBookmarkPaneAndroid, -+ &kBookmarksExportUseSaf, - &kBrowserControlsDebugging, - &kBrowserControlsEarlyResize, - &kCacheActivityTaskID, -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 -@@ -712,6 +712,7 @@ public abstract class ChromeFeatureList { - public static final String USE_LIBUNWINDSTACK_NATIVE_UNWINDER_ANDROID = - "UseLibunwindstackNativeUnwinderAndroid"; - public static final String VISITED_URL_RANKING_SERVICE = "VisitedURLRankingService"; -+ public static final String BOOKMARKS_EXPORT_USESAF = "BookmarksExportUseSaf"; - public static final String WEB_APK_BACKUP_AND_RESTORE_BACKEND = "WebApkBackupAndRestoreBackend"; - public static final String WEB_APK_INSTALL_FAILURE_NOTIFICATION = - "WebApkInstallFailureNotification"; -diff --git a/chrome/browser/importer/profile_writer.cc b/chrome/browser/importer/profile_writer.cc ---- a/chrome/browser/importer/profile_writer.cc -+++ b/chrome/browser/importer/profile_writer.cc -@@ -126,6 +126,16 @@ void ProfileWriter::AddBookmarks( - return; - - BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(profile_); -+ AddBookmarksWithModel(model, bookmarks, top_level_folder_name); -+} -+ -+void ProfileWriter::AddBookmarksWithModel( -+ BookmarkModel* model, -+ const std::vector& bookmarks, -+ const std::u16string& top_level_folder_name) { -+ if (bookmarks.empty()) -+ return; -+ - DCHECK(model->loaded()); - - // If the bookmark bar is currently empty, we should import directly to it. -diff --git a/chrome/browser/importer/profile_writer.h b/chrome/browser/importer/profile_writer.h ---- a/chrome/browser/importer/profile_writer.h -+++ b/chrome/browser/importer/profile_writer.h -@@ -11,6 +11,7 @@ - #include "base/memory/raw_ptr.h" - #include "base/memory/ref_counted.h" - #include "build/build_config.h" -+#include "components/bookmarks/browser/bookmark_model.h" - #include "components/favicon_base/favicon_usage_data.h" - #include "components/history/core/browser/history_types.h" - #include "components/search_engines/template_url_service.h" -@@ -75,6 +76,11 @@ class ProfileWriter : public base::RefCountedThreadSafe { - const std::vector& bookmarks, - const std::u16string& top_level_folder_name); - -+ virtual void AddBookmarksWithModel( -+ bookmarks::BookmarkModel* model, -+ const std::vector& bookmarks, -+ const std::u16string& top_level_folder_name); -+ - virtual void AddFavicons(const favicon_base::FaviconUsageDataList& favicons); - - // Adds the TemplateURLs in |template_urls| to the local store. -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 -@@ -140,6 +140,8 @@ public final class ChromePreferenceKeys { - "enhanced_bookmark_last_used_parent_folder"; - public static final String BOOKMARKS_SORT_ORDER = "Chrome.Bookmarks.BookmarkRowSortOrder"; - public static final String BOOKMARKS_VISUALS_PREF = "Chrome.Bookmarks.BookmarkRowDisplay"; -+ public static final String BOOKMARKS_LAST_EXPORT_URI = -+ "Chrome.Bookmarks.Last_Export_Uri"; - - /** Whether Chrome is set as the default browser. Default value is false. */ - public static final String CHROME_DEFAULT_BROWSER = "applink.chrome_default_browser"; -@@ -1067,6 +1069,7 @@ public final class ChromePreferenceKeys { - AUXILIARY_SEARCH_SCHEMA_VERSION, - APP_LAUNCH_LAST_KNOWN_ACTIVE_TAB_STATE, - APP_LAUNCH_SEARCH_ENGINE_HAD_LOGO, -+ BOOKMARKS_LAST_EXPORT_URI, - APPLICATION_OVERRIDE_LANGUAGE, - BLUETOOTH_NOTIFICATION_IDS, - BOOKMARKS_SORT_ORDER, -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 -@@ -252,6 +252,24 @@ CHAR_LIMIT guidelines: - - Sites - -+ -+ Import -+ -+ -+ Export -+ -+ -+ Export bookmarks to file -+ -+ -+ Do you want to overwrite %s? -+ -+ -+ Yes -+ -+ -+ Choose another file -+ - - Virtual Reality - -diff --git a/chrome/utility/BUILD.gn b/chrome/utility/BUILD.gn ---- a/chrome/utility/BUILD.gn -+++ b/chrome/utility/BUILD.gn -@@ -222,6 +222,13 @@ static_library("utility") { - deps += [ "//chrome/services/pdf:lib" ] - } - -+ if (is_android) { -+ sources += [ -+ "importer/bookmarks_file_importer.cc", -+ "importer/bookmarks_file_importer.h", -+ ] -+ } -+ - # NSS decryptor is not needed on ChromeOS. - if (!is_chromeos && use_nss_certs) { - sources += [ -diff --git a/chrome/utility/importer/bookmarks_file_importer.cc b/chrome/utility/importer/bookmarks_file_importer.cc ---- a/chrome/utility/importer/bookmarks_file_importer.cc -+++ b/chrome/utility/importer/bookmarks_file_importer.cc -@@ -103,8 +103,12 @@ void BookmarksFileImporter::StartImport( - user_data_importer::ParseBookmarksUnsafe(raw_html); - - if (!parsed_bookmarks.bookmarks.empty()) { -+#if BUILDFLAG(IS_ANDROID) -+ std::u16string first_folder_name; -+#else - std::u16string first_folder_name = - bridge_->GetLocalizedString(IDS_BOOKMARK_GROUP); -+#endif - std::erase_if(parsed_bookmarks.bookmarks, - [](user_data_importer::ImportedBookmarkEntry bookmark) { - return !internal::CanImportURL(bookmark.url); -diff --git a/components/headless/select_file_dialog/headless_select_file_dialog.cc b/components/headless/select_file_dialog/headless_select_file_dialog.cc ---- a/components/headless/select_file_dialog/headless_select_file_dialog.cc -+++ b/components/headless/select_file_dialog/headless_select_file_dialog.cc -@@ -57,6 +57,10 @@ class HeadlessSelectFileDialog : public ui::SelectFileDialog { - // ui::SelectFileDialog: - bool HasMultipleFileTypeChoicesImpl() override { return false; } - -+ void ShowToast(const std::string& message) override { -+ // nothing to do, used only on android -+ } -+ - SelectFileDialogCallback callback_; - }; - -diff --git a/components/user_data_importer/content/content_bookmark_parser_utils.cc b/components/user_data_importer/content/content_bookmark_parser_utils.cc ---- a/components/user_data_importer/content/content_bookmark_parser_utils.cc -+++ b/components/user_data_importer/content/content_bookmark_parser_utils.cc -@@ -138,6 +138,7 @@ std::optional GetBoolAttribute(std::string_view attribute_list, - - // Given the URL of a page and a favicon data URL, adds an appropriate record - // to the given favicon usage vector. -+[[maybe_unused]] - void DataURLToFaviconUsage(const GURL& link_url, - const GURL& favicon_data, - favicon_base::FaviconUsageDataList* favicons) { -@@ -495,9 +496,11 @@ BookmarkParser::ParsedBookmarks ParseBookmarksUnsafe( - } - parsing_result.bookmarks.push_back(std::move(entry)); - -+#if !BUILDFLAG(IS_ANDROID) - // Save the favicon. DataURLToFaviconUsage will handle the case where - // there is no favicon. - DataURLToFaviconUsage(url, favicon, &parsing_result.favicons); -+#endif - - continue; - } -diff --git a/cromite_flags/chrome/browser/about_flags_cc/add-bookmark-import-export-actions.inc b/cromite_flags/chrome/browser/about_flags_cc/add-bookmark-import-export-actions.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/chrome/browser/about_flags_cc/add-bookmark-import-export-actions.inc -@@ -0,0 +1,12 @@ -+#ifdef FLAG_SECTION -+ -+#if BUILDFLAG(IS_ANDROID) -+ {"export-bookmarks-use-saf", -+ "Use saf for bookmarks export", -+ "When enabled user can choose where save the exported bookmarks " -+ "file.", kOsAndroid, -+ FEATURE_VALUE_TYPE( -+ chrome::android::kBookmarksExportUseSaf)}, -+#endif -+ -+#endif -diff --git a/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/add-bookmark-import-export-actions.inc b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/add-bookmark-import-export-actions.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/add-bookmark-import-export-actions.inc -@@ -0,0 +1,4 @@ -+// disabled by default because of an issue on Android 6.0 -+CROMITE_FEATURE(kBookmarksExportUseSaf, -+ "BookmarksExportUseSaf", -+ base::FEATURE_DISABLED_BY_DEFAULT); -diff --git a/cromite_flags/chrome/browser/flags/android/chrome_feature_list_h/add-bookmark-import-export-actions.inc b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_h/add-bookmark-import-export-actions.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_h/add-bookmark-import-export-actions.inc -@@ -0,0 +1 @@ -+BASE_DECLARE_FEATURE(kBookmarksExportUseSaf); -diff --git a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java ---- a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java -+++ b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java -@@ -51,6 +51,7 @@ import org.chromium.build.annotations.Initializer; - import org.chromium.build.annotations.NullMarked; - import org.chromium.build.annotations.Nullable; - import org.chromium.ui.R; -+import org.chromium.ui.widget.Toast; - import org.chromium.ui.UiUtils; - - import java.io.File; -@@ -74,6 +75,7 @@ public class SelectFileDialog implements WindowAndroid.IntentCallback, PhotoPick - private static final String TAG = "SelectFileDialog"; - private static final String IMAGE_TYPE = "image"; - private static final String VIDEO_TYPE = "video"; -+ private static final String HTML_TYPE = "html"; - private static final String AUDIO_TYPE = "audio"; - private static final String ALL_TYPES = "*/*"; - private static final String GENERIC_TYPE = "application/octet-stream"; -@@ -323,6 +325,17 @@ public class SelectFileDialog implements WindowAndroid.IntentCallback, PhotoPick - mMimeTypes = convertToSupportedMimeTypes(mFileTypes); - } - -+ @CalledByNative -+ private void showToast(String message) { -+ ThreadUtils.runOnUiThread( -+ new Runnable() { -+ @Override -+ public void run() { -+ Toast.makeText(ContextUtils.getApplicationContext(), message, Toast.LENGTH_LONG).show(); -+ } -+ }); -+ } -+ - /** - * Creates and starts an intent based on the passed fileTypes and capture value. - * -@@ -407,7 +420,7 @@ public class SelectFileDialog implements WindowAndroid.IntentCallback, PhotoPick - List missingPermissions = new ArrayList<>(); - String storagePermission = Manifest.permission.READ_EXTERNAL_STORAGE; - boolean shouldUsePhotoPicker = shouldUsePhotoPicker(); -- if (shouldUsePhotoPicker) { -+ if (shouldUsePhotoPicker || shouldShowHtmlTypes()) { - // The permission scenario for accessing media has evolved a bit over the years: - // Early on, READ_EXTERNAL_STORAGE was required to access media, but that permission was - // later deprecated. In its place (starting with Android T) READ_MEDIA_IMAGES and -@@ -460,7 +473,7 @@ public class SelectFileDialog implements WindowAndroid.IntentCallback, PhotoPick - - // TODO(finnur): Remove once we figure out the cause of - // crbug.com/950024. -- if (shouldUsePhotoPicker) { -+ if (shouldUsePhotoPicker || shouldShowHtmlTypes()) { - if (permissions.length != requestPermissions.length) { - throw new RuntimeException( - String.format( -@@ -477,7 +490,7 @@ public class SelectFileDialog implements WindowAndroid.IntentCallback, PhotoPick - } - } - -- if (shouldUsePhotoPicker) { -+ if (shouldUsePhotoPicker || shouldShowHtmlTypes()) { - if (permissions[i].equals(storagePermission) - || permissions[i].equals( - Manifest.permission.READ_MEDIA_IMAGES) -@@ -783,6 +796,7 @@ public class SelectFileDialog implements WindowAndroid.IntentCallback, PhotoPick - mimeTypes.add(mimeType); - } - } -+ if (mimeTypes.size() == 0) return null; - return mimeTypes; - } - -@@ -1168,6 +1182,10 @@ public class SelectFileDialog implements WindowAndroid.IntentCallback, PhotoPick - return countAcceptTypesFor(superType) == mMimeTypes.size(); - } - -+ private boolean shouldShowHtmlTypes() { -+ return countAcceptTypesFor(HTML_TYPE) > 0; -+ } -+ - /** - * Checks whether the list of accepted types effectively describes only a single type, which - * might be wildcard. For example: -diff --git a/ui/android/java/strings/android_ui_strings.grd b/ui/android/java/strings/android_ui_strings.grd ---- a/ui/android/java/strings/android_ui_strings.grd -+++ b/ui/android/java/strings/android_ui_strings.grd -@@ -184,6 +184,9 @@ - - Unable to select media due to denied permissions - -+ -+ Failed to save selected file -+ - - - -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 -@@ -224,6 +224,8 @@ class SHELL_DIALOGS_EXPORT SelectFileDialog - const GURL* caller = nullptr); - bool HasMultipleFileTypeChoices(); - -+ virtual void ShowToast(const std::string& message) = 0; -+ - protected: - friend class base::RefCountedThreadSafe; - -diff --git a/ui/shell_dialogs/select_file_dialog_android.cc b/ui/shell_dialogs/select_file_dialog_android.cc ---- a/ui/shell_dialogs/select_file_dialog_android.cc -+++ b/ui/shell_dialogs/select_file_dialog_android.cc -@@ -171,6 +171,12 @@ void SelectFileDialogImpl::SelectFileImpl(Type type, - owning_window->GetJavaObject()); - } - -+void SelectFileDialogImpl::ShowToast(const std::string& message) { -+ JNIEnv* env = base::android::AttachCurrentThread(); -+ -+ Java_SelectFileDialog_showToast(env, java_object_, base::android::ConvertUTF8ToJavaString(env, message)); -+} -+ - SelectFileDialogImpl::~SelectFileDialogImpl() { - JNIEnv* env = base::android::AttachCurrentThread(); - Java_SelectFileDialog_nativeDestroyed(env, java_object_); -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 -@@ -49,6 +49,8 @@ class SelectFileDialogImpl : public SelectFileDialog { - gfx::NativeWindow owning_window, - const GURL* caller) override; - -+ void ShowToast(const std::string& message) override; -+ - protected: - ~SelectFileDialogImpl() override; - -diff --git a/ui/shell_dialogs/select_file_dialog_linux.cc b/ui/shell_dialogs/select_file_dialog_linux.cc ---- a/ui/shell_dialogs/select_file_dialog_linux.cc -+++ b/ui/shell_dialogs/select_file_dialog_linux.cc -@@ -31,6 +31,10 @@ void SelectFileDialogLinux::ListenerDestroyed() { - listener_ = nullptr; - } - -+void SelectFileDialogLinux::ShowToast(const std::string& message) { -+ // nothing to do, used only on android -+} -+ - bool SelectFileDialogLinux::CallDirectoryExistsOnUIThread( - const base::FilePath& path) { - base::ScopedAllowBlocking scoped_allow_blocking; -diff --git a/ui/shell_dialogs/select_file_dialog_linux.h b/ui/shell_dialogs/select_file_dialog_linux.h ---- a/ui/shell_dialogs/select_file_dialog_linux.h -+++ b/ui/shell_dialogs/select_file_dialog_linux.h -@@ -33,6 +33,8 @@ class SHELL_DIALOGS_EXPORT SelectFileDialogLinux : public SelectFileDialog { - // BaseShellDialog implementation. - void ListenerDestroyed() override; - -+ void ShowToast(const std::string& message) override; -+ - protected: - explicit SelectFileDialogLinux(Listener* listener, - std::unique_ptr policy); -diff --git a/ui/shell_dialogs/select_file_dialog_win.cc b/ui/shell_dialogs/select_file_dialog_win.cc ---- a/ui/shell_dialogs/select_file_dialog_win.cc -+++ b/ui/shell_dialogs/select_file_dialog_win.cc -@@ -193,6 +193,7 @@ class SelectFileDialogImpl : public ui::SelectFileDialog, - int index); - - bool HasMultipleFileTypeChoicesImpl() override; -+ void ShowToast(const std::string& message) override; - - // Returns the filter to be used while displaying the open/save file dialog. - // This is computed from the extensions for the file types being opened. -@@ -270,6 +271,10 @@ bool SelectFileDialogImpl::HasMultipleFileTypeChoicesImpl() { - return has_multiple_file_type_choices_; - } - -+void SelectFileDialogImpl::ShowToast(const std::string& message) { -+ // nothing to do, used only on android -+} -+ - bool SelectFileDialogImpl::IsRunning(gfx::NativeWindow owning_window) const { - if (!owning_window->GetRootWindow()) - return false; --- diff --git a/build/cromite_patches/Add-cromite-flags-support.patch b/build/cromite_patches/Add-cromite-flags-support.patch deleted file mode 100644 index 30619cba..00000000 --- a/build/cromite_patches/Add-cromite-flags-support.patch +++ /dev/null @@ -1,2104 +0,0 @@ -From: uazo -Date: Sat, 18 Nov 2023 09:41:28 +0000 -Subject: Add cromite flags support - -Add SET_CROMITE_FEATURE_ENABLED*, SET_CROMITE_FEATURE_DISABLED* -and CROMITE_FEATURE macros, logic has been adapted from that found -in brave. -Allows flags to be defined in separate files. -Activates a new cromite tab in chrome://flags with only the flags -added and changed. In android added chrome://flags/cromite -in the setting ui. - -Need: bromite-build-utils.patch -License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html ---- - base/BUILD.gn | 4 +- - base/android/feature_map.cc | 5 + - .../base/cached_flags/ValuesReturned.java | 2 +- - base/feature_list.cc | 76 ++++++++ - base/feature_list.h | 98 +++++++++- - build/android/gyp/java_cpp_features.py | 15 ++ - chrome/android/java/res/values/values.xml | 3 + - .../java/res/xml/privacy_preferences.xml | 4 + - .../homepage/settings/HomepageSettings.java | 2 +- - .../privacy/settings/PrivacySettings.java | 2 +- - .../settings/FragmentDependencyProvider.java | 10 +- - .../browser/settings/SettingsActivity.java | 42 ++++- - .../tracing/settings/DeveloperSettings.java | 5 +- - chrome/browser/about_flags.cc | 11 ++ - chrome/browser/browser_features.cc | 1 + - chrome/browser/browser_features.h | 1 + - chrome/browser/flags/BUILD.gn | 13 ++ - .../flags/android/chrome_feature_list.cc | 1 + - .../flags/android/chrome_feature_list.h | 1 + - .../browser/flags/ChromeFeatureList.java | 13 +- - .../flags/cromite/include_all_directory.java | 1 + - .../java_template/CromiteCachedFlag.java.tmpl | 47 +++++ - .../settings/ChromeBaseSettingsFragment.java | 50 +++++ - .../strings/android_chrome_strings.grd | 1 + - .../Add-cromite-flags-support.grdp | 9 + - .../placeholder.txt | 1 + - chrome/browser/ui/ui_features.cc | 1 + - chrome/browser/unexpire_flags.cc | 15 +- - chrome/common/chrome_features.cc | 2 +- - .../browser_ui/accessibility/android/BUILD.gn | 1 + - .../res/xml/accessibility_preferences.xml | 3 +- - .../accessibility/AccessibilitySettings.java | 6 +- - .../android/java/res/values/attrs.xml | 4 + - .../settings/ChromeSwitchPreference.java | 19 ++ - .../components/cached_flags/CachedFlag.java | 8 +- - components/components_strings.grd | 1 + - .../content_settings/core/common/features.cc | 1 + - .../placeholder.txt | 1 + - .../core/offline_page_feature.cc | 1 + - .../offline_pages/core/offline_page_feature.h | 1 + - .../browser/features/password_features.cc | 1 + - components/permissions/features.cc | 2 + - ...nthetic_trials_active_group_id_provider.cc | 4 +- - ...ynthetic_trials_active_group_id_provider.h | 4 +- - components/webui/flags/flags_state.cc | 59 ++++++ - components/webui/flags/resources/app.css | 24 +++ - components/webui/flags/resources/app.html.ts | 28 +++ - components/webui/flags/resources/app.ts | 24 +++ - .../webui/flags/resources/experiment.css | 9 +- - .../webui/flags/resources/experiment.html.ts | 7 +- - .../webui/flags/resources/experiment.ts | 12 +- - .../flags/resources/flags_browser_proxy.ts | 5 + - .../webui/version/version_handler_helper.cc | 4 +- - content/common/features.cc | 1 + - content/public/common/content_features.cc | 1 + - content/public/common/content_features.h | 1 + - cromite_flags/BUILD.gn | 174 ++++++++++++++++++ - .../browser/about_flags_cc/placeholder.txt | 1 + - .../browser_features_cc/placeholder.txt | 1 + - .../browser_features_h/placeholder.txt | 1 + - .../chrome_feature_list_cc/placeholder.txt | 1 + - .../chrome_feature_list_h/placeholder.txt | 1 + - .../browser/ui/ui_features_cc/placeholder.txt | 1 + - .../common/chrome_features_cc/placeholder.txt | 1 + - .../common/chrome_features_h/placeholder.txt | 1 + - .../core/common/features_cc/placeholder.txt | 1 + - .../offline_page_feature_cc/placeholder.txt | 1 + - .../offline_page_feature_h/placeholder.txt | 1 + - .../password_features_cc/placeholder.txt | 1 + - .../permissions/features_cc/placeholder.txt | 1 + - .../common/features_cc/placeholder.txt | 1 + - .../content_features_cc/placeholder.txt | 1 + - .../common/content_features_h/placeholder.txt | 1 + - .../base/media_switches_cc/placeholder.txt | 1 + - .../base/media_switches_h/placeholder.txt | 1 + - .../net/base/features_cc/placeholder.txt | 1 + - .../net/base/features_h/placeholder.txt | 1 + - .../public/cpp/features_cc/placeholder.txt | 1 + - .../public/cpp/features_h/placeholder.txt | 1 + - .../blink/common/features_cc/placeholder.txt | 1 + - .../blink/common/features_h/placeholder.txt | 1 + - .../ui/base/features_cc/placeholder.txt | 1 + - .../ui/base/features_h/placeholder.txt | 1 + - media/base/media_switches.cc | 2 +- - media/base/media_switches.h | 2 +- - net/base/features.cc | 1 + - net/base/features.h | 1 + - services/network/public/cpp/features.cc | 1 + - services/network/public/cpp/features.h | 1 + - third_party/blink/common/features.cc | 1 + - third_party/blink/public/common/features.h | 1 + - ui/base/ui_base_features.cc | 1 + - ui/base/ui_base_features.h | 1 + - 93 files changed, 848 insertions(+), 32 deletions(-) - create mode 100644 chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/cromite/include_all_directory.java - create mode 100644 chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/cromite/java_template/CromiteCachedFlag.java.tmpl - create mode 100644 chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Add-cromite-flags-support.grdp - create mode 100644 chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/placeholder.txt - create mode 100644 components/cromite_components_strings_grd/placeholder.txt - create mode 100755 cromite_flags/BUILD.gn - create mode 100755 cromite_flags/chrome/browser/about_flags_cc/placeholder.txt - create mode 100755 cromite_flags/chrome/browser/browser_features_cc/placeholder.txt - create mode 100755 cromite_flags/chrome/browser/browser_features_h/placeholder.txt - create mode 100755 cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/placeholder.txt - create mode 100755 cromite_flags/chrome/browser/flags/android/chrome_feature_list_h/placeholder.txt - create mode 100755 cromite_flags/chrome/browser/ui/ui_features_cc/placeholder.txt - create mode 100755 cromite_flags/chrome/common/chrome_features_cc/placeholder.txt - create mode 100755 cromite_flags/chrome/common/chrome_features_h/placeholder.txt - create mode 100755 cromite_flags/components/content_settings/core/common/features_cc/placeholder.txt - create mode 100755 cromite_flags/components/offline_pages/core/offline_page_feature_cc/placeholder.txt - create mode 100755 cromite_flags/components/offline_pages/core/offline_page_feature_h/placeholder.txt - create mode 100755 cromite_flags/components/password_manager/core/browser/features/password_features_cc/placeholder.txt - create mode 100755 cromite_flags/components/permissions/features_cc/placeholder.txt - create mode 100755 cromite_flags/content/common/features_cc/placeholder.txt - create mode 100755 cromite_flags/content/public/common/content_features_cc/placeholder.txt - create mode 100755 cromite_flags/content/public/common/content_features_h/placeholder.txt - create mode 100755 cromite_flags/media/base/media_switches_cc/placeholder.txt - create mode 100755 cromite_flags/media/base/media_switches_h/placeholder.txt - create mode 100755 cromite_flags/net/base/features_cc/placeholder.txt - create mode 100755 cromite_flags/net/base/features_h/placeholder.txt - create mode 100755 cromite_flags/services/network/public/cpp/features_cc/placeholder.txt - create mode 100755 cromite_flags/services/network/public/cpp/features_h/placeholder.txt - create mode 100755 cromite_flags/third_party/blink/common/features_cc/placeholder.txt - create mode 100755 cromite_flags/third_party/blink/common/features_h/placeholder.txt - create mode 100755 cromite_flags/ui/base/features_cc/placeholder.txt - create mode 100755 cromite_flags/ui/base/features_h/placeholder.txt - -diff --git a/base/BUILD.gn b/base/BUILD.gn ---- a/base/BUILD.gn -+++ b/base/BUILD.gn -@@ -170,6 +170,8 @@ use_epoll = is_linux || is_chromeos || is_android - # This does not include test code (test support and anything in the test - # directory) which should use source_set as is recommended for GN targets). - component("base") { -+ deps = [ "//cromite_flags", ] -+ - sources = [ - "allocator/allocator_check.cc", - "allocator/allocator_check.h", -@@ -1048,7 +1050,7 @@ component("base") { - "//build/config/compiler:wglobal_constructors", - ] - -- deps = [ -+ deps += [ - ":check_version_internal", - "//base/allocator:buildflags", - "//base/third_party/cityhash", -diff --git a/base/android/feature_map.cc b/base/android/feature_map.cc ---- a/base/android/feature_map.cc -+++ b/base/android/feature_map.cc -@@ -47,6 +47,11 @@ const Feature* FeatureMap::FindFeatureExposedToJava( - static jboolean JNI_FeatureMap_IsEnabled(JNIEnv* env, - jlong jfeature_map, - std::string& feature_name) { -+ if (base::FeatureList::IsCromiteFlag(feature_name)) { -+ const base::Feature* cromite_feature = -+ base::FeatureList::GetCromiteFlag(feature_name); -+ return base::FeatureList::IsEnabled(*cromite_feature); -+ } - FeatureMap* feature_map = reinterpret_cast(jfeature_map); - const base::Feature* feature = - feature_map->FindFeatureExposedToJava(feature_name); -diff --git a/base/android/java/src/org/chromium/base/cached_flags/ValuesReturned.java b/base/android/java/src/org/chromium/base/cached_flags/ValuesReturned.java ---- a/base/android/java/src/org/chromium/base/cached_flags/ValuesReturned.java -+++ b/base/android/java/src/org/chromium/base/cached_flags/ValuesReturned.java -@@ -18,7 +18,7 @@ import java.util.function.Supplier; - @NullMarked - public abstract class ValuesReturned { - @GuardedBy("sBoolValues") -- private static final Map sBoolValues = new HashMap<>(); -+ public static final Map sBoolValues = new HashMap<>(); - - @GuardedBy("sStringValues") - private static final Map sStringValues = new HashMap<>(); -diff --git a/base/feature_list.cc b/base/feature_list.cc ---- a/base/feature_list.cc -+++ b/base/feature_list.cc -@@ -42,6 +42,31 @@ - - namespace base { - -+namespace internal { -+ -+using DefaultStateOverrides = -+ flat_map; -+ -+constexpr size_t kDefaultStateOverridesReserve = 64 * 4; -+ -+DefaultStateOverrides& GetListOfNewFeatureState() { -+ static NoDestructor -+ startup_default_state_overrides([] { -+ DefaultStateOverrides v; -+ v.reserve(kDefaultStateOverridesReserve); -+ return v; -+ }()); -+ return *startup_default_state_overrides; -+} -+ -+FeatureDefaultStateOverrider::FeatureDefaultStateOverrider( -+ const Feature& feature, FeatureState state) { -+ auto& default_state_overrides = GetListOfNewFeatureState(); -+ default_state_overrides.insert({&feature, state}); -+} -+ -+} // namespace internal -+ - namespace { - - // Pointer to the FeatureList instance singleton that was set via -@@ -471,6 +496,46 @@ bool FeatureList::IsEnabled(const Feature& feature) { - return g_feature_list_instance->IsFeatureEnabled(feature); - } - -+// static -+bool FeatureList::IsCromiteChanged(const Feature& feature) { -+ for(auto const& [key, value]: internal::GetListOfNewFeatureState()) { -+ if (key->name == feature.name) { -+ return true; -+ } -+ } -+ return false; -+} -+ -+// static -+const base::Feature* FeatureList::GetCromiteFlag(const std::string& feature_name) { -+ for(auto const& [key, value]: internal::GetListOfNewFeatureState()) { -+ if (key->name == feature_name && key->is_cromite) { -+ return key; -+ } -+ } -+ NOTREACHED(); -+} -+ -+// static -+bool FeatureList::IsCromiteFlag(const std::string& feature_name) { -+ for(auto const& [key, value]: internal::GetListOfNewFeatureState()) { -+ if (key->name == feature_name && key->is_cromite) { -+ return true; -+ } -+ } -+ return false; -+} -+ -+// static -+bool FeatureList::GetCromiteChange(const Feature& feature) { -+ for(auto const& [key, value]: internal::GetListOfNewFeatureState()) { -+ if (key->name == feature.name) { -+ return value == base::FEATURE_ENABLED_BY_DEFAULT; -+ } -+ } -+ NOTREACHED(); -+} -+ - // static - bool FeatureList::IsValidFeatureOrFieldTrialName(std::string_view name) { - return IsStringASCII(name) && name.find_first_of(",<*") == std::string::npos; -@@ -738,6 +803,17 @@ void FeatureList::VisitFeaturesAndParams(FeatureVisitor& visitor, - - void FeatureList::FinalizeInitialization() { - DCHECK(!initialized_); -+ //LOG(INFO) << "---FinalizeInitialization"; -+ for(auto const& [key, value]: internal::GetListOfNewFeatureState()) { -+ // LOG(INFO) << "---key " << key->name -+ // << " " -+ // << (value == base::FEATURE_ENABLED_BY_DEFAULT ? "1" : "0"); -+ RegisterOverride(key->name, -+ value == base::FEATURE_ENABLED_BY_DEFAULT -+ ? OverrideState::OVERRIDE_ENABLE_FEATURE -+ : OverrideState::OVERRIDE_DISABLE_FEATURE, -+ /* field_trial = */ nullptr); -+ } - // Store the field trial list pointer for DCHECKing. - field_trial_list_ = FieldTrialList::GetInstance(); - initialized_ = true; -diff --git a/base/feature_list.h b/base/feature_list.h ---- a/base/feature_list.h -+++ b/base/feature_list.h -@@ -233,8 +233,10 @@ StringStorage(const char (&feature)[N]) -> StringStorage; - struct BASE_EXPORT LOGICALLY_CONST Feature { - constexpr Feature(const char* name, - FeatureState default_state, -- internal::FeatureMacroHandshake) -- : name(name), default_state(default_state) { -+ internal::FeatureMacroHandshake, -+ bool cromite = false, bool is_new_flag = false) -+ : name(name), default_state(default_state), -+ is_cromite(cromite), is_new(is_new_flag) { - #if BUILDFLAG(ENABLE_BANNED_BASE_FEATURE_PREFIX) - if (std::string_view(name).find(BUILDFLAG(BANNED_BASE_FEATURE_PREFIX)) == - 0) { -@@ -261,6 +263,9 @@ struct BASE_EXPORT LOGICALLY_CONST Feature { - // command line switch. - const FeatureState default_state; - -+ const bool is_cromite = false; -+ const bool is_new = false; -+ - private: - friend class FeatureList; - -@@ -541,6 +546,11 @@ class BASE_EXPORT FeatureList { - // instance, which is checked in builds with DCHECKs enabled. - static bool IsEnabled(const Feature& feature); - -+ static bool IsCromiteFlag(const std::string& featureName); -+ static const base::Feature* GetCromiteFlag(const std::string& featureName); -+ static bool IsCromiteChanged(const Feature& feature); -+ static bool GetCromiteChange(const Feature& feature); -+ - // Some characters are not allowed to appear in feature names or the - // associated field trial names, as they are used as special characters for - // command-line serialization. This function checks that the strings are ASCII -@@ -810,4 +820,88 @@ class BASE_EXPORT FeatureList { - - } // namespace base - -+namespace base { -+namespace internal { -+ -+// Perform base::Feature duplicates check and fills overriden states into a -+// map that is used at runtime to get an override if available. -+class BASE_EXPORT FeatureDefaultStateOverrider { -+ public: -+ using FeatureOverrideInfo = -+ std::pair, FeatureState>; -+ -+ FeatureDefaultStateOverrider( -+ const Feature& feature, FeatureState state); -+}; -+ -+} // namespace internal -+} // namespace base -+ -+#define CROMITE_FEATURE(feature, name, default_state) \ -+ constinit const base::Feature feature(name, default_state, base::internal::FeatureMacroHandshake::kSecret, true, true); \ -+ _Pragma("clang diagnostic push") \ -+ _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") \ -+ static const ::base::internal::FeatureDefaultStateOverrider \ -+ g_feature_default_state_overrider_ ##feature {feature, default_state}; \ -+ _Pragma("clang diagnostic pop") \ -+ static_assert(true, "") /* for a semicolon requirement */ -+ -+#define SET_CROMITE_FEATURE_ENABLED(feature) \ -+ _Pragma("clang diagnostic push") \ -+ _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") \ -+ static const ::base::internal::FeatureDefaultStateOverrider \ -+ g_feature_default_state_overrider_ ##feature {feature, base::FEATURE_ENABLED_BY_DEFAULT}; \ -+ _Pragma("clang diagnostic pop") \ -+ static_assert(true, "") /* for a semicolon requirement */ -+ -+#define SET_CROMITE_FEATURE_DISABLED(feature) \ -+ _Pragma("clang diagnostic push") \ -+ _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") \ -+ static const ::base::internal::FeatureDefaultStateOverrider \ -+ g_feature_default_state_overrider_ ##feature {feature, base::FEATURE_DISABLED_BY_DEFAULT}; \ -+ _Pragma("clang diagnostic pop") \ -+ static_assert(true, "") /* for a semicolon requirement */ -+ -+#define SET_CROMITE_FEATURE_ENABLED_W_NAMESPACE(namespace_value, feature) \ -+ _Pragma("clang diagnostic push") \ -+ _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") \ -+ static const ::base::internal::FeatureDefaultStateOverrider \ -+ g_feature_default_state_overrider_ ##feature {namespace_value::feature, base::FEATURE_ENABLED_BY_DEFAULT}; \ -+ _Pragma("clang diagnostic pop") \ -+ static_assert(true, "") /* for a semicolon requirement */ -+ -+#define SET_CROMITE_FEATURE_DISABLED_W_NAMESPACE(namespace_value, feature) \ -+ _Pragma("clang diagnostic push") \ -+ _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") \ -+ static const ::base::internal::FeatureDefaultStateOverrider \ -+ g_feature_default_state_overrider_ ##feature {namespace_value::feature, base::FEATURE_DISABLED_BY_DEFAULT}; \ -+ _Pragma("clang diagnostic pop") \ -+ static_assert(true, "") /* for a semicolon requirement */ -+ -+#define BASE_FEATURE_DISABLED_3_ARGS(feature, name, default_state) \ -+ BASE_FEATURE(feature, name, default_state); \ -+ static_assert(default_state == base::FEATURE_DISABLED_BY_DEFAULT, "Check default state") -+ -+#define BASE_FEATURE_DISABLED_2_ARGS(name, default_state) \ -+ BASE_FEATURE(name, default_state); \ -+ static_assert(default_state == base::FEATURE_DISABLED_BY_DEFAULT, "Check default state") -+ -+#define GET_BASE_FEATURE_DISABLED_MACRO(_1, _2, _3, NAME, ...) NAME -+#define BASE_FEATURE_DISABLED(...) \ -+ GET_BASE_FEATURE_DISABLED_MACRO(__VA_ARGS__, BASE_FEATURE_DISABLED_3_ARGS, \ -+ BASE_FEATURE_DISABLED_2_ARGS)(__VA_ARGS__) -+ -+#define BASE_FEATURE_ENABLED_3_ARGS(feature, name, default_state) \ -+ BASE_FEATURE(feature, name, default_state); \ -+ static_assert(default_state == base::FEATURE_ENABLED_BY_DEFAULT, "Check default state") -+ -+#define BASE_FEATURE_ENABLED_2_ARGS(name, default_state) \ -+ BASE_FEATURE(name, default_state); \ -+ static_assert(default_state == base::FEATURE_ENABLED_BY_DEFAULT, "Check default state") -+ -+#define GET_BASE_FEATURE_ENABLED_MACRO(_1, _2, _3, NAME, ...) NAME -+#define BASE_FEATURE_ENABLED(...) \ -+ GET_BASE_FEATURE_ENABLED_MACRO(__VA_ARGS__, BASE_FEATURE_ENABLED_3_ARGS, \ -+ BASE_FEATURE_ENABLED_2_ARGS)(__VA_ARGS__) -+ - #endif // BASE_FEATURE_LIST_H_ -diff --git a/build/android/gyp/java_cpp_features.py b/build/android/gyp/java_cpp_features.py ---- a/build/android/gyp/java_cpp_features.py -+++ b/build/android/gyp/java_cpp_features.py -@@ -22,6 +22,11 @@ class FeatureParserDelegate(java_cpp_utils.CppConstantParser.Delegate): - # ExtractConstantName() -> 'ConstantName' - # ExtractValue() -> '"StringNameOfTheFeature"' or '"ConstantName"' - _FEATURE_RE = re.compile(r'BASE_FEATURE\(\s*(k\w+),') -+ _FEATURE_RE1 = re.compile(r'CROMITE_FEATURE\(\s*(k\w+),') -+ _FEATURE_RE2 = re.compile(r'BASE_FEATURE_DISABLED\(\s*(k\w+),') -+ _FEATURE_RE3 = re.compile(r'CROMITE_FEATURE_DISABLED\(\s*(k\w+),') -+ _FEATURE_RE4 = re.compile(r'BASE_FEATURE_ENABLED\(\s*(k\w+),') -+ _FEATURE_RE5 = re.compile(r'CROMITE_FEATURE_ENABLED\(\s*(k\w+),') - _STRING_LITERAL_RE = re.compile(r'"(?:\\"|[^"])*"') - _constant_name = None # The name of the current macro. - _comma_count = 0 # Number of commas seen in the current macro. -@@ -34,6 +39,16 @@ class FeatureParserDelegate(java_cpp_utils.CppConstantParser.Delegate): - self._constant_name = None - - match = self._FEATURE_RE.match(line) -+ if match is None: -+ match = self._FEATURE_RE1.match(line) -+ if match is None: -+ match = self._FEATURE_RE2.match(line) -+ if match is None: -+ match = self._FEATURE_RE3.match(line) -+ if match is None: -+ match = self._FEATURE_RE4.match(line) -+ if match is None: -+ match = self._FEATURE_RE5.match(line) - if match: - # The regex ensures that the feature name starts with 'k'. - feature_name = match.group(1) -diff --git a/chrome/android/java/res/values/values.xml b/chrome/android/java/res/values/values.xml ---- a/chrome/android/java/res/values/values.xml -+++ b/chrome/android/java/res/values/values.xml -@@ -9,6 +9,9 @@ found in the LICENSE file. - xmlns:tools="http://schemas.android.com/tools" - tools:ignore="MissingTranslation"> - -+ Open Cromite flags list -+ chrome://flags/cromite -+ - - - - -diff --git a/chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Add-cromite-flags-support.grdp b/chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Add-cromite-flags-support.grdp -new file mode 100644 ---- /dev/null -+++ b/chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Add-cromite-flags-support.grdp -@@ -0,0 +1,9 @@ -+ -+ -+ -+ Relaunch -+ -+ -+ Your changes will take effect the next time you relaunch Cromite. -+ -+ -diff --git a/chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/placeholder.txt b/chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/placeholder.txt -new file mode 100644 ---- /dev/null -+++ b/chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/chrome/browser/ui/ui_features.cc b/chrome/browser/ui/ui_features.cc ---- a/chrome/browser/ui/ui_features.cc -+++ b/chrome/browser/ui/ui_features.cc -@@ -664,4 +664,5 @@ bool IsAndroidAnimatedProgressBarInBrowserEnabled() { - - BASE_FEATURE(kWhatsNewDesktopRefresh, base::FEATURE_DISABLED_BY_DEFAULT); - -+#include "cromite_flags/chrome_browser_ui_ui_features_cc.inc" - } // namespace features -diff --git a/chrome/browser/unexpire_flags.cc b/chrome/browser/unexpire_flags.cc ---- a/chrome/browser/unexpire_flags.cc -+++ b/chrome/browser/unexpire_flags.cc -@@ -8,6 +8,7 @@ - #include "base/containers/contains.h" - #include "base/containers/flat_map.h" - #include "base/no_destructor.h" -+#include "chrome/browser/about_flags.h" - #include "chrome/browser/expired_flags_list.h" - #include "chrome/browser/unexpire_flags_gen.h" - #include "chrome/common/chrome_version.h" -@@ -114,7 +115,19 @@ bool IsFlagExpired(const flags_ui::FlagsStorage* storage, - - // Otherwise, the flag is expired if its expiration mstone is less than the - // mstone of this copy of Chromium. -- return mstone < CHROME_VERSION_MAJOR; -+ if (mstone < CHROME_VERSION_MAJOR) { -+ if (const flags_ui::FeatureEntry* entry = -+ about_flags::GetCurrentFlagsState()->FindFeatureEntryByName( -+ internal_name)) { -+ if (const base::Feature* feature = entry->feature.feature) { -+ if (feature->is_cromite) { -+ return false; -+ } -+ } -+ } -+ return true; -+ } -+ return false; - } - - namespace testing { -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 -@@ -1696,5 +1696,5 @@ BASE_FEATURE(kDisableShortcutsEnableDiy, base::FEATURE_ENABLED_BY_DEFAULT); - // happen silently without prompting an updating dialog. - BASE_FEATURE(kSilentPolicyAndDefaultAppUpdating, - base::FEATURE_DISABLED_BY_DEFAULT); -- -+#include "cromite_flags/chrome_common_chrome_features_cc.inc" - } // namespace features -diff --git a/components/browser_ui/accessibility/android/BUILD.gn b/components/browser_ui/accessibility/android/BUILD.gn ---- a/components/browser_ui/accessibility/android/BUILD.gn -+++ b/components/browser_ui/accessibility/android/BUILD.gn -@@ -61,6 +61,7 @@ android_library("lib_java") { - ":page_zoom_utils_java", - "//base:base_java", - "//build/android:build_java", -+ "//chrome/browser/settings:java", - "//components/browser_ui/settings/android:java", - "//components/browser_ui/site_settings/android:java", - "//components/browser_ui/styles/android:java", -diff --git a/components/browser_ui/accessibility/android/java/res/xml/accessibility_preferences.xml b/components/browser_ui/accessibility/android/java/res/xml/accessibility_preferences.xml ---- a/components/browser_ui/accessibility/android/java/res/xml/accessibility_preferences.xml -+++ b/components/browser_ui/accessibility/android/java/res/xml/accessibility_preferences.xml -@@ -5,7 +5,8 @@ Use of this source code is governed by a BSD-style license that can be - found in the LICENSE file. - --> - -- -+ - -diff --git a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/AccessibilitySettings.java b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/AccessibilitySettings.java ---- a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/AccessibilitySettings.java -+++ b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/AccessibilitySettings.java -@@ -28,9 +28,11 @@ import org.chromium.components.omnibox.OmniboxFeatures; - import org.chromium.content_public.browser.ContentFeatureList; - import org.chromium.content_public.browser.ContentFeatureMap; - -+import org.chromium.chrome.browser.settings.ChromeBaseSettingsFragment; -+ - /** Fragment to keep track of all the accessibility related preferences. */ - @NullMarked --public class AccessibilitySettings extends PreferenceFragmentCompat -+public class AccessibilitySettings extends ChromeBaseSettingsFragment - implements EmbeddableSettingsPage, Preference.OnPreferenceChangeListener { - public static final String PREF_PAGE_ZOOM_DEFAULT_ZOOM = "page_zoom_default_zoom"; - public static final String PREF_PAGE_ZOOM_INCLUDE_OS_ADJUSTMENT = -@@ -69,7 +71,7 @@ public class AccessibilitySettings extends PreferenceFragmentCompat - } - - @Override -- public void onCreatePreferences(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { -+ public void onCreatePreferencesCromite(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { - SettingsUtils.addPreferencesFromResource(this, R.xml.accessibility_preferences); - - // TODO(crbug.com/439911511): Add PageZoomPreference directly to the xml file instead. -diff --git a/components/browser_ui/settings/android/java/res/values/attrs.xml b/components/browser_ui/settings/android/java/res/values/attrs.xml ---- a/components/browser_ui/settings/android/java/res/values/attrs.xml -+++ b/components/browser_ui/settings/android/java/res/values/attrs.xml -@@ -12,6 +12,10 @@ found in the LICENSE file. - - - -+ -+ -+ -+ - - - -diff --git a/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/ChromeSwitchPreference.java b/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/ChromeSwitchPreference.java ---- a/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/ChromeSwitchPreference.java -+++ b/components/browser_ui/settings/android/widget/java/src/org/chromium/components/browser_ui/settings/ChromeSwitchPreference.java -@@ -15,6 +15,8 @@ import android.view.accessibility.AccessibilityEvent; - import android.view.accessibility.AccessibilityNodeInfo; - import android.widget.TextView; - -+import android.content.res.TypedArray; -+ - import androidx.annotation.ColorInt; - import androidx.annotation.VisibleForTesting; - import androidx.preference.PreferenceViewHolder; -@@ -43,6 +45,11 @@ public class ChromeSwitchPreference extends SwitchPreferenceCompat - /** Indicates if the preference uses a custom layout. */ - private final boolean mHasCustomLayout; - -+ @Nullable -+ private String mFeatureName; -+ -+ private final boolean mNeedRestart; -+ - // TOOD(crbug.com/1451550): This is an interim solution. In the long-term, we should migrate - // away from a switch with dynamically changing summaries onto a radio group. - /** -@@ -67,6 +74,18 @@ public class ChromeSwitchPreference extends SwitchPreferenceCompat - - mHasCustomLayout = ManagedPreferencesUtils.isCustomLayoutApplied(context, attrs); - mUseSummaryAsTitle = true; -+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ChromeBasePreference); -+ mFeatureName = a.getString(R.styleable.ChromeBasePreference_featureName); -+ mNeedRestart = a.getBoolean(R.styleable.ChromeBasePreference_needRestart, false); -+ a.recycle(); -+ } -+ -+ public String getFeatureName() { -+ return mFeatureName; -+ } -+ -+ public boolean needRestart() { -+ return mNeedRestart; - } - - /** -diff --git a/components/cached_flags/android/java/src/org/chromium/components/cached_flags/CachedFlag.java b/components/cached_flags/android/java/src/org/chromium/components/cached_flags/CachedFlag.java ---- a/components/cached_flags/android/java/src/org/chromium/components/cached_flags/CachedFlag.java -+++ b/components/cached_flags/android/java/src/org/chromium/components/cached_flags/CachedFlag.java -@@ -155,7 +155,7 @@ public class CachedFlag extends Flag { - editor.putBoolean(getSharedPreferenceKey(), featureValue); - } - -- String getSharedPreferenceKey() { -+ public String getSharedPreferenceKey() { - // Create the key only once to avoid String concatenation every flag check. - if (mPreferenceKey == null) { - mPreferenceKey = CachedFlagsSharedPreferences.FLAGS_CACHED.createKey(mFeatureName); -@@ -163,6 +163,12 @@ public class CachedFlag extends Flag { - return mPreferenceKey; - } - -+ public void setValueReturnedOverride(@Nullable Boolean value) { -+ synchronized (ValuesReturned.sBoolValues) { -+ ValuesReturned.sBoolValues.put(getSharedPreferenceKey(), value); -+ } -+ } -+ - /** Create a Map of feature names -> {@link CachedFlag} from multiple lists of CachedFlags. */ - public static Map createCachedFlagMap( - List> allCachedFlagsLists) { -diff --git a/components/components_strings.grd b/components/components_strings.grd ---- a/components/components_strings.grd -+++ b/components/components_strings.grd -@@ -282,6 +282,7 @@ - - - -+ - - - -diff --git a/components/content_settings/core/common/features.cc b/components/content_settings/core/common/features.cc ---- a/components/content_settings/core/common/features.cc -+++ b/components/content_settings/core/common/features.cc -@@ -160,5 +160,6 @@ BASE_FEATURE(kContentSettingsPartitioning, base::FEATURE_DISABLED_BY_DEFAULT); - - BASE_FEATURE(kForceAllowStorageAccess, base::FEATURE_DISABLED_BY_DEFAULT); - -+#include "cromite_flags/components_content_settings_core_common_features_cc.inc" - } // namespace features - } // namespace content_settings -diff --git a/components/cromite_components_strings_grd/placeholder.txt b/components/cromite_components_strings_grd/placeholder.txt -new file mode 100644 ---- /dev/null -+++ b/components/cromite_components_strings_grd/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/components/offline_pages/core/offline_page_feature.cc b/components/offline_pages/core/offline_page_feature.cc ---- a/components/offline_pages/core/offline_page_feature.cc -+++ b/components/offline_pages/core/offline_page_feature.cc -@@ -47,4 +47,5 @@ bool IsOfflinePagesNetworkStateLikelyUnknown() { - return base::FeatureList::IsEnabled(kOfflinePagesNetworkStateLikelyUnknown); - } - -+#include "cromite_flags/components_offline_pages_core_offline_page_feature_cc.inc" - } // namespace offline_pages -diff --git a/components/offline_pages/core/offline_page_feature.h b/components/offline_pages/core/offline_page_feature.h ---- a/components/offline_pages/core/offline_page_feature.h -+++ b/components/offline_pages/core/offline_page_feature.h -@@ -42,6 +42,7 @@ bool IsOnTheFlyMhtmlHashComputationEnabled(); - // offline pages to avoid showing them even when the device is online. - bool IsOfflinePagesNetworkStateLikelyUnknown(); - -+#include "cromite_flags/components_offline_pages_core_offline_page_feature_h.inc" - } // namespace offline_pages - - #endif // COMPONENTS_OFFLINE_PAGES_CORE_OFFLINE_PAGE_FEATURE_H_ -diff --git a/components/password_manager/core/browser/features/password_features.cc b/components/password_manager/core/browser/features/password_features.cc ---- a/components/password_manager/core/browser/features/password_features.cc -+++ b/components/password_manager/core/browser/features/password_features.cc -@@ -183,4 +183,5 @@ BASE_FEATURE(kRetrieveTrustedVaultKeyKeyboardAccessoryAction, - base::FEATURE_DISABLED_BY_DEFAULT); - #endif // BUILDFLAG(IS_ANDROID) - -+#include "cromite_flags/components_password_manager_core_browser_features_password_features_cc.inc" - } // namespace password_manager::features -diff --git a/components/permissions/features.cc b/components/permissions/features.cc ---- a/components/permissions/features.cc -+++ b/components/permissions/features.cc -@@ -107,6 +107,8 @@ BASE_FEATURE(kSafetyHubUnusedPermissionRevocationForAllSurfaces, - BASE_FEATURE(kOsAdditionalSecurityPermissionKillSwitch, - base::FEATURE_DISABLED_BY_DEFAULT); - #endif -+ -+#include "cromite_flags/components_permissions_features_cc.inc" - } // namespace features - namespace feature_params { - -diff --git a/components/variations/synthetic_trials_active_group_id_provider.cc b/components/variations/synthetic_trials_active_group_id_provider.cc ---- a/components/variations/synthetic_trials_active_group_id_provider.cc -+++ b/components/variations/synthetic_trials_active_group_id_provider.cc -@@ -27,7 +27,7 @@ SyntheticTrialsActiveGroupIdProvider::GetActiveGroupIds() { - return group_ids_; - } - --#if !defined(NDEBUG) -+#if true - std::vector - SyntheticTrialsActiveGroupIdProvider::GetGroups() { - base::AutoLock scoped_lock(lock_); -@@ -53,7 +53,7 @@ void SyntheticTrialsActiveGroupIdProvider::OnSyntheticTrialsChanged( - for (const auto& group : groups) { - group_ids_.push_back(group.id()); - } --#if !defined(NDEBUG) -+#if true - groups_ = groups; - #endif // !defined(NDEBUG) - } -diff --git a/components/variations/synthetic_trials_active_group_id_provider.h b/components/variations/synthetic_trials_active_group_id_provider.h ---- a/components/variations/synthetic_trials_active_group_id_provider.h -+++ b/components/variations/synthetic_trials_active_group_id_provider.h -@@ -36,7 +36,7 @@ class COMPONENT_EXPORT(VARIATIONS) SyntheticTrialsActiveGroupIdProvider - // Returns currently active synthetic trial group IDs. - std::vector GetActiveGroupIds(); - --#if !defined(NDEBUG) -+#if true - // In debug mode, not only the group IDs are tracked but also the full group - // info, to display the names unhashed in chrome://version. - std::vector GetGroups(); -@@ -60,7 +60,7 @@ class COMPONENT_EXPORT(VARIATIONS) SyntheticTrialsActiveGroupIdProvider - - base::Lock lock_; - std::vector group_ids_; // GUARDED_BY(lock_); --#if !defined(NDEBUG) -+#if true - // In debug builds, keep the full group information to be able to display it - // in chrome://version. - std::vector groups_; // GUARDED_BY(lock_); -diff --git a/components/webui/flags/flags_state.cc b/components/webui/flags/flags_state.cc ---- a/components/webui/flags/flags_state.cc -+++ b/components/webui/flags/flags_state.cc -@@ -377,6 +377,21 @@ void FlagsState::GetSwitchesAndFeaturesFromFlags( - - for (const std::string& entry_name : enabled_entries) { - const auto& entry_it = name_to_switch_map.find(entry_name); -+ if (entry_it == name_to_switch_map.end()) { -+ // check if is a cromite feature -+ std::string::size_type pos = entry_name.find('@'); -+ if (pos != std::string::npos) { -+ std::string feature_name = entry_name.substr(0, pos); -+ if (base::FeatureList::IsCromiteFlag(feature_name)) { -+ if (entry_name.ends_with("@1")) -+ features->insert(entry_name + ":enabled"); -+ else -+ features->insert(entry_name + ":disabled"); -+ continue; -+ } -+ } -+ NOTREACHED(); -+ } - CHECK(entry_it != name_to_switch_map.end()); - - const SwitchEntry& entry = entry_it->second; -@@ -710,6 +725,27 @@ void FlagsState::GetFlagFeatureEntries( - data.Set("links", std::move(links)); - } - -+ if (entry.type == FeatureEntry::FEATURE_VALUE -+ || entry.type == FeatureEntry::FEATURE_WITH_PARAMS_VALUE) { -+ DCHECK(entry.feature.feature); -+ if (base::FeatureList::IsCromiteChanged(*entry.feature.feature)) { -+ bool is_enabled = base::FeatureList::GetCromiteChange(*entry.feature.feature); -+ data.Set("is_cromite", true); -+ data.Set("default_value", -+ is_enabled ? "enabled" : "disabled"); -+ } else { -+ bool is_enabled = entry.feature.feature->default_state == base::FEATURE_ENABLED_BY_DEFAULT; -+ data.Set("default_value", is_enabled -+ ? "enabled" : "disabled"); -+ if (is_enabled) -+ data.Set("is_default_value_on", true); -+ } -+ if (entry.feature.feature->is_cromite) -+ data.Set("is_cromite", true); -+ if (entry.feature.feature->is_new) -+ data.Set("is_new", true); -+ } -+ - switch (entry.type) { - case FeatureEntry::SINGLE_VALUE: - case FeatureEntry::SINGLE_DISABLE_VALUE: -@@ -837,6 +873,16 @@ void FlagsState::AddSwitchesToCommandLine( - for (const std::string& entry_name : enabled_entries) { - const auto& entry_it = name_to_switch_map.find(entry_name); - if (entry_it == name_to_switch_map.end()) { -+ // check if is a cromite feature -+ std::string::size_type pos = entry_name.find('@'); -+ if (pos != std::string::npos) { -+ std::string feature_name = entry_name.substr(0, pos); -+ if (base::FeatureList::IsCromiteFlag(feature_name)) { -+ feature_switches[feature_name] = -+ entry_name.ends_with("@1"); -+ continue; -+ } -+ } - NOTREACHED(); - } - -@@ -1093,6 +1139,14 @@ const FeatureEntry* FlagsState::FindFeatureEntryByName( - bool FlagsState::IsSupportedFeature(const FlagsStorage* storage, - const std::string& name, - int platform_mask) const { -+ // check if is a cromite feature -+ std::string::size_type pos = name.find('@'); -+ if (pos != std::string::npos) { -+ std::string feature_name = name.substr(0, pos); -+ if (base::FeatureList::IsCromiteFlag(feature_name)) { -+ return true; -+ } -+ } - for (const auto& entry : feature_entries_) { - DCHECK(entry.IsValid()); - if (!(entry.supported_platforms & platform_mask)) { -@@ -1131,6 +1185,11 @@ void FlagsState::SetFlags( - FindFeatureEntryByName(feature_internal_name); - // Since this flag is currently enabled, we know for sure that we can find - // its feature entry using its internal name. -+ if (!entry) { -+ if (base::FeatureList::IsCromiteFlag(feature_internal_name)) { -+ continue; -+ } -+ } - CHECK(entry); - - if (entry->type == FeatureEntry::FEATURE_VALUE || -diff --git a/components/webui/flags/resources/app.css b/components/webui/flags/resources/app.css ---- a/components/webui/flags/resources/app.css -+++ b/components/webui/flags/resources/app.css -@@ -391,3 +391,27 @@ cr-tabs { - padding-top: 1.5rem; - } - } -+#appcontainer { -+ overflow-y: scroll; -+} -+.cromite #header { -+ display: none; -+} -+.cromite .blurb-container { -+ display: none; -+} -+.cromite #tabs { -+ display: none; -+} -+.cromite #tab-content-available { -+ display: none; -+} -+.cromite #tab-content-unavailable { -+ display: none; -+} -+.cromite #tab-content-cromite { -+ display: block !important; -+} -+.cromite .section-header-title { -+ display: none; -+} -diff --git a/components/webui/flags/resources/app.html.ts b/components/webui/flags/resources/app.html.ts ---- a/components/webui/flags/resources/app.html.ts -+++ b/components/webui/flags/resources/app.html.ts -@@ -9,6 +9,7 @@ import type {AppElement} from './app.js'; - export function getHtml(this: AppElement) { - // clang-format off - return html` -+
- -
-+ - `; - // clang-format on - } -diff --git a/components/webui/flags/resources/app.ts b/components/webui/flags/resources/app.ts ---- a/components/webui/flags/resources/app.ts -+++ b/components/webui/flags/resources/app.ts -@@ -132,6 +132,7 @@ export class FlagsAppElement extends CrLitElement { - // - loadTimeData.getString('unavailable'), - // -+ "Cromite", - ]; - protected accessor selectedTabIndex_: number = 0; - -@@ -150,9 +151,12 @@ export class FlagsAppElement extends CrLitElement { - - protected accessor defaultFeatures: Feature[] = []; - protected accessor nonDefaultFeatures: Feature[] = []; -+ protected defaultCromiteFeatures: Feature[] = []; -+ protected nonDefaultCromiteFeatures: Feature[] = []; - protected accessor searching: boolean = false; - protected accessor needsRestart: boolean = false; - -+ private onlyCromiteFlags: boolean = false; - private announceStatusDelayMs: number = 100; - private featuresResolver: PromiseResolver = new PromiseResolver(); - private flagSearch: FlagSearch|null = null; -@@ -186,10 +190,25 @@ export class FlagsAppElement extends CrLitElement { - if (changedPrivateProperties.has('data')) { - const defaultFeatures: Feature[] = []; - const nonDefaultFeatures: Feature[] = []; -+ const defaultCromiteFeatures: Feature[] = []; -+ const nonDefaultCromiteFeatures: Feature[] = []; -+ -+ if (this.onlyCromiteFlags) { -+ this.data.supportedFeatures = -+ this.data.supportedFeatures.filter(item => item.is_new); -+ } -+ this.data.supportedFeatures.forEach( -+ f => (f.is_cromite -+ ? (f.is_default ? defaultCromiteFeatures : nonDefaultCromiteFeatures).push(f) -+ : undefined)); -+ this.data.supportedFeatures.sort( -+ (a,b) => (a.internal_name.localeCompare(b.internal_name))); - - this.data.supportedFeatures.forEach( - f => (f.is_default ? defaultFeatures : nonDefaultFeatures).push(f)); - -+ this.defaultCromiteFeatures = defaultCromiteFeatures; -+ this.nonDefaultCromiteFeatures = nonDefaultCromiteFeatures; - this.defaultFeatures = defaultFeatures; - this.nonDefaultFeatures = nonDefaultFeatures; - -@@ -233,6 +252,11 @@ export class FlagsAppElement extends CrLitElement { - override connectedCallback() { - super.connectedCallback(); - -+ if (location.pathname == '/cromite') { -+ this.onlyCromiteFlags = true; -+ this.getRequiredElement("#appcontainer").classList.add('cromite'); -+ document.title = "Cromite Flags List"; -+ } - // - const pathname = new URL(window.location.href).pathname; - this.isFlagsDeprecatedUrl_ = -diff --git a/components/webui/flags/resources/experiment.css b/components/webui/flags/resources/experiment.css ---- a/components/webui/flags/resources/experiment.css -+++ b/components/webui/flags/resources/experiment.css -@@ -17,6 +17,7 @@ - } - - .experiment { -+ padding-bottom: 25px; - color: var(--secondary-color); - line-height: 1.45; - width: 100%; -@@ -84,6 +85,11 @@ - resize: none; - } - -+.experiment-on select { -+ background: #dddddd; -+ color: var(--link-color); -+} -+ - select { - background: white; - border: 1px solid var(--link-color); -@@ -160,6 +166,7 @@ input { - @media (max-width: 480px) { - .experiment { - border-bottom: 1px solid var(--separator-color); -+ padding-bottom: 8px; - } - - .experiment-name { -@@ -177,7 +184,6 @@ input { - .experiment .experiment-actions { - max-width: 100%; - padding-top: 12px; -- text-align: left; /* csschecker-disable-line left-right */ - width: 100%; - } - -@@ -185,7 +191,6 @@ input { - .body { - overflow: hidden; - text-overflow: ellipsis; -- white-space: nowrap; - width: 100%; - } - -diff --git a/components/webui/flags/resources/experiment.html.ts b/components/webui/flags/resources/experiment.html.ts ---- a/components/webui/flags/resources/experiment.html.ts -+++ b/components/webui/flags/resources/experiment.html.ts -@@ -10,7 +10,8 @@ export function getHtml(this: ExperimentElement) { - // clang-format off - return html` -
--
-+
-
- ${this.showingSearchHit_? html` -

- ${this.feature_.options!.map(option => html` - - `)} - -diff --git a/components/webui/flags/resources/experiment.ts b/components/webui/flags/resources/experiment.ts ---- a/components/webui/flags/resources/experiment.ts -+++ b/components/webui/flags/resources/experiment.ts -@@ -81,6 +81,11 @@ export class ExperimentElement extends CrLitElement { - enabled: false, - is_default: false, - supported_platforms: [], -+ is_default_value_on: false, -+ default_value: '', -+ is_cromite: false, -+ is_new: false, -+ permalink: true, - }; - - // Whether the controls to change the experiment state should be hidden. -@@ -121,9 +126,12 @@ export class ExperimentElement extends CrLitElement { - } - - protected getExperimentTitle_(): string { -+ const suffix = -+ this.feature_.is_cromite && this.feature_.is_new -+ ? " (Cromite flag)" : ""; - if (this.showEnableDisableSelect_()) { -- return this.isDefault_ ? '' : -- loadTimeData.getString('experiment-enabled'); -+ return (this.isDefault_ ? '' : -+ loadTimeData.getString('experiment-enabled')) + suffix; - } - - return ''; -diff --git a/components/webui/flags/resources/flags_browser_proxy.ts b/components/webui/flags/resources/flags_browser_proxy.ts ---- a/components/webui/flags/resources/flags_browser_proxy.ts -+++ b/components/webui/flags/resources/flags_browser_proxy.ts -@@ -16,6 +16,11 @@ export interface Feature { - description: string; - enabled: boolean; - is_default: boolean; -+ is_default_value_on: boolean; -+ default_value: string; -+ is_cromite: boolean; -+ is_new: boolean; -+ permalink: boolean; - supported_platforms: string[]; - origin_list_value?: string; - string_value?: string; -diff --git a/components/webui/version/version_handler_helper.cc b/components/webui/version/version_handler_helper.cc ---- a/components/webui/version/version_handler_helper.cc -+++ b/components/webui/version/version_handler_helper.cc -@@ -20,7 +20,7 @@ - namespace version_ui { - namespace { - --#if !defined(NDEBUG) -+#if true - std::string GetActiveGroupNameAsString( - const base::FieldTrial::ActiveGroup& group) { - static const unsigned char kNonBreakingHyphenUTF8[] = {0xE2, 0x80, 0x91, -@@ -56,7 +56,7 @@ base::Value::List GetVariationsList() { - base::FieldTrialListIncludingLowAnonymity::GetActiveFieldTrialGroups( - &active_groups); - --#if !defined(NDEBUG) -+#if true - for (const auto& group : active_groups) { - variations.push_back(GetActiveGroupNameAsString(group)); - } -diff --git a/content/common/features.cc b/content/common/features.cc ---- a/content/common/features.cc -+++ b/content/common/features.cc -@@ -675,4 +675,5 @@ bool IsEnforceSameDocumentOriginInvariantsEnabled() { - blink::features::kTreatMhtmlInitialDocumentLoadsAsCrossDocument); - } - -+#include "cromite_flags/content_common_features_cc.inc" - } // namespace 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 -@@ -1411,4 +1411,5 @@ bool IsPushSubscriptionChangeEventEnabled() { - features::kPushSubscriptionChangeEventOnResubscribe); - } - -+#include "cromite_flags/content_public_common_content_features_cc.inc" - } // namespace features -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 -@@ -409,6 +409,7 @@ CONTENT_EXPORT bool IsVideoCaptureServiceEnabledForOutOfProcess(); - CONTENT_EXPORT bool IsVideoCaptureServiceEnabledForBrowserProcess(); - CONTENT_EXPORT bool IsPushSubscriptionChangeEventEnabled(); - -+#include "cromite_flags/content_public_common_content_features_h.inc" - } // namespace features - - #endif // CONTENT_PUBLIC_COMMON_CONTENT_FEATURES_H_ -diff --git a/cromite_flags/BUILD.gn b/cromite_flags/BUILD.gn -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/BUILD.gn -@@ -0,0 +1,174 @@ -+# 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 . -+ -+# for placeholder.txt: -+# -+# this file is intentionally empty -+# -+ -+cpp_bromite_include("chrome_browser_about_flags_cc") { -+ inputs = [ "//cromite_flags/chrome/browser/about_flags_cc/placeholder.txt" ] -+ output_file = "chrome_browser_about_flags_cc.inc" -+} -+ -+cpp_bromite_include("chrome_common_chrome_features_cc") { -+ inputs = [ "//cromite_flags/chrome/common/chrome_features_cc/placeholder.txt" ] -+ output_file = "chrome_common_chrome_features_cc.inc" -+} -+ -+cpp_bromite_include("content_common_features_cc") { -+ inputs = [ "//cromite_flags/content/common/features_cc/placeholder.txt" ] -+ output_file = "content_common_features_cc.inc" -+} -+ -+cpp_bromite_include("content_public_common_content_features_h") { -+ inputs = [ "//cromite_flags/content/public/common/content_features_h/placeholder.txt" ] -+ output_file = "content_public_common_content_features_h.inc" -+} -+ -+cpp_bromite_include("content_public_common_content_features_cc") { -+ inputs = [ "//cromite_flags/content/public/common/content_features_cc/placeholder.txt" ] -+ output_file = "content_public_common_content_features_cc.inc" -+} -+ -+cpp_bromite_include("third_party_blink_common_features_cc") { -+ inputs = [ "//cromite_flags/third_party/blink/common/features_cc/placeholder.txt" ] -+ output_file = "third_party_blink_common_features_cc.inc" -+} -+ -+cpp_bromite_include("third_party_blink_common_features_h") { -+ inputs = [ "//cromite_flags/third_party/blink/common/features_h/placeholder.txt" ] -+ output_file = "third_party_blink_common_features_h.inc" -+} -+ -+cpp_bromite_include("chrome_browser_flags_android_chrome_feature_list_cc") { -+ inputs = [ "//cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/placeholder.txt" ] -+ output_file = "chrome_browser_flags_android_chrome_feature_list_cc.inc" -+} -+ -+cpp_bromite_include("chrome_browser_flags_android_chrome_feature_list_h") { -+ inputs = [ "//cromite_flags/chrome/browser/flags/android/chrome_feature_list_h/placeholder.txt" ] -+ output_file = "chrome_browser_flags_android_chrome_feature_list_h.inc" -+} -+ -+cpp_bromite_include("chrome_browser_browser_features_cc") { -+ inputs = [ "//cromite_flags/chrome/browser/browser_features_cc/placeholder.txt" ] -+ output_file = "chrome_browser_browser_features_cc.inc" -+} -+ -+cpp_bromite_include("chrome_browser_browser_features_h") { -+ inputs = [ "//cromite_flags/chrome/browser/browser_features_h/placeholder.txt" ] -+ output_file = "chrome_browser_browser_features_h.inc" -+} -+ -+cpp_bromite_include("chrome_browser_ui_ui_features_cc") { -+ inputs = [ "//cromite_flags/chrome/browser/ui/ui_features_cc/placeholder.txt" ] -+ output_file = "chrome_browser_ui_ui_features_cc.inc" -+} -+ -+cpp_bromite_include("media_base_media_switches_cc") { -+ inputs = [ "//cromite_flags/media/base/media_switches_cc/placeholder.txt" ] -+ output_file = "media_base_media_switches_cc.inc" -+} -+ -+cpp_bromite_include("media_base_media_switches_h") { -+ inputs = [ "//cromite_flags/media/base/media_switches_h/placeholder.txt" ] -+ output_file = "media_base_media_switches_h.inc" -+} -+ -+cpp_bromite_include("components_content_settings_core_common_features_cc") { -+ inputs = [ "//cromite_flags/components/content_settings/core/common/features_cc/placeholder.txt" ] -+ output_file = "components_content_settings_core_common_features_cc.inc" -+} -+ -+cpp_bromite_include("components_permissions_features_cc") { -+ inputs = [ "//cromite_flags/components/permissions/features_cc/placeholder.txt" ] -+ output_file = "components_permissions_features_cc.inc" -+} -+ -+cpp_bromite_include("components_offline_pages_core_offline_page_feature_cc") { -+ inputs = [ "//cromite_flags/components/offline_pages/core/offline_page_feature_cc/placeholder.txt" ] -+ output_file = "components_offline_pages_core_offline_page_feature_cc.inc" -+} -+ -+cpp_bromite_include("components_offline_pages_core_offline_page_feature_h") { -+ inputs = [ "//cromite_flags/components/offline_pages/core/offline_page_feature_h/placeholder.txt" ] -+ output_file = "components_offline_pages_core_offline_page_feature_h.inc" -+} -+ -+cpp_bromite_include("net_base_features_cc") { -+ inputs = [ "//cromite_flags/net/base/features_cc/placeholder.txt" ] -+ output_file = "net_base_features_cc.inc" -+} -+ -+cpp_bromite_include("net_base_features_h") { -+ inputs = [ "//cromite_flags/net/base/features_h/placeholder.txt" ] -+ output_file = "net_base_features_h.inc" -+} -+ -+cpp_bromite_include("services_network_public_cpp_features_cc") { -+ inputs = [ "//cromite_flags/services/network/public/cpp/features_cc/placeholder.txt" ] -+ output_file = "services_network_public_cpp_features_cc.inc" -+} -+ -+cpp_bromite_include("services_network_public_cpp_features_h") { -+ inputs = [ "//cromite_flags/services/network/public/cpp/features_h/placeholder.txt" ] -+ output_file = "services_network_public_cpp_features_h.inc" -+} -+ -+cpp_bromite_include("ui_base_features_cc") { -+ inputs = [ "//cromite_flags/ui/base/features_cc/placeholder.txt" ] -+ output_file = "ui_base_features_cc.inc" -+} -+ -+cpp_bromite_include("ui_base_features_h") { -+ inputs = [ "//cromite_flags/ui/base/features_h/placeholder.txt" ] -+ output_file = "ui_base_features_h.inc" -+} -+ -+cpp_bromite_include("components_password_manager_core_browser_features_password_features_cc") { -+ inputs = [ "//cromite_flags/components/password_manager/core/browser/features/password_features_cc/placeholder.txt" ] -+ output_file = "components_password_manager_core_browser_features_password_features_cc.inc" -+} -+ -+component("cromite_flags") { -+ deps = [ -+ ":content_common_features_cc", -+ ":content_public_common_content_features_cc", -+ ":content_public_common_content_features_h", -+ ":components_content_settings_core_common_features_cc", -+ ":components_permissions_features_cc", -+ ":components_offline_pages_core_offline_page_feature_cc", -+ ":components_offline_pages_core_offline_page_feature_h", -+ ":components_password_manager_core_browser_features_password_features_cc", -+ ":media_base_media_switches_cc", -+ ":media_base_media_switches_h", -+ ":net_base_features_cc", -+ ":net_base_features_h", -+ ":chrome_common_chrome_features_cc", -+ ":chrome_browser_about_flags_cc", -+ ":chrome_browser_flags_android_chrome_feature_list_cc", -+ ":chrome_browser_flags_android_chrome_feature_list_h", -+ ":chrome_browser_ui_ui_features_cc", -+ ":chrome_browser_browser_features_cc", -+ ":chrome_browser_browser_features_h", -+ ":services_network_public_cpp_features_cc", -+ ":services_network_public_cpp_features_h", -+ ":third_party_blink_common_features_cc", -+ ":third_party_blink_common_features_h", -+ ":ui_base_features_cc", -+ ":ui_base_features_h", -+ ] -+} -diff --git a/cromite_flags/chrome/browser/about_flags_cc/placeholder.txt b/cromite_flags/chrome/browser/about_flags_cc/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/chrome/browser/about_flags_cc/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/chrome/browser/browser_features_cc/placeholder.txt b/cromite_flags/chrome/browser/browser_features_cc/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/chrome/browser/browser_features_cc/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/chrome/browser/browser_features_h/placeholder.txt b/cromite_flags/chrome/browser/browser_features_h/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/chrome/browser/browser_features_h/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/placeholder.txt b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/chrome/browser/flags/android/chrome_feature_list_h/placeholder.txt b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_h/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_h/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/chrome/browser/ui/ui_features_cc/placeholder.txt b/cromite_flags/chrome/browser/ui/ui_features_cc/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/chrome/browser/ui/ui_features_cc/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/chrome/common/chrome_features_cc/placeholder.txt b/cromite_flags/chrome/common/chrome_features_cc/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/chrome/common/chrome_features_cc/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/chrome/common/chrome_features_h/placeholder.txt b/cromite_flags/chrome/common/chrome_features_h/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/chrome/common/chrome_features_h/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/components/content_settings/core/common/features_cc/placeholder.txt b/cromite_flags/components/content_settings/core/common/features_cc/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/components/content_settings/core/common/features_cc/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/components/offline_pages/core/offline_page_feature_cc/placeholder.txt b/cromite_flags/components/offline_pages/core/offline_page_feature_cc/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/components/offline_pages/core/offline_page_feature_cc/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/components/offline_pages/core/offline_page_feature_h/placeholder.txt b/cromite_flags/components/offline_pages/core/offline_page_feature_h/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/components/offline_pages/core/offline_page_feature_h/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/components/password_manager/core/browser/features/password_features_cc/placeholder.txt b/cromite_flags/components/password_manager/core/browser/features/password_features_cc/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/components/password_manager/core/browser/features/password_features_cc/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/components/permissions/features_cc/placeholder.txt b/cromite_flags/components/permissions/features_cc/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/components/permissions/features_cc/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/content/common/features_cc/placeholder.txt b/cromite_flags/content/common/features_cc/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/content/common/features_cc/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/content/public/common/content_features_cc/placeholder.txt b/cromite_flags/content/public/common/content_features_cc/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/content/public/common/content_features_cc/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/content/public/common/content_features_h/placeholder.txt b/cromite_flags/content/public/common/content_features_h/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/content/public/common/content_features_h/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/media/base/media_switches_cc/placeholder.txt b/cromite_flags/media/base/media_switches_cc/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/media/base/media_switches_cc/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/media/base/media_switches_h/placeholder.txt b/cromite_flags/media/base/media_switches_h/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/media/base/media_switches_h/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/net/base/features_cc/placeholder.txt b/cromite_flags/net/base/features_cc/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/net/base/features_cc/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/net/base/features_h/placeholder.txt b/cromite_flags/net/base/features_h/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/net/base/features_h/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/services/network/public/cpp/features_cc/placeholder.txt b/cromite_flags/services/network/public/cpp/features_cc/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/services/network/public/cpp/features_cc/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/services/network/public/cpp/features_h/placeholder.txt b/cromite_flags/services/network/public/cpp/features_h/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/services/network/public/cpp/features_h/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/third_party/blink/common/features_cc/placeholder.txt b/cromite_flags/third_party/blink/common/features_cc/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/third_party/blink/common/features_cc/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/third_party/blink/common/features_h/placeholder.txt b/cromite_flags/third_party/blink/common/features_h/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/third_party/blink/common/features_h/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/ui/base/features_cc/placeholder.txt b/cromite_flags/ui/base/features_cc/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/ui/base/features_cc/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -diff --git a/cromite_flags/ui/base/features_h/placeholder.txt b/cromite_flags/ui/base/features_h/placeholder.txt -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/ui/base/features_h/placeholder.txt -@@ -0,0 +1 @@ -+this file is intentionally empty -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 -@@ -1730,5 +1730,5 @@ uint32_t GetPassthroughAudioFormats() { - return 0; - #endif // BUILDFLAG(ENABLE_PASSTHROUGH_AUDIO_CODECS) - } -- -+#include "cromite_flags/media_base_media_switches_cc.inc" - } // namespace media -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 -@@ -609,5 +609,5 @@ MEDIA_EXPORT bool IsOutOfProcessVideoDecodingEnabled(); - MEDIA_EXPORT uint32_t GetPassthroughAudioFormats(); - - } // namespace media -- -+#include "cromite_flags/media_base_media_switches_h.inc" - #endif // MEDIA_BASE_MEDIA_SWITCHES_H_ -diff --git a/net/base/features.cc b/net/base/features.cc ---- a/net/base/features.cc -+++ b/net/base/features.cc -@@ -839,4 +839,5 @@ BASE_FEATURE_PARAM(size_t, - "cache_size", - 64); - -+#include "cromite_flags/net_base_features_cc.inc" - } // namespace net::features -diff --git a/net/base/features.h b/net/base/features.h ---- a/net/base/features.h -+++ b/net/base/features.h -@@ -935,6 +935,7 @@ NET_EXPORT BASE_DECLARE_FEATURE(kDnsFilteringDetails); - NET_EXPORT BASE_DECLARE_FEATURE(kUpdateIsMainFrameOriginRecentlyAccessed); - NET_EXPORT BASE_DECLARE_FEATURE_PARAM(size_t, kRecentlyAccessedOriginCacheSize); - -+#include "cromite_flags/net_base_features_h.inc" - } // namespace net::features - - #endif // NET_BASE_FEATURES_H_ -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 -@@ -587,4 +587,5 @@ BASE_FEATURE_PARAM(bool, - "url_loader", - true); - -+#include "cromite_flags/services_network_public_cpp_features_cc.inc" - } // namespace network::features -diff --git a/services/network/public/cpp/features.h b/services/network/public/cpp/features.h ---- a/services/network/public/cpp/features.h -+++ b/services/network/public/cpp/features.h -@@ -361,6 +361,7 @@ BASE_DECLARE_FEATURE_PARAM(bool, kNetworkServiceTaskSchedulerResourceScheduler); - COMPONENT_EXPORT(NETWORK_CPP_FLAGS_AND_SWITCHES) - BASE_DECLARE_FEATURE_PARAM(bool, kNetworkServiceTaskSchedulerURLLoader); - -+#include "cromite_flags/services_network_public_cpp_features_h.inc" - } // namespace network::features - - #endif // SERVICES_NETWORK_PUBLIC_CPP_FEATURES_H_ -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 -@@ -2633,4 +2633,5 @@ bool IsXrDevice() { - // - // DO NOT ADD NEW FEATURES HERE. - -+#include "cromite_flags/third_party_blink_common_features_cc.inc" - } // namespace blink::features -diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h ---- a/third_party/blink/public/common/features.h -+++ b/third_party/blink/public/common/features.h -@@ -1917,6 +1917,7 @@ BLINK_COMMON_EXPORT bool IsXrDevice(); - // - // DO NOT ADD NEW FEATURES HERE. - -+#include "cromite_flags/third_party_blink_common_features_h.inc" - } // namespace features - } // namespace blink - -diff --git a/ui/base/ui_base_features.cc b/ui/base/ui_base_features.cc ---- a/ui/base/ui_base_features.cc -+++ b/ui/base/ui_base_features.cc -@@ -434,4 +434,5 @@ BASE_FEATURE(kUseSystemDefaultAccentColors, base::FEATURE_ENABLED_BY_DEFAULT); - - BASE_FEATURE(kStringWidthCache, base::FEATURE_DISABLED_BY_DEFAULT); - -+#include "cromite_flags/ui_base_features_cc.inc" - } // namespace features -diff --git a/ui/base/ui_base_features.h b/ui/base/ui_base_features.h ---- a/ui/base/ui_base_features.h -+++ b/ui/base/ui_base_features.h -@@ -267,6 +267,7 @@ BASE_DECLARE_FEATURE(kUseSystemDefaultAccentColors); - COMPONENT_EXPORT(UI_BASE_FEATURES) - BASE_DECLARE_FEATURE(kStringWidthCache); - -+#include "cromite_flags/ui_base_features_h.inc" - } // namespace features - - #endif // UI_BASE_UI_BASE_FEATURES_H_ --- diff --git a/build/cromite_patches/Add-custom-tab-intents-privacy-option.patch b/build/cromite_patches/Add-custom-tab-intents-privacy-option.patch deleted file mode 100644 index c5ecd490..00000000 --- a/build/cromite_patches/Add-custom-tab-intents-privacy-option.patch +++ /dev/null @@ -1,438 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Wed, 29 Aug 2018 11:03:44 +0200 -Subject: Add custom tab intents privacy option - -Add custom tab intents privacy option and force -open external links in incognito flag. -Use the CCT ephemeral mode. - -Flags are mutually exclusive. - -See also: https://github.com/bromite/bromite/issues/1474 - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../java/res/xml/privacy_preferences.xml | 15 ++++++ - .../browser/LaunchIntentDispatcher.java | 21 ++++++++ - .../CustomTabIntentDataProvider.java | 22 ++++---- - .../customtabs/CustomTabsConnection.java | 3 +- - .../IncognitoCustomTabIntentDataProvider.java | 14 +++++ - .../privacy/settings/PrivacySettings.java | 51 +++++++++++++++++++ - .../flags/android/chrome_feature_list.cc | 5 +- - .../browser/flags/ChromeFeatureList.java | 3 ++ - .../chrome/browser/tab/TabAssociatedApp.java | 6 ++- - ...Add-custom-tab-intents-privacy-option.grdp | 25 +++++++++ - .../OriginVerifier.java | 5 ++ - .../core/common/language_experiments.cc | 1 + - .../add-custom-tab-intents-privacy-option.inc | 1 + - 13 files changed, 158 insertions(+), 14 deletions(-) - create mode 100644 chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Add-custom-tab-intents-privacy-option.grdp - create mode 100644 cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/add-custom-tab-intents-privacy-option.inc - -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 -@@ -52,6 +52,21 @@ found in the LICENSE file. - android:key="cromite_flags" - android:title="@string/cromite_flags_title" - app:url="@string/cromite_flags_url" /> -+ -+ -+ - { -+ if ((true)) return; // Disable CCTPostMessageAPI - // Attempt to verify origin synchronously. If successful directly initialize - // postMessage channel for session. - Uri verifiedOrigin = verifyOriginForSession(session, uid, postMessageOrigin); -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabIntentDataProvider.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabIntentDataProvider.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/IncognitoCustomTabIntentDataProvider.java -@@ -43,6 +43,9 @@ import org.chromium.components.browser_ui.widget.TintedDrawable; - import java.util.ArrayList; - import java.util.List; - -+import org.chromium.base.ContextUtils; -+import org.chromium.chrome.browser.privacy.settings.PrivacySettings; -+ - /** - * A model class that parses the incoming intent for incognito Custom Tabs specific customization - * data. -@@ -125,6 +128,9 @@ public class IncognitoCustomTabIntentDataProvider extends BrowserServicesIntentD - } - - private static boolean isIntentFromThirdPartyAllowed() { -+ if (ContextUtils.getAppSharedPreferences() -+ .getBoolean(PrivacySettings.PREF_OPEN_EXTERNAL_LINKS_INCOGNITO, false)) -+ return true; - return ChromeFeatureList.sCctIncognitoAvailableToThirdParty.isEnabled(); - } - -@@ -222,6 +228,10 @@ public class IncognitoCustomTabIntentDataProvider extends BrowserServicesIntentD - } - - public static boolean isValidIncognitoIntent(Intent intent, boolean recordMetrics) { -+ if (ContextUtils.getAppSharedPreferences() -+ .getBoolean(PrivacySettings.PREF_OPEN_EXTERNAL_LINKS_INCOGNITO, false)) { -+ return true; -+ } - if (!isIncognitoRequested(intent)) return false; - var session = SessionHolder.getSessionHolderFromIntent(intent); - if (isIntentFromThirdPartyAllowed() -@@ -332,6 +342,10 @@ public class IncognitoCustomTabIntentDataProvider extends BrowserServicesIntentD - - @Override - public @CustomTabProfileType int getCustomTabMode() { -+ if (ContextUtils.getAppSharedPreferences() -+ .getBoolean(PrivacySettings.PREF_OPEN_EXTERNAL_LINKS_INCOGNITO, false)) { -+ return CustomTabProfileType.EPHEMERAL; -+ } - return CustomTabProfileType.INCOGNITO; - } - -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 -@@ -11,6 +11,7 @@ import android.content.Context; - import android.content.Intent; - import android.content.SharedPreferences; - import android.graphics.drawable.Drawable; -+import android.os.Build; - import android.os.Bundle; - import android.text.SpannableString; - import android.text.style.ClickableSpan; -@@ -79,6 +80,15 @@ import org.chromium.ui.text.SpanApplier; - import java.util.concurrent.TimeUnit; - import java.util.function.Consumer; - -+import android.app.role.RoleManager; -+import android.content.Context; -+import android.content.Intent; -+import android.content.pm.ResolveInfo; -+import android.provider.Settings; -+import android.text.TextUtils; -+import org.chromium.base.IntentUtils; -+import org.chromium.base.PackageManagerUtils; -+ - import androidx.preference.PreferenceCategory; - import org.chromium.chrome.browser.contextualsearch.ContextualSearchManager; - import org.chromium.base.shared_preferences.SharedPreferencesManager; -@@ -153,6 +163,9 @@ public class PrivacySettings extends ChromeBaseSettingsFragment - startTag, endTag, new ChromeClickableSpan(context, onClickCallback)); - } - -+ private ChromeSwitchPreference allowCustomTabIntentsPref; -+ private ChromeSwitchPreference openExternalLinksPref; -+ - @Override - public void onCreatePreferencesCromite(@Nullable Bundle savedInstanceState, @Nullable String rootKey) { - mPageTitle.set(getString(R.string.prefs_privacy_security)); -@@ -384,6 +397,9 @@ public class PrivacySettings extends ChromeBaseSettingsFragment - new SpanApplier.SpanInfo("", "", servicesLink)); - } - -+ public static final String PREF_ALLOW_CUSTOM_TAB_INTENTS = "allow_custom_tab_intents"; -+ public static final String PREF_OPEN_EXTERNAL_LINKS_INCOGNITO = "open_external_links_incognito"; -+ - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - String key = preference.getKey(); -@@ -404,6 +420,31 @@ public class PrivacySettings extends ChromeBaseSettingsFragment - } else if (PREF_SEARCH_SUGGESTIONS.equals(key)) { - UserPrefs.get(getProfile()) - .setBoolean(Pref.SEARCH_SUGGEST_ENABLED, (boolean) newValue); -+ } else if (PREF_ALLOW_CUSTOM_TAB_INTENTS.equals(key)) { -+ SharedPreferences.Editor sharedPreferencesEditor = ContextUtils.getAppSharedPreferences().edit(); -+ sharedPreferencesEditor.putBoolean(PREF_ALLOW_CUSTOM_TAB_INTENTS, (boolean)newValue); -+ sharedPreferencesEditor.apply(); -+ // check default browser -+ if ((boolean)newValue) { -+ ResolveInfo info = PackageManagerUtils.resolveDefaultWebBrowserActivity(); -+ if (info == null || info.match == 0 || -+ !TextUtils.equals(ContextUtils.getApplicationContext().getPackageName(), -+ info.activityInfo.packageName)) { -+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { -+ RoleManager roleManager = (RoleManager) getContext().getSystemService(Context.ROLE_SERVICE); -+ Intent intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_BROWSER); -+ startActivityForResult(intent, 0); -+ } else { -+ Intent intent = new Intent(Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS); -+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); -+ IntentUtils.safeStartActivity(getContext(), intent); -+ } -+ } -+ } -+ } else if (PREF_OPEN_EXTERNAL_LINKS_INCOGNITO.equals(key)) { -+ SharedPreferences.Editor sharedPreferencesEditor = ContextUtils.getAppSharedPreferences().edit(); -+ sharedPreferencesEditor.putBoolean(PREF_OPEN_EXTERNAL_LINKS_INCOGNITO, (boolean)newValue); -+ sharedPreferencesEditor.apply(); - } - return true; - } -@@ -436,6 +477,16 @@ public class PrivacySettings extends ChromeBaseSettingsFragment - UserPrefs.get(getProfile()).getBoolean(Pref.CAN_MAKE_PAYMENT_ENABLED)); - } - -+ allowCustomTabIntentsPref = -+ (ChromeSwitchPreference) findPreference(PREF_ALLOW_CUSTOM_TAB_INTENTS); -+ allowCustomTabIntentsPref.setOnPreferenceChangeListener(this); -+ allowCustomTabIntentsPref.setManagedPreferenceDelegate(mManagedPreferenceDelegate); -+ -+ openExternalLinksPref = -+ (ChromeSwitchPreference) findPreference(PREF_OPEN_EXTERNAL_LINKS_INCOGNITO); -+ openExternalLinksPref.setOnPreferenceChangeListener(this); -+ openExternalLinksPref.setManagedPreferenceDelegate(mManagedPreferenceDelegate); -+ - Preference doNotTrackPref = findPreference(PREF_DO_NOT_TRACK); - if (doNotTrackPref != null) { - doNotTrackPref.setSummary( -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 -@@ -909,8 +909,9 @@ BASE_FEATURE(kMagicStackAndroid, base::FEATURE_ENABLED_BY_DEFAULT); - // Enables an experimental feature which forces mayLaunchUrl to use a different - // storage partition. This may reduce performance. This should not be enabled by - // default. --BASE_FEATURE(kMayLaunchUrlUsesSeparateStoragePartition, -- base::FEATURE_DISABLED_BY_DEFAULT); -+CROMITE_FEATURE(kMayLaunchUrlUsesSeparateStoragePartition, -+ "MayLaunchUrlUsesSeparateStoragePartition", -+ base::FEATURE_DISABLED_BY_DEFAULT); - - BASE_FEATURE(kMediaIndicatorsAndroid, base::FEATURE_DISABLED_BY_DEFAULT); - -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 -@@ -991,6 +991,8 @@ public abstract class ChromeFeatureList { - MOST_VISITED_TILES_CUSTOMIZATION, - /* defaultValue= */ false, - /* defaultValueInTests= */ true); -+ public static final CachedFlag sMayLaunchurlUsesSeparateStoragePartition = -+ newCachedFlag(MAYLAUNCHURL_USES_SEPARATE_STORAGE_PARTITION, false); - public static final CachedFlag sMostVisitedTilesReselect = - newCachedFlag(MOST_VISITED_TILES_RESELECT, false); - public static final CachedFlag sMultiInstanceApplicationStatusCleanup = -@@ -1224,6 +1226,7 @@ public abstract class ChromeFeatureList { - sMiniOriginBar, - sMitigateLegacySearchEnginePromoOverlap, - sMostVisitedTilesCustomization, -+ sMayLaunchurlUsesSeparateStoragePartition, - sMostVisitedTilesReselect, - sMultiInstanceApplicationStatusCleanup, - sMvcUpdateViewWhenModelChanged, -diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabAssociatedApp.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabAssociatedApp.java ---- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabAssociatedApp.java -+++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabAssociatedApp.java -@@ -88,7 +88,11 @@ public final class TabAssociatedApp extends TabWebContentsUserData implements Im - public static boolean isOpenedFromExternalApp(Tab tab) { - TabAssociatedApp app = get(tab); - if (app == null) return false; -- -+ if (ContextUtils.getAppSharedPreferences() -+ .getBoolean("open_external_links_incognito", false) && -+ tab.isIncognito() && -+ tab.getLaunchType() == TabLaunchType.FROM_EXTERNAL_APP) -+ return true; - String packageName = ContextUtils.getApplicationContext().getPackageName(); - return tab.getLaunchType() == TabLaunchType.FROM_EXTERNAL_APP - && !TextUtils.equals(app.getAppId(), packageName); -diff --git a/chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Add-custom-tab-intents-privacy-option.grdp b/chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Add-custom-tab-intents-privacy-option.grdp -new file mode 100644 ---- /dev/null -+++ b/chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Add-custom-tab-intents-privacy-option.grdp -@@ -0,0 +1,25 @@ -+ -+ -+ -+ -+ Allow custom tab intents. -+ -+ -+ Allow applications to open custom tab intents, similar to webview. To work, Cromite must be set as the default browser. -+ -+ -+ -+ Use ephemeral mode for CCT -+ -+ -+ Use a separate storage partition when opening custom tab intents -+ -+ -+ -+ -+ Open external links in incognito -+ -+ -+ Force the opening of all external links in incognito mode and uses the CCT ephemeral mode. Caution: there is only one incognito profile. -+ -+ -diff --git a/components/content_relationship_verification/android/java/src/org/chromium/components/content_relationship_verification/OriginVerifier.java b/components/content_relationship_verification/android/java/src/org/chromium/components/content_relationship_verification/OriginVerifier.java ---- a/components/content_relationship_verification/android/java/src/org/chromium/components/content_relationship_verification/OriginVerifier.java -+++ b/components/content_relationship_verification/android/java/src/org/chromium/components/content_relationship_verification/OriginVerifier.java -@@ -181,6 +181,11 @@ public abstract class OriginVerifier { - assert mNativeOriginVerifier != 0 - : "Either provide a browserContextHandle to " - + "OriginVerifier#ctor or call initNativeOriginVerifier."; -+ if ((true)) { -+ PostTask.runOrPostTask( -+ TaskTraits.UI_DEFAULT, new VerifiedCallback(origin, false, null)); -+ return; -+ } - - String scheme = origin.uri().getScheme(); - String host = assumeNonNull(origin.uri().getHost()); -diff --git a/components/language/core/common/language_experiments.cc b/components/language/core/common/language_experiments.cc ---- a/components/language/core/common/language_experiments.cc -+++ b/components/language/core/common/language_experiments.cc -@@ -20,4 +20,5 @@ BASE_FEATURE(kTranslateOpenSettings, base::FEATURE_DISABLED_BY_DEFAULT); - - BASE_FEATURE(kDisableGeoLanguageModel, base::FEATURE_ENABLED_BY_DEFAULT); - -+SET_CROMITE_FEATURE_DISABLED(kCctAutoTranslate); - } // namespace language -diff --git a/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/add-custom-tab-intents-privacy-option.inc b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/add-custom-tab-intents-privacy-option.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/add-custom-tab-intents-privacy-option.inc -@@ -0,0 +1 @@ -+// explicitly empty --- diff --git a/build/cromite_patches/Add-exit-menu-item.patch b/build/cromite_patches/Add-exit-menu-item.patch deleted file mode 100644 index 543cf846..00000000 --- a/build/cromite_patches/Add-exit-menu-item.patch +++ /dev/null @@ -1,121 +0,0 @@ -From: Serg -Date: Tue, 31 Jan 2017 22:12:27 -0500 -Subject: Add exit menu item - -Corrected Exit functionality - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - chrome/android/java/res/values/ids.xml | 1 + - .../org/chromium/chrome/browser/ChromeTabbedActivity.java | 4 ++++ - .../org/chromium/chrome/browser/app/ChromeActivity.java | 6 ++++++ - .../chrome/browser/init/ChromeLifetimeController.java | 2 ++ - .../tabbed_mode/TabbedAppMenuPropertiesDelegate.java | 7 +++++++ - .../browser/ui/android/strings/android_chrome_strings.grd | 3 +++ - 6 files changed, 23 insertions(+) - -diff --git a/chrome/android/java/res/values/ids.xml b/chrome/android/java/res/values/ids.xml ---- a/chrome/android/java/res/values/ids.xml -+++ b/chrome/android/java/res/values/ids.xml -@@ -123,6 +123,7 @@ found in the LICENSE file. - - - -+ - - - -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 -@@ -358,6 +358,8 @@ import java.util.Set; - import java.util.concurrent.atomic.AtomicBoolean; - import java.util.function.Supplier; - -+import org.chromium.chrome.browser.lifetime.ApplicationLifetime; -+ - /** - * 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. -@@ -3882,6 +3884,8 @@ public class ChromeTabbedActivity extends ChromeActivity { - .closeTabs( - TabClosureParams.closeTab(currentTab).build(), /* allowDialog= */ true); - RecordUserAction.record("MobileTabClosed"); -+ } else if (id == R.id.exit_id) { -+ ApplicationLifetime.terminate(false); - } else if (id == R.id.close_all_tabs_menu_id) { - boolean allowUndo = TabClosureParamsUtils.shouldAllowUndo(triggeringMotion); - -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 -@@ -63,6 +63,7 @@ import org.chromium.base.supplier.UnownedUserDataSupplier; - import org.chromium.chrome.R; - import org.chromium.chrome.browser.ActivityTabProvider; - import org.chromium.chrome.browser.ActivityUtils; -+import org.chromium.chrome.browser.lifetime.ApplicationLifetime; - import org.chromium.chrome.browser.ChromeActivitySessionTracker; - import org.chromium.chrome.browser.ChromeApplicationImpl; - import org.chromium.chrome.browser.ChromeKeyboardVisibilityDelegate; -@@ -2529,6 +2530,11 @@ public abstract class ChromeActivity extends AsyncInitializationActivity - return true; - } - -+ if (id == R.id.exit_id) { -+ ApplicationLifetime.terminate(false); -+ return true; -+ } -+ - if (id == R.id.update_menu_id) { - UpdateMenuItemHelper.getInstance( - getProfileProviderSupplier().get().getOriginalProfile()) -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeLifetimeController.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeLifetimeController.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeLifetimeController.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeLifetimeController.java -@@ -20,6 +20,7 @@ import org.chromium.build.annotations.MonotonicNonNull; - import org.chromium.build.annotations.NullMarked; - import org.chromium.chrome.browser.BrowserRestartActivity; - import org.chromium.chrome.browser.lifetime.ApplicationLifetime; -+import org.chromium.chrome.browser.incognito.IncognitoNotificationManager; - - /** - * Answers requests to kill and (potentially) restart Chrome's main browser process. -@@ -76,6 +77,7 @@ class ChromeLifetimeController - - @Override - public void onTerminate(boolean restart) { -+ IncognitoNotificationManager.dismissIncognitoNotification(); - mRestartChromeOnDestroy = restart; - - // Tell all Chrome Activities to finish themselves. -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java -@@ -410,6 +410,13 @@ public class TabbedAppMenuPropertiesDelegate extends AppMenuPropertiesDelegateIm - maybeAddDividerLine(modelList, R.id.menu_item_content_filter_divider_line_id); - modelList.add(buildContentFilterHelpCenterMenuItem(currentTab)); - } -+ -+ modelList.add(new MVCListAdapter.ListItem( -+ AppMenuHandler.AppMenuItemType.STANDARD, -+ buildModelForStandardMenuItem( -+ R.id.exit_id, -+ R.string.menu_exit, -+ shouldShowIconBeforeItem() ? R.drawable.ic_exit_to_app_white_24dp : 0))); - } - - private Runnable buildUpdateStateChangedObserver() { -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 -@@ -4317,6 +4317,9 @@ To change this setting, BEGIN_LINKdelete the Chrome d - - Dark theme - -+ -+ Exit -+ - - Appearance - --- diff --git a/build/cromite_patches/Add-flag-for-omnibox-autocomplete-filtering.patch b/build/cromite_patches/Add-flag-for-omnibox-autocomplete-filtering.patch deleted file mode 100644 index 9e5e7811..00000000 --- a/build/cromite_patches/Add-flag-for-omnibox-autocomplete-filtering.patch +++ /dev/null @@ -1,137 +0,0 @@ -From: Blaise -Date: Sat, 22 Aug 2020 08:52:40 -0500 -Subject: Add flag for omnibox autocomplete filtering - -Adds a flag that restricts whether search history, clipboard, bookmarks -and internal chrome:// pages will be used for the autocomplete results. - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../browser/autocomplete_controller.cc | 10 ++++++ - .../omnibox/browser/history_url_provider.cc | 3 ++ - components/omnibox/browser/search_provider.cc | 4 +++ - components/url_formatter/url_fixer.cc | 4 +++ - ...lag-for-omnibox-autocomplete-filtering.inc | 32 +++++++++++++++++++ - 5 files changed, 53 insertions(+) - create mode 100644 cromite_flags/chrome/browser/about_flags_cc/Add-flag-for-omnibox-autocomplete-filtering.inc - -diff --git a/components/omnibox/browser/autocomplete_controller.cc b/components/omnibox/browser/autocomplete_controller.cc ---- a/components/omnibox/browser/autocomplete_controller.cc -+++ b/components/omnibox/browser/autocomplete_controller.cc -@@ -23,6 +23,7 @@ - - #include "base/check_op.h" - #include "base/containers/contains.h" -+#include "base/command_line.h" - #include "base/feature_list.h" - #include "base/format_macros.h" - #include "base/functional/bind.h" -@@ -571,6 +572,15 @@ AutocompleteController::AutocompleteController( - provider_client_->GetOmniboxTriggeredFeatureService()), - steady_state_omnibox_position_( - metrics::OmniboxEventProto::UNKNOWN_POSITION) { -+ if (base::CommandLine::ForCurrentProcess()->HasSwitch("omnibox-autocomplete-filtering")) { -+ const std::string flag_value = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII("omnibox-autocomplete-filtering"); -+ provider_types &= AutocompleteProvider::TYPE_KEYWORD | AutocompleteProvider::TYPE_SEARCH | -+ AutocompleteProvider::TYPE_HISTORY_URL | AutocompleteProvider::TYPE_BOOKMARK | AutocompleteProvider::TYPE_BUILTIN; -+ if (!base::Contains(flag_value, "bookmarks")) -+ provider_types &= ~AutocompleteProvider::TYPE_BOOKMARK; -+ if (!base::Contains(flag_value, "chrome")) -+ provider_types &= ~AutocompleteProvider::TYPE_BUILTIN; -+ } - provider_types &= ~OmniboxFieldTrial::GetDisabledProviderTypes(); - - // Providers run in the order they're added. Async providers should run first -diff --git a/components/omnibox/browser/history_url_provider.cc b/components/omnibox/browser/history_url_provider.cc ---- a/components/omnibox/browser/history_url_provider.cc -+++ b/components/omnibox/browser/history_url_provider.cc -@@ -488,6 +488,9 @@ void HistoryURLProvider::Start(const AutocompleteInput& input, - if (fixed_up_input.type() != metrics::OmniboxInputType::QUERY) - matches_.push_back(what_you_typed_match); - -+ if (base::CommandLine::ForCurrentProcess()->HasSwitch("omnibox-autocomplete-filtering")) -+ return; -+ - // We'll need the history service to run both passes, so try to obtain it. - history::HistoryService* const history_service = - client()->GetHistoryService(); -diff --git a/components/omnibox/browser/search_provider.cc b/components/omnibox/browser/search_provider.cc ---- a/components/omnibox/browser/search_provider.cc -+++ b/components/omnibox/browser/search_provider.cc -@@ -17,6 +17,7 @@ - #include "base/base64.h" - #include "base/feature_list.h" - #include "base/functional/bind.h" -+#include "base/command_line.h" - #include "base/functional/callback.h" - #include "base/i18n/break_iterator.h" - #include "base/i18n/case_conversion.h" -@@ -637,6 +638,9 @@ void SearchProvider::Run(bool query_is_private) { - } - - void SearchProvider::DoHistoryQuery(bool minimal_changes) { -+ if (base::CommandLine::ForCurrentProcess()->HasSwitch("omnibox-autocomplete-filtering")) -+ return; -+ - // The history query results are synchronous, so if minimal_changes is true, - // we still have the last results and don't need to do anything. - if (minimal_changes) -diff --git a/components/url_formatter/url_fixer.cc b/components/url_formatter/url_fixer.cc ---- a/components/url_formatter/url_fixer.cc -+++ b/components/url_formatter/url_fixer.cc -@@ -11,6 +11,8 @@ - - #include "base/check_op.h" - #include "base/compiler_specific.h" -+#include "base/containers/contains.h" -+#include "base/command_line.h" - #include "base/files/file_path.h" - #include "base/files/file_util.h" - #include "base/i18n/char_iterator.h" -@@ -644,6 +646,8 @@ GURL FixupURLInternal(const std::string& text, - - FixupHost(trimmed, parts.host, parts.scheme.is_valid(), desired_tld, &url); - if (chrome_url && !parts.host.is_valid()) { -+ if (!base::CommandLine::ForCurrentProcess()->HasSwitch("omnibox-autocomplete-filtering") || -+ base::Contains(base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII("omnibox-autocomplete-filtering"), "chrome")) - url.append(kChromeUIDefaultHost); - } - FixupPort(trimmed, parts.port, &url); -diff --git a/cromite_flags/chrome/browser/about_flags_cc/Add-flag-for-omnibox-autocomplete-filtering.inc b/cromite_flags/chrome/browser/about_flags_cc/Add-flag-for-omnibox-autocomplete-filtering.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/chrome/browser/about_flags_cc/Add-flag-for-omnibox-autocomplete-filtering.inc -@@ -0,0 +1,32 @@ -+#if BUILDFLAG(IS_ANDROID) -+ -+#ifdef FEATURE_PARAM_SECTION -+ -+const FeatureEntry::Choice kOmniboxAutocompleteFiltering[] = { -+ {flags_ui::kGenericExperimentChoiceDefault, "", ""}, -+ {"Search suggestions only", -+ "omnibox-autocomplete-filtering", -+ "search"}, -+ {"Search suggestions and bookmarks", -+ "omnibox-autocomplete-filtering", -+ "search-bookmarks"}, -+ {"Search suggestions and internal chrome pages", -+ "omnibox-autocomplete-filtering", -+ "search-chrome"}, -+ {"Search suggestions, bookmarks, and internal chrome pages", -+ "omnibox-autocomplete-filtering", -+ "search-bookmarks-chrome"}, -+}; -+ -+#endif -+ -+#ifdef FLAG_SECTION -+ -+ {"omnibox-autocomplete-filtering", -+ "Omnibox Autocomplete Filtering", -+ "Restrict omnibox autocomplete results to a combination of search suggestions (if enabled), bookmarks, and internal chrome pages.", -+ kOsAll, MULTI_VALUE_TYPE(kOmniboxAutocompleteFiltering)}, -+ -+#endif -+ -+#endif --- diff --git a/build/cromite_patches/Add-flag-for-save-data-header.patch b/build/cromite_patches/Add-flag-for-save-data-header.patch deleted file mode 100644 index da2a0f9c..00000000 --- a/build/cromite_patches/Add-flag-for-save-data-header.patch +++ /dev/null @@ -1,73 +0,0 @@ -From: Wengling Chen -Date: Mon, 1 Feb 2021 19:18:55 +0200 -Subject: Add flag for save-data-header - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../loader/browser_initiated_resource_request.cc | 8 ++++++++ - .../about_flags_cc/Add-flag-for-save-data-header.inc | 10 ++++++++++ - .../cpp/features_cc/Add-flag-for-save-data-header.inc | 4 ++++ - .../cpp/features_h/Add-flag-for-save-data-header.inc | 1 + - 4 files changed, 23 insertions(+) - create mode 100644 cromite_flags/chrome/browser/about_flags_cc/Add-flag-for-save-data-header.inc - create mode 100644 cromite_flags/services/network/public/cpp/features_cc/Add-flag-for-save-data-header.inc - create mode 100644 cromite_flags/services/network/public/cpp/features_h/Add-flag-for-save-data-header.inc - -diff --git a/content/browser/loader/browser_initiated_resource_request.cc b/content/browser/loader/browser_initiated_resource_request.cc ---- a/content/browser/loader/browser_initiated_resource_request.cc -+++ b/content/browser/loader/browser_initiated_resource_request.cc -@@ -4,6 +4,9 @@ - - #include "content/browser/loader/browser_initiated_resource_request.h" - -+#include "base/feature_list.h" -+#include "services/network/public/cpp/features.h" -+ - #include "content/public/browser/browser_context.h" - #include "content/public/browser/browser_thread.h" - #include "content/public/browser/content_browser_client.h" -@@ -37,8 +40,13 @@ void UpdateAdditionalHeadersForBrowserInitiatedRequest( - // Save-Data was previously included in hints for workers, thus we cannot - // remove it for the time being. If you're reading this, consider building - // permissions policies for workers and/or deprecating this inclusion. -+ bool setHeader = false; - if (is_for_worker_script && - GetContentClient()->browser()->IsDataSaverEnabled(browser_context)) { -+ setHeader = true; -+ } -+ setHeader |= base::FeatureList::IsEnabled(network::features::kEnableSaveDataHeader); -+ if (setHeader) { - if (should_update_existing_headers) { - headers->RemoveHeader("Save-Data"); - } -diff --git a/cromite_flags/chrome/browser/about_flags_cc/Add-flag-for-save-data-header.inc b/cromite_flags/chrome/browser/about_flags_cc/Add-flag-for-save-data-header.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/chrome/browser/about_flags_cc/Add-flag-for-save-data-header.inc -@@ -0,0 +1,10 @@ -+ -+#ifdef FLAG_SECTION -+ -+ // Bromite save data header -+ {"enable-save-data-header", -+ "Enable save-data header", -+ "Enable save-data header without enabling Data Saver.", kOsAll, -+ FEATURE_VALUE_TYPE(network::features::kEnableSaveDataHeader)}, -+ -+#endif -diff --git a/cromite_flags/services/network/public/cpp/features_cc/Add-flag-for-save-data-header.inc b/cromite_flags/services/network/public/cpp/features_cc/Add-flag-for-save-data-header.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/services/network/public/cpp/features_cc/Add-flag-for-save-data-header.inc -@@ -0,0 +1,4 @@ -+// Enable save-data header separately (without enabled data reduction service). -+CROMITE_FEATURE(kEnableSaveDataHeader, -+ "EnableSaveDataHeader", -+ base::FEATURE_DISABLED_BY_DEFAULT); -diff --git a/cromite_flags/services/network/public/cpp/features_h/Add-flag-for-save-data-header.inc b/cromite_flags/services/network/public/cpp/features_h/Add-flag-for-save-data-header.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/services/network/public/cpp/features_h/Add-flag-for-save-data-header.inc -@@ -0,0 +1 @@ -+COMPONENT_EXPORT(NETWORK_CPP) BASE_DECLARE_FEATURE(kEnableSaveDataHeader); --- diff --git a/build/cromite_patches/Add-flag-to-configure-maximum-connections-per-host.patch b/build/cromite_patches/Add-flag-to-configure-maximum-connections-per-host.patch deleted file mode 100644 index a38a6369..00000000 --- a/build/cromite_patches/Add-flag-to-configure-maximum-connections-per-host.patch +++ /dev/null @@ -1,126 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Sun, 8 Jul 2018 22:42:04 +0200 -Subject: Add flag to configure maximum connections per host - -With the introduction of this flag it is possible to increase the maximum -allowed connections per host; this can however be detrimental to devices -with limited CPU/memory resources and it is disabled by default. - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../common/network_features.cc | 3 +++ - .../common/network_features.h | 4 ++++ - .../common/network_switch_list.h | 4 ++++ - .../spoof_checks/top_domains/BUILD.gn | 1 + - ...o-configure-maximum-connections-per-host.inc | 17 +++++++++++++++++ - net/socket/client_socket_pool_manager.cc | 17 +++++++++++++++++ - 6 files changed, 46 insertions(+) - create mode 100644 cromite_flags/chrome/browser/about_flags_cc/add-flag-to-configure-maximum-connections-per-host.inc - -diff --git a/components/network_session_configurator/common/network_features.cc b/components/network_session_configurator/common/network_features.cc ---- a/components/network_session_configurator/common/network_features.cc -+++ b/components/network_session_configurator/common/network_features.cc -@@ -8,4 +8,7 @@ - - namespace features { - -+const char kMaxConnectionsPerHostChoiceDefault[] = "6", -+ kMaxConnectionsPerHostChoice15[] = "15"; -+ - } // namespace features -diff --git a/components/network_session_configurator/common/network_features.h b/components/network_session_configurator/common/network_features.h ---- a/components/network_session_configurator/common/network_features.h -+++ b/components/network_session_configurator/common/network_features.h -@@ -10,6 +10,10 @@ - - namespace features { - -+NETWORK_SESSION_CONFIGURATOR_EXPORT extern const char kMaxConnectionsPerHostChoiceDefault[], -+ kMaxConnectionsPerHostChoice6[], -+ kMaxConnectionsPerHostChoice15[]; -+ - } // namespace features - - #endif // COMPONENTS_NETWORK_SESSION_CONFIGURATOR_COMMON_NETWORK_FEATURES_H_ -diff --git a/components/network_session_configurator/common/network_switch_list.h b/components/network_session_configurator/common/network_switch_list.h ---- a/components/network_session_configurator/common/network_switch_list.h -+++ b/components/network_session_configurator/common/network_switch_list.h -@@ -19,6 +19,10 @@ NETWORK_SWITCH(kEnableUserAlternateProtocolPorts, - // Enables the QUIC protocol. This is a temporary testing flag. - NETWORK_SWITCH(kEnableQuic, "enable-quic") - -+// Allows specifying a higher number of maximum connections per host -+// (15 instead of 6, mirroring the value Mozilla uses). -+NETWORK_SWITCH(kMaxConnectionsPerHost, "max-connections-per-host") -+ - // Ignores certificate-related errors. - NETWORK_SWITCH(kIgnoreCertificateErrors, "ignore-certificate-errors") - -diff --git a/components/url_formatter/spoof_checks/top_domains/BUILD.gn b/components/url_formatter/spoof_checks/top_domains/BUILD.gn ---- a/components/url_formatter/spoof_checks/top_domains/BUILD.gn -+++ b/components/url_formatter/spoof_checks/top_domains/BUILD.gn -@@ -90,6 +90,7 @@ executable("make_top_domain_list_variables") { - "//base:i18n", - "//components/url_formatter/spoof_checks/common_words:common", - "//third_party/icu", -+ "//components/network_session_configurator/common" - ] - if (is_ios) { - frameworks = [ "UIKit.framework" ] -diff --git a/cromite_flags/chrome/browser/about_flags_cc/add-flag-to-configure-maximum-connections-per-host.inc b/cromite_flags/chrome/browser/about_flags_cc/add-flag-to-configure-maximum-connections-per-host.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/chrome/browser/about_flags_cc/add-flag-to-configure-maximum-connections-per-host.inc -@@ -0,0 +1,17 @@ -+#ifdef FEATURE_PARAM_SECTION -+ -+const FeatureEntry::Choice kMaxConnectionsPerHostChoices[] = { -+ {features::kMaxConnectionsPerHostChoiceDefault, "", ""}, -+ {features::kMaxConnectionsPerHostChoice15, switches::kMaxConnectionsPerHost, "15"}, -+}; -+ -+#endif -+ -+#ifdef FLAG_SECTION -+ -+ {"max-connections-per-host", -+ "Maximum connections per host", -+ "Customize maximum allowed connections per host.", kOsAll, -+ MULTI_VALUE_TYPE(kMaxConnectionsPerHostChoices)}, -+ -+#endif -diff --git a/net/socket/client_socket_pool_manager.cc b/net/socket/client_socket_pool_manager.cc ---- a/net/socket/client_socket_pool_manager.cc -+++ b/net/socket/client_socket_pool_manager.cc -@@ -22,6 +22,10 @@ - #include "net/socket/client_socket_handle.h" - #include "net/socket/client_socket_pool.h" - #include "net/socket/connect_job.h" -+#include "components/network_session_configurator/common/network_switches.h" -+ -+#include "base/command_line.h" -+#include "base/strings/string_number_conversions.h" - #include "net/ssl/ssl_config.h" - #include "url/gurl.h" - #include "url/scheme_host_port.h" -@@ -187,6 +191,19 @@ void ClientSocketPoolManager::set_max_sockets_per_pool( - int ClientSocketPoolManager::max_sockets_per_group( - HttpNetworkSession::SocketPoolType pool_type) { - DCHECK_LT(pool_type, HttpNetworkSession::NUM_SOCKET_POOL_TYPES); -+ -+ if (pool_type == HttpNetworkSession::NORMAL_SOCKET_POOL) { -+ int maxConnectionsPerHost = 0; -+ auto value = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kMaxConnectionsPerHost); -+ if (!value.empty() && !base::StringToInt(value, &maxConnectionsPerHost)) { -+ LOG(DFATAL) << "--" << switches::kMaxConnectionsPerHost << " only accepts integers as arguments (\"" << value << "\" is invalid)"; -+ } -+ if (maxConnectionsPerHost != 0) { -+ return maxConnectionsPerHost; -+ } -+ // fallthrough for default value -+ } -+ - return g_max_sockets_per_group[pool_type]; - } - --- diff --git a/build/cromite_patches/Add-flag-to-control-video-playback-resume-feature.patch b/build/cromite_patches/Add-flag-to-control-video-playback-resume-feature.patch deleted file mode 100644 index 35bf730c..00000000 --- a/build/cromite_patches/Add-flag-to-control-video-playback-resume-feature.patch +++ /dev/null @@ -1,39 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Thu, 25 Oct 2018 23:13:34 +0200 -Subject: Add flag to control video playback resume feature - -Disable it by default on Android as it is everywhere else - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - ...lag-to-control-video-playback-resume-feature.inc | 13 +++++++++++++ - ...lag-to-control-video-playback-resume-feature.inc | 1 + - 2 files changed, 14 insertions(+) - create mode 100644 cromite_flags/chrome/browser/about_flags_cc/add-flag-to-control-video-playback-resume-feature.inc - create mode 100644 cromite_flags/media/base/media_switches_cc/add-flag-to-control-video-playback-resume-feature.inc - -diff --git a/cromite_flags/chrome/browser/about_flags_cc/add-flag-to-control-video-playback-resume-feature.inc b/cromite_flags/chrome/browser/about_flags_cc/add-flag-to-control-video-playback-resume-feature.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/chrome/browser/about_flags_cc/add-flag-to-control-video-playback-resume-feature.inc -@@ -0,0 +1,13 @@ -+#ifdef FLAG_SECTION -+ -+#if BUILDFLAG(IS_ANDROID) -+ -+ {"resume-background-video", -+ "Resume background video.", -+ "Resume background video playback when tab re-gains focus; additionally, " -+ "it will pause video playback every single time you switch tabs.", kOsAll, -+ FEATURE_VALUE_TYPE(media::kResumeBackgroundVideo)}, -+ -+#endif // BUILDFLAG(IS_ANDROID) -+ -+#endif // ifdef FLAG_SECTION -diff --git a/cromite_flags/media/base/media_switches_cc/add-flag-to-control-video-playback-resume-feature.inc b/cromite_flags/media/base/media_switches_cc/add-flag-to-control-video-playback-resume-feature.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/media/base/media_switches_cc/add-flag-to-control-video-playback-resume-feature.inc -@@ -0,0 +1 @@ -+SET_CROMITE_FEATURE_DISABLED(kResumeBackgroundVideo); --- diff --git a/build/cromite_patches/Add-flag-to-disable-IPv6-probes.patch b/build/cromite_patches/Add-flag-to-disable-IPv6-probes.patch deleted file mode 100644 index 0011adb8..00000000 --- a/build/cromite_patches/Add-flag-to-disable-IPv6-probes.patch +++ /dev/null @@ -1,81 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Sun, 18 Nov 2018 13:06:49 +0100 -Subject: Add flag to disable IPv6 probes - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../about_flags_cc/add-flag-to-disable-IPv6-probes.inc | 8 ++++++++ - .../base/features_cc/add-flag-to-disable-IPv6-probes.inc | 3 +++ - .../base/features_h/add-flag-to-disable-IPv6-probes.inc | 2 ++ - net/BUILD.gn | 1 + - net/dns/host_resolver_manager.cc | 8 ++++++++ - 5 files changed, 22 insertions(+) - create mode 100644 cromite_flags/chrome/browser/about_flags_cc/add-flag-to-disable-IPv6-probes.inc - create mode 100644 cromite_flags/net/base/features_cc/add-flag-to-disable-IPv6-probes.inc - create mode 100644 cromite_flags/net/base/features_h/add-flag-to-disable-IPv6-probes.inc - -diff --git a/cromite_flags/chrome/browser/about_flags_cc/add-flag-to-disable-IPv6-probes.inc b/cromite_flags/chrome/browser/about_flags_cc/add-flag-to-disable-IPv6-probes.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/chrome/browser/about_flags_cc/add-flag-to-disable-IPv6-probes.inc -@@ -0,0 +1,8 @@ -+#ifdef FLAG_SECTION -+ -+ {"ipv6-probing", -+ "Enable IPv6 probing.", -+ "Send IPv6 probes to a RIPE DNS address to verify IPv6 connectivity.", kOsAll, -+ FEATURE_VALUE_TYPE(net::features::kIPv6Probing)}, -+ -+#endif // ifdef FLAG_SECTION -diff --git a/cromite_flags/net/base/features_cc/add-flag-to-disable-IPv6-probes.inc b/cromite_flags/net/base/features_cc/add-flag-to-disable-IPv6-probes.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/net/base/features_cc/add-flag-to-disable-IPv6-probes.inc -@@ -0,0 +1,3 @@ -+CROMITE_FEATURE(kIPv6Probing, -+ "IPv6Probing", -+ base::FEATURE_ENABLED_BY_DEFAULT); -diff --git a/cromite_flags/net/base/features_h/add-flag-to-disable-IPv6-probes.inc b/cromite_flags/net/base/features_h/add-flag-to-disable-IPv6-probes.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/net/base/features_h/add-flag-to-disable-IPv6-probes.inc -@@ -0,0 +1,2 @@ -+// Enable IPv6 ping probes to RIPE DNS. -+NET_EXPORT BASE_DECLARE_FEATURE(kIPv6Probing); -diff --git a/net/BUILD.gn b/net/BUILD.gn ---- a/net/BUILD.gn -+++ b/net/BUILD.gn -@@ -1172,6 +1172,7 @@ component("net") { - ":net_deps", - "//components/miracle_parameter/common", - "//components/network_time/time_tracker", -+ "//components/network_session_configurator/common", - "//net/http:transport_security_state_generated_files", - "//third_party/simdutf", - ] -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 -@@ -115,6 +115,7 @@ - #include "net/log/net_log_event_type.h" - #include "net/log/net_log_source.h" - #include "net/log/net_log_source_type.h" -+#include "services/network/public/cpp/features.h" - #include "net/log/net_log_with_source.h" - #include "net/socket/client_socket_factory.h" - #include "net/url_request/url_request_context.h" -@@ -1493,6 +1494,13 @@ int HostResolverManager::StartIPv6ReachabilityCheck( - return OK; - } - -+ if (!base::FeatureList::IsEnabled(net::features::kIPv6Probing)) { -+ probing_ipv6_ = false; -+ last_ipv6_probe_result_ = false; -+ last_ipv6_probe_time_ = base::TimeTicks(); -+ return OK; -+ } -+ - if (probing_ipv6_) { - ipv6_request_callbacks_.push_back(std::move(callback)); - return ERR_IO_PENDING; --- diff --git a/build/cromite_patches/Add-flag-to-disable-external-intent-requests.patch b/build/cromite_patches/Add-flag-to-disable-external-intent-requests.patch deleted file mode 100644 index 4bc8327e..00000000 --- a/build/cromite_patches/Add-flag-to-disable-external-intent-requests.patch +++ /dev/null @@ -1,277 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Tue, 25 May 2021 19:46:14 +0200 -Subject: Add flag to disable external intent requests - -Adds a new flag that allows to control the switch with same name; -when flag is disabled no external intent will ever be allowed, -for any URL except for the tel: schema. -This also reverts commit b710cefb53b558a8bcd884f6baf0229ba4225721 and -enables IntentBlockExternalFormRedirectsNoGesture. - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../java/res/xml/privacy_preferences.xml | 7 +++- - .../customtabs/CustomTabDelegateFactory.java | 2 ++ - .../ExternalNavigationDelegateImpl.java | 4 ++- - .../cromite/sAllowExternalIntentRequests.java | 33 +++++++++++++++++++ - ...g-to-disable-external-intent-requests.grdp | 9 +++++ - .../android/external_intents_features.cc | 7 +++- - .../android/external_intents_features.h | 1 + - .../ExternalIntentsFeatures.java | 6 ++++ - .../ExternalNavigationHandler.java | 21 ++++++++++++ - ...ag-to-disable-external-intent-requests.inc | 13 ++++++++ - ...t-Delete-block-external-form-redirects.inc | 15 +++++++++ - ...ag-to-disable-external-intent-requests.inc | 3 ++ - 12 files changed, 118 insertions(+), 3 deletions(-) - create mode 100644 chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/cromite/sAllowExternalIntentRequests.java - create mode 100644 chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Add-flag-to-disable-external-intent-requests.grdp - create mode 100644 cromite_flags/chrome/browser/about_flags_cc/Add-flag-to-disable-external-intent-requests.inc - create mode 100644 cromite_flags/chrome/browser/about_flags_cc/Revert-Delete-block-external-form-redirects.inc - create mode 100644 cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/Add-flag-to-disable-external-intent-requests.inc - -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 -@@ -77,7 +77,12 @@ found in the LICENSE file. - android:title="@string/settings_incognito_tab_lock_title" - android:summary="@string/settings_incognito_tab_lock_summary_android_setting_off" - android:persistent="false" /> -- -+ - -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabDelegateFactory.java -@@ -38,6 +38,7 @@ import org.chromium.chrome.browser.ephemeraltab.EphemeralTabCoordinator; - import org.chromium.chrome.browser.externalnav.ExternalNavigationDelegateImpl; - import org.chromium.chrome.browser.flags.ActivityType; - import org.chromium.chrome.browser.flags.ChromeFeatureList; -+import org.chromium.chrome.browser.flags.cromite.sAllowExternalIntentRequests; - import org.chromium.chrome.browser.fullscreen.BrowserControlsManager; - import org.chromium.chrome.browser.fullscreen.FullscreenManager; - import org.chromium.chrome.browser.init.ChromeActivityNativeDelegate; -@@ -156,6 +157,7 @@ public class CustomTabDelegateFactory implements TabDelegateFactory { - - @Override - public boolean shouldDisableAllExternalIntents() { -+ if (!sAllowExternalIntentRequests.getInstance().isEnabled()) return true; - return mActivityType == ActivityType.AUTH_TAB - && ChromeFeatureList.sCctAuthTabDisableAllExternalIntents.isEnabled(); - } -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationDelegateImpl.java -@@ -25,6 +25,7 @@ import org.chromium.base.PackageManagerUtils; - import org.chromium.build.annotations.NullMarked; - import org.chromium.build.annotations.Nullable; - import org.chromium.chrome.browser.ChromeTabbedActivity2; -+import org.chromium.chrome.browser.flags.cromite.sAllowExternalIntentRequests; - import org.chromium.chrome.browser.IntentHandler; - import org.chromium.chrome.browser.browserservices.intents.WebappConstants; - import org.chromium.chrome.browser.document.ChromeLauncherActivity; -@@ -119,7 +120,8 @@ public class ExternalNavigationDelegateImpl implements ExternalNavigationDelegat - @Override - public boolean shouldDisableExternalIntentRequestsForUrl( - ExternalNavigationParams params, Intent intent) { -- return false; -+ if ("tel".equals(params.getUrl().getScheme())) return false; -+ return !sAllowExternalIntentRequests.getInstance().isEnabled(); - } - - @Override -diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/cromite/sAllowExternalIntentRequests.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/cromite/sAllowExternalIntentRequests.java -new file mode 100644 ---- /dev/null -+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/cromite/sAllowExternalIntentRequests.java -@@ -0,0 +1,33 @@ -+/* -+ This file is part of Cromite. -+ -+ Cromite 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. -+ -+ Cromite 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 Cromite. If not, see . -+*/ -+ -+package org.chromium.chrome.browser.flags.cromite; -+ -+import org.chromium.components.cached_flags.CachedFlag; -+import org.chromium.chrome.browser.flags.ChromeFeatureMap; -+ -+public class sAllowExternalIntentRequests { -+ private static final CachedFlag sInstance = -+ new CachedFlag(ChromeFeatureMap.getInstance(), -+ "AllowExternalIntentRequests", false); -+ -+ private sAllowExternalIntentRequests() {} -+ -+ public static CachedFlag getInstance() { -+ return sInstance; -+ } -+} -diff --git a/chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Add-flag-to-disable-external-intent-requests.grdp b/chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Add-flag-to-disable-external-intent-requests.grdp -new file mode 100644 ---- /dev/null -+++ b/chrome/browser/ui/android/strings/cromite_android_chrome_strings_grd/Add-flag-to-disable-external-intent-requests.grdp -@@ -0,0 +1,9 @@ -+ -+ -+ -+ Allow forward URL requests to external intents -+ -+ -+ If disabled, URL requests will never allow redirection to an external intent, such as open application. Caution: since no verification is possible on the information, allows linkage between browser browsing and activity on the application. -+ -+ -diff --git a/components/external_intents/android/external_intents_features.cc b/components/external_intents/android/external_intents_features.cc ---- a/components/external_intents/android/external_intents_features.cc -+++ b/components/external_intents/android/external_intents_features.cc -@@ -29,7 +29,6 @@ const base::Feature* const kFeaturesExposedToJava[] = { - &kNavigationCaptureRefactorAndroid, &kAuxiliaryNavigationStaysInBrowser, - &kReparentTopLevelNavigationFromPWA, &kReparentAuxiliaryNavigationFromPWA, - &kAuxiliaryNavigationStaysInPWA}; -- - } // namespace - - // Alphabetical: -@@ -52,7 +51,13 @@ BASE_FEATURE(kReparentAuxiliaryNavigationFromPWA, - - BASE_FEATURE(kAuxiliaryNavigationStaysInPWA, base::FEATURE_DISABLED_BY_DEFAULT); - -+CROMITE_FEATURE(kIntentBlockExternalFormRedirectsNoGesture, -+ "IntentBlockExternalFormRedirectsNoGesture", -+ base::FEATURE_ENABLED_BY_DEFAULT); -+ - static jlong JNI_ExternalIntentsFeatures_GetFeature(JNIEnv* env, jint ordinal) { -+ if (ordinal == -1) -+ return reinterpret_cast(&kIntentBlockExternalFormRedirectsNoGesture); - return reinterpret_cast(kFeaturesExposedToJava[ordinal]); - } - -diff --git a/components/external_intents/android/external_intents_features.h b/components/external_intents/android/external_intents_features.h ---- a/components/external_intents/android/external_intents_features.h -+++ b/components/external_intents/android/external_intents_features.h -@@ -9,6 +9,7 @@ - - namespace external_intents { - -+BASE_DECLARE_FEATURE(kIntentBlockExternalFormRedirectsNoGesture); - BASE_DECLARE_FEATURE(kExternalNavigationDebugLogs); - BASE_DECLARE_FEATURE(kBlockFrameRenavigations); - BASE_DECLARE_FEATURE(kBlockIntentsToSelf); -diff --git a/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalIntentsFeatures.java b/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalIntentsFeatures.java ---- a/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalIntentsFeatures.java -+++ b/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalIntentsFeatures.java -@@ -19,6 +19,12 @@ import org.chromium.build.annotations.NullMarked; - @JNINamespace("external_intents") - @NullMarked - public class ExternalIntentsFeatures { -+ public static final String INTENT_BLOCK_EXTERNAL_FORM_REDIRECT_NO_GESTURE_NAME = -+ "IntentBlockExternalFormRedirectsNoGesture"; -+ -+ public static final ExternalIntentsFeature INTENT_BLOCK_EXTERNAL_FORM_REDIRECT_NO_GESTURE = -+ new ExternalIntentsFeature(-1, INTENT_BLOCK_EXTERNAL_FORM_REDIRECT_NO_GESTURE_NAME); -+ - public static final String EXTERNAL_NAVIGATION_DEBUG_LOGS_NAME = "ExternalNavigationDebugLogs"; - public static final String BLOCK_INTENTS_TO_SELF_NAME = "BlockIntentsToSelf"; - public static final String NAVIGATION_CAPTURE_REFACTOR_ANDROID_NAME = -diff --git a/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java b/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java ---- a/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java -+++ b/components/external_intents/android/java/src/org/chromium/components/external_intents/ExternalNavigationHandler.java -@@ -1623,6 +1623,12 @@ public class ExternalNavigationHandler { - return false; - } - -+ /** Wrapper of check against the feature to support overriding for testing. */ -+ @VisibleForTesting -+ boolean blockExternalFormRedirectsWithoutGesture() { -+ return ExternalIntentsFeatures.INTENT_BLOCK_EXTERNAL_FORM_REDIRECT_NO_GESTURE.isEnabled(); -+ } -+ - private OverrideUrlLoadingResult shouldOverrideUrlLoadingInternal( - ExternalNavigationParams params, - Intent targetIntent, -@@ -1716,6 +1722,21 @@ public class ExternalNavigationHandler { - return OverrideUrlLoadingResult.forNoOverride(); - } - -+ // http://crbug.com/839751: Require user gestures for form submits to external -+ // protocols. -+ // TODO(tedchoc): Turn this on by default once we verify this change does -+ // not break the world. -+ int pageTransitionCore = params.getPageTransition() & PageTransition.CORE_MASK; -+ boolean isFormSubmit = pageTransitionCore == PageTransition.FORM_SUBMIT; -+ boolean isRedirectFromFormSubmit = isFormSubmit && params.isRedirect(); -+ if (isRedirectFromFormSubmit && !incomingIntentRedirect && !params.hasUserGesture() -+ && blockExternalFormRedirectsWithoutGesture()) { -+ if (debug()) { -+ Log.i(TAG, "Incoming form intent attempting to redirect without user gesture"); -+ } -+ return OverrideUrlLoadingResult.forNoOverride(); -+ } -+ - if (hasInternalScheme(params.getUrl(), targetIntent) - || hasContentScheme(params.getUrl(), targetIntent) - || hasFileSchemeInIntentURI(params.getUrl(), targetIntent) -diff --git a/cromite_flags/chrome/browser/about_flags_cc/Add-flag-to-disable-external-intent-requests.inc b/cromite_flags/chrome/browser/about_flags_cc/Add-flag-to-disable-external-intent-requests.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/chrome/browser/about_flags_cc/Add-flag-to-disable-external-intent-requests.inc -@@ -0,0 +1,13 @@ -+#if BUILDFLAG(IS_ANDROID) -+ -+#ifdef FLAG_SECTION -+ -+ {"allow-external-intent-requests", -+ "Allow forward URL requests to external intents", -+ "If disabled, URL requests will never" -+ "allow for redirecting to an external intent.", kOsAndroid, -+ SINGLE_DISABLE_VALUE_TYPE("disable-external-intent-requests")}, -+ -+#endif -+ -+#endif -diff --git a/cromite_flags/chrome/browser/about_flags_cc/Revert-Delete-block-external-form-redirects.inc b/cromite_flags/chrome/browser/about_flags_cc/Revert-Delete-block-external-form-redirects.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/chrome/browser/about_flags_cc/Revert-Delete-block-external-form-redirects.inc -@@ -0,0 +1,15 @@ -+#if BUILDFLAG(IS_ANDROID) -+ -+#ifdef FLAG_SECTION -+ -+ {"block-external-form-redirects-no-gesture", -+ "Block intents from form submissions without user gesture", -+ "Require a user gesture that triggered a form submission in order to " -+ "allow for redirecting to an external intent.", -+ kOsAndroid, -+ FEATURE_VALUE_TYPE( -+ external_intents::kIntentBlockExternalFormRedirectsNoGesture)}, -+ -+#endif -+ -+#endif -diff --git a/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/Add-flag-to-disable-external-intent-requests.inc b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/Add-flag-to-disable-external-intent-requests.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/Add-flag-to-disable-external-intent-requests.inc -@@ -0,0 +1,3 @@ -+CROMITE_FEATURE(kAllowExternalIntentRequests, -+ "AllowExternalIntentRequests", -+ base::FEATURE_DISABLED_BY_DEFAULT); --- diff --git a/build/cromite_patches/Add-flag-to-disable-vibration.patch b/build/cromite_patches/Add-flag-to-disable-vibration.patch deleted file mode 100644 index 2bffa706..00000000 --- a/build/cromite_patches/Add-flag-to-disable-vibration.patch +++ /dev/null @@ -1,118 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Sun, 27 Jun 2021 17:35:39 +0200 -Subject: Add flag to disable vibration - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - content/child/runtime_features.cc | 1 + - .../about_flags_cc/Add-flag-to-disable-vibration.inc | 8 ++++++++ - .../content_features_cc/Add-flag-to-disable-vibration.inc | 4 ++++ - .../content_features_h/Add-flag-to-disable-vibration.inc | 1 + - third_party/blink/public/platform/web_runtime_features.h | 1 + - .../renderer/modules/vibration/vibration_controller.cc | 3 +++ - .../renderer/platform/exported/web_runtime_features.cc | 4 ++++ - .../renderer/platform/runtime_enabled_features.json5 | 4 ++++ - 8 files changed, 26 insertions(+) - create mode 100644 cromite_flags/chrome/browser/about_flags_cc/Add-flag-to-disable-vibration.inc - create mode 100644 cromite_flags/content/public/common/content_features_cc/Add-flag-to-disable-vibration.inc - create mode 100644 cromite_flags/content/public/common/content_features_h/Add-flag-to-disable-vibration.inc - -diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc ---- a/content/child/runtime_features.cc -+++ b/content/child/runtime_features.cc -@@ -105,6 +105,7 @@ void SetRuntimeFeatureDefaultsForPlatform( - if (command_line.HasSwitch(switches::kDisableMediaSessionAPI)) { - WebRuntimeFeatures::EnableMediaSession(false); - } -+ WebRuntimeFeatures::EnableVibration(base::FeatureList::IsEnabled(features::kVibration)); - #endif - - #if BUILDFLAG(IS_ANDROID) -diff --git a/cromite_flags/chrome/browser/about_flags_cc/Add-flag-to-disable-vibration.inc b/cromite_flags/chrome/browser/about_flags_cc/Add-flag-to-disable-vibration.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/chrome/browser/about_flags_cc/Add-flag-to-disable-vibration.inc -@@ -0,0 +1,8 @@ -+#ifdef FLAG_SECTION -+ -+ {"enable-vibration", -+ "Vibration", -+ "Enable vibration API; an user gesture will still be needed.", kOsAll, -+ FEATURE_VALUE_TYPE(features::kVibration)}, -+ -+#endif -diff --git a/cromite_flags/content/public/common/content_features_cc/Add-flag-to-disable-vibration.inc b/cromite_flags/content/public/common/content_features_cc/Add-flag-to-disable-vibration.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/content/public/common/content_features_cc/Add-flag-to-disable-vibration.inc -@@ -0,0 +1,4 @@ -+// Enables vibration; an user gesture will still be required if enabled. -+CROMITE_FEATURE(kVibration, -+ "VibrationEnabled", -+ base::FEATURE_DISABLED_BY_DEFAULT); -diff --git a/cromite_flags/content/public/common/content_features_h/Add-flag-to-disable-vibration.inc b/cromite_flags/content/public/common/content_features_h/Add-flag-to-disable-vibration.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/content/public/common/content_features_h/Add-flag-to-disable-vibration.inc -@@ -0,0 +1 @@ -+CONTENT_EXPORT BASE_DECLARE_FEATURE(kVibration); -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 -@@ -70,6 +70,7 @@ class BLINK_PLATFORM_EXPORT WebRuntimeFeatures : public WebRuntimeFeaturesBase { - static void EnableFingerprintingCanvasImageDataNoise(bool); - static void EnableFluentScrollbars(bool); - static void EnableFluentOverlayScrollbars(bool); -+ static void EnableVibration(bool); - - static void EnableLocalNetworkAccessWebRTC(bool); - -diff --git a/third_party/blink/renderer/modules/vibration/vibration_controller.cc b/third_party/blink/renderer/modules/vibration/vibration_controller.cc ---- a/third_party/blink/renderer/modules/vibration/vibration_controller.cc -+++ b/third_party/blink/renderer/modules/vibration/vibration_controller.cc -@@ -28,6 +28,7 @@ - #include "third_party/blink/renderer/core/frame/local_frame.h" - #include "third_party/blink/renderer/core/frame/navigator.h" - #include "third_party/blink/renderer/core/page/page.h" -+#include "third_party/blink/renderer/platform/runtime_enabled_features.h" - - // Maximum number of entries in a vibration pattern. - const unsigned kVibrationPatternLengthMax = 99; -@@ -108,6 +109,8 @@ bool VibrationController::vibrate(Navigator& navigator, - // reference to |window| or |navigator| was retained in another window. - if (!navigator.DomWindow()) - return false; -+ if (!RuntimeEnabledFeatures::VibrationEnabled()) -+ return false; - return From(navigator).Vibrate(pattern); - } - -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 -@@ -52,6 +52,10 @@ void WebRuntimeFeatures::EnableTestOnlyFeatures(bool enable) { - RuntimeEnabledFeatures::SetTestFeaturesEnabled(enable); - } - -+void WebRuntimeFeatures::EnableVibration(bool enable) { -+ RuntimeEnabledFeatures::SetVibrationEnabled(enable); -+} -+ - void WebRuntimeFeatures::EnableOriginTrialControlledFeatures(bool enable) { - RuntimeEnabledFeatures::SetOriginTrialControlledFeaturesEnabled(enable); - } -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 -@@ -1070,6 +1070,10 @@ - { - name: "CompositingDecisionAtAnimationPhaseBoundaries" - }, -+ { -+ name: "Vibration", -+ status: "stable", -+ }, - { - name: "CompositionForegroundMarkers", - status: { --- diff --git a/build/cromite_patches/Add-lifetime-options-for-permissions.patch b/build/cromite_patches/Add-lifetime-options-for-permissions.patch deleted file mode 100644 index 525be567..00000000 --- a/build/cromite_patches/Add-lifetime-options-for-permissions.patch +++ /dev/null @@ -1,1431 +0,0 @@ -From: uazo -Date: Fri, 8 Apr 2022 11:04:04 +0000 -Subject: Add lifetime options for permissions - -Indicate the session mode for content-settings by using the constraint `content_settings::SessionModel` as -UserSession when setting the value, and also make use of an expiration time value. -This is used in Chromium for `ClientHints` but it is generally possible to use this functionality when a -specific value needs to be persisted by origin. -All content settings of this type are not saved on disk (except for the `Forever` option), allowing user to -reset the status each time application is restarted. - -There are 4 main areas affected to introduce the functionality: -* components/content_settings - A new `content_settings::LifetimeMode` enum value is defined to specify the user's - choice (Always, OnlyThisTime, UntilOriginClosed, UntilBrowserClosed). - Enumeration is also generated for java by adding it in `content_settings_enums_javagen` (gn). - This is mainly used in `content_settings_utils.cc` to create a specialised `content_settings::ContentSettingConstraints` - that is then used in `SetContentSettingDefaultScope()` by `PermissionContextBase::UpdateContentSetting`. - Existing Chromium data structures do not provide a specific property to define a choice which is instead encoded through - the `ContentSettingConstraints`; this approach is already used in other parts of the Chromium codebase so it is not - novel here. - Therefore, `content_settings::GetConstraintSessionExpiration()` and `content_settings::IsConstraintSessionExpiration()` - manage the lifetime modes of the session content-settings. - The modification also adds the session pattern to the ContentSettingPatternSource so that it is available for the UI. -* components/permissions - Lifetime support is added to the permissions; most of the changes are caused by the fact that it is necessary to report - the value selected by the user from the Java UI managed by `components/browser_ui` up to - `PermissionContextBase::UpdateContentSetting()`, without necessarily having to modify all requests that are not - related to geolocation/camera/microphone. The approach used is a new - `PermissionRequest::PermissionDecidedCallbackWithLifetime` used by an overload of - `PermissionContextBase::CreatePermissionRequest` so that options are present only for the specific content-settings - (see `PermissionDialogModel.java`). - For other permissions no behaviour is changed (see `PermissionDialogDelegate::Accept`); for geolocation it was - necessary to act directly in the specific context, because, unlike microphone/camera, the content-setting value is - inserted in its specific method (`FinishNotifyPermissionSet`, that calls the callback), even if the class always - derives from `PermissionContextBase`. -* components/page_info - Some changes needed to see in the summary of the `page_info` the text "(only this session)" - (aka `page_info_android_permission_session_permission`) through adding a new property "is_user_session" in - `PageInfoPermissionEntry` (Java). -* components/browser_ui - Changes to the Settings UI to show "(only this session)" in the specific content-setting. - The same view is used both in the settings and in the page_info. - -For the management of `UntilOriginClosed` the logic used by flag `kOneTimeGeolocationPermission` was used; this flag -is active only in the desktop (files `last_tab_standing_tracker_*`). It is a class that manages a list of the active -origins and allows to perform operations when all the tabs relating to that origin have been closed, in this case -deleting the session content settings of `UntilOriginClosed`. - -See also: https://github.com/bromite/bromite/issues/1549 - -Original License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../permissions/last_tab_standing_tracker.cc | 33 ++++++++ - .../one_time_permissions_tracker.cc | 34 +++++++- - .../one_time_permissions_tracker.h | 5 +- - .../one_time_permissions_tracker_factory.cc | 2 +- - .../views/permissions/chip/chip_controller.cc | 2 +- - ...exclusive_access_permission_prompt_view.cc | 2 +- - .../permission_prompt_bubble_base_view.cc | 2 +- - .../site_settings/SingleWebsiteSettings.java | 9 ++ - .../android/website_preference_bridge.cc | 2 +- - .../strings/android/browser_ui_strings.grd | 5 ++ - .../core/browser/content_settings_utils.cc | 44 ++++++++-- - .../core/browser/content_settings_utils.h | 6 ++ - .../core/common/content_settings_enums.mojom | 9 ++ - .../page_info/PageInfoController.java | 4 +- - .../PermissionParamsListBuilder.java | 13 ++- - .../android/page_info_controller_android.cc | 10 ++- - components/page_info/page_info.cc | 2 + - components/page_info/page_info.h | 1 + - .../permissions/PermissionDialogDelegate.java | 13 +++ - .../PermissionDialogModelFactory.java | 83 ++++++++++++++++++- - .../embedded_permission_prompt_android.cc | 3 +- - .../embedded_permission_prompt_android.h | 2 +- - .../permission_dialog_delegate.cc | 24 +++++- - .../permission_dialog_delegate.h | 1 + - .../permission_prompt_android.cc | 8 +- - .../permission_prompt_android.h | 3 +- - .../android/permissions_android_strings.grd | 17 ++++ - .../geolocation_permission_context_android.cc | 30 +++++-- - .../geolocation_permission_context_android.h | 8 ++ - .../embedded_permission_prompt_flow_model.cc | 2 +- - .../permissions/permission_context_base.cc | 64 ++++++++++++-- - .../permissions/permission_context_base.h | 26 +++++- - components/permissions/permission_prompt.h | 3 +- - components/permissions/permission_request.cc | 34 +++++++- - components/permissions/permission_request.h | 18 +++- - .../permissions/permission_request_manager.cc | 45 ++++++---- - .../permissions/permission_request_manager.h | 11 ++- - 37 files changed, 507 insertions(+), 73 deletions(-) - -diff --git a/chrome/browser/permissions/last_tab_standing_tracker.cc b/chrome/browser/permissions/last_tab_standing_tracker.cc ---- a/chrome/browser/permissions/last_tab_standing_tracker.cc -+++ b/chrome/browser/permissions/last_tab_standing_tracker.cc -@@ -7,6 +7,32 @@ - #include "base/observer_list.h" - #include "url/gurl.h" - -+#include "components/content_settings/core/browser/host_content_settings_map.h" -+#include "components/content_settings/core/common/content_settings_utils.h" -+#include "components/permissions/permissions_client.h" -+ -+namespace { -+ // Remove all sessions content setting by origin and type -+ void RemoveSessionSettings(HostContentSettingsMap* content_settings, -+ const url::Origin& origin, -+ ContentSettingsType type) { -+ ContentSettingsForOneType session_settings = -+ content_settings->GetSettingsForOneType( -+ type, content_settings::mojom::SessionModel::USER_SESSION); -+ -+ GURL url = origin.GetURL(); -+ for (ContentSettingPatternSource& entry : session_settings) { -+ if (content_settings::IsConstraintSessionExpiration(entry, -+ content_settings::mojom::LifetimeMode::UNTIL_ORIGIN_CLOSED) && -+ entry.primary_pattern.Matches(url)) { -+ content_settings->SetWebsiteSettingCustomScope( -+ entry.primary_pattern, entry.secondary_pattern, -+ type, base::Value()); -+ } -+ } -+ } -+} -+ - LastTabStandingTracker::LastTabStandingTracker(content::BrowserContext* context) - : context_(context) {} - -@@ -56,4 +82,11 @@ void LastTabStandingTracker::WebContentsUnloadedOrigin( - for (auto& observer : observer_list_) { - observer.OnLastPageFromOriginClosed(origin); - } -+ HostContentSettingsMap* content_settings = -+ permissions::PermissionsClient::Get()->GetSettingsMap(context_); -+ RemoveSessionSettings(content_settings, origin, ContentSettingsType::GEOLOCATION); -+ RemoveSessionSettings(content_settings, origin, ContentSettingsType::GEOLOCATION_WITH_OPTIONS); -+ RemoveSessionSettings(content_settings, origin, ContentSettingsType::MEDIASTREAM_MIC); -+ RemoveSessionSettings(content_settings, origin, ContentSettingsType::MEDIASTREAM_CAMERA); -+ } - } -diff --git a/chrome/browser/permissions/one_time_permissions_tracker.cc b/chrome/browser/permissions/one_time_permissions_tracker.cc ---- a/chrome/browser/permissions/one_time_permissions_tracker.cc -+++ b/chrome/browser/permissions/one_time_permissions_tracker.cc -@@ -20,8 +20,34 @@ - #include "components/permissions/permission_util.h" - #include "content/public/browser/visibility.h" - #include "url/gurl.h" -+#include "components/content_settings/core/browser/host_content_settings_map.h" -+#include "components/content_settings/core/common/content_settings_utils.h" -+#include "components/permissions/permissions_client.h" -+ -+namespace { -+ // Remove all sessions content setting by origin and type -+ void RemoveSessionSettings(HostContentSettingsMap* content_settings, -+ const url::Origin& origin, -+ ContentSettingsType type) { -+ ContentSettingsForOneType session_settings = -+ content_settings->GetSettingsForOneType( -+ type, content_settings::mojom::SessionModel::USER_SESSION); -+ -+ GURL url = origin.GetURL(); -+ for (ContentSettingPatternSource& entry : session_settings) { -+ if (content_settings::IsConstraintSessionExpiration(entry, -+ content_settings::mojom::LifetimeMode::UNTIL_ORIGIN_CLOSED) && -+ entry.primary_pattern.Matches(url)) { -+ content_settings->SetWebsiteSettingCustomScope( -+ entry.primary_pattern, entry.secondary_pattern, -+ type, base::Value()); -+ } -+ } -+ } -+} - --OneTimePermissionsTracker::OneTimePermissionsTracker() = default; -+OneTimePermissionsTracker::OneTimePermissionsTracker(content::BrowserContext* context) -+ : context_(context) {} - OneTimePermissionsTracker::~OneTimePermissionsTracker() = default; - - OneTimePermissionsTracker::OriginTrackEntry::OriginTrackEntry() = default; -@@ -255,6 +281,12 @@ void OneTimePermissionsTracker::NotifyLastPageFromOriginClosed( - for (auto& observer : observer_list_) { - observer.OnLastPageFromOriginClosed(origin); - } -+ HostContentSettingsMap* content_settings = -+ permissions::PermissionsClient::Get()->GetSettingsMap(context_); -+ RemoveSessionSettings(content_settings, origin, ContentSettingsType::GEOLOCATION); -+ RemoveSessionSettings(content_settings, origin, ContentSettingsType::GEOLOCATION_WITH_OPTIONS); -+ RemoveSessionSettings(content_settings, origin, ContentSettingsType::MEDIASTREAM_MIC); -+ RemoveSessionSettings(content_settings, origin, ContentSettingsType::MEDIASTREAM_CAMERA); - } - - bool OneTimePermissionsTracker::ShouldIgnoreOrigin(const url::Origin& origin) { -diff --git a/chrome/browser/permissions/one_time_permissions_tracker.h b/chrome/browser/permissions/one_time_permissions_tracker.h ---- a/chrome/browser/permissions/one_time_permissions_tracker.h -+++ b/chrome/browser/permissions/one_time_permissions_tracker.h -@@ -12,6 +12,7 @@ - #include "base/timer/timer.h" - #include "chrome/browser/permissions/one_time_permissions_tracker_observer.h" - #include "components/content_settings/core/common/content_settings_pattern.h" -+#include "chrome/browser/profiles/profile.h" - #include "components/content_settings/core/common/content_settings_types.h" - #include "components/keyed_service/core/keyed_service.h" - #include "content/public/browser/visibility.h" -@@ -24,7 +25,7 @@ class OneTimePermissionsTracker : public KeyedService { - void (OneTimePermissionsTracker::*)(const url::Origin&); - - public: -- OneTimePermissionsTracker(); -+ OneTimePermissionsTracker(content::BrowserContext* context); - ~OneTimePermissionsTracker() override; - - OneTimePermissionsTracker(const OneTimePermissionsTracker&) = delete; -@@ -138,7 +139,7 @@ class OneTimePermissionsTracker : public KeyedService { - base::ObserverList observer_list_; - - std::map origin_tracker_; -- -+ raw_ptr context_; - base::WeakPtrFactory weak_factory_{this}; - }; - -diff --git a/chrome/browser/permissions/one_time_permissions_tracker_factory.cc b/chrome/browser/permissions/one_time_permissions_tracker_factory.cc ---- a/chrome/browser/permissions/one_time_permissions_tracker_factory.cc -+++ b/chrome/browser/permissions/one_time_permissions_tracker_factory.cc -@@ -44,5 +44,5 @@ bool OneTimePermissionsTrackerFactory::ServiceIsCreatedWithBrowserContext() - std::unique_ptr - OneTimePermissionsTrackerFactory::BuildServiceInstanceForBrowserContext( - content::BrowserContext* context) const { -- return std::make_unique(); -+ return std::make_unique(context); - } -diff --git a/chrome/browser/ui/views/permissions/chip/chip_controller.cc b/chrome/browser/ui/views/permissions/chip/chip_controller.cc ---- a/chrome/browser/ui/views/permissions/chip/chip_controller.cc -+++ b/chrome/browser/ui/views/permissions/chip/chip_controller.cc -@@ -228,7 +228,7 @@ void ChipController::OnWidgetDestroyed(views::Widget* widget) { - active_chip_permission_request_manager_.value()->Accept(); - break; - case permissions::PermissionAction::GRANTED_ONCE: -- active_chip_permission_request_manager_.value()->AcceptThisTime(); -+ active_chip_permission_request_manager_.value()->AcceptThisTime(content_settings::mojom::LifetimeMode::ONLY_THIS_TIME); - break; - case permissions::PermissionAction::DENIED: - active_chip_permission_request_manager_.value()->Deny(); -diff --git a/chrome/browser/ui/views/permissions/exclusive_access_permission_prompt_view.cc b/chrome/browser/ui/views/permissions/exclusive_access_permission_prompt_view.cc ---- a/chrome/browser/ui/views/permissions/exclusive_access_permission_prompt_view.cc -+++ b/chrome/browser/ui/views/permissions/exclusive_access_permission_prompt_view.cc -@@ -117,7 +117,7 @@ void ExclusiveAccessPermissionPromptView::RunButtonCallback(int button_id) { - request_type(), GetPermissionActionString(button), - record_browser_always_active_value()); - if (button == ButtonType::kAllowThisTime) { -- delegate_->AcceptThisTime(); -+ delegate_->AcceptThisTime(content_settings::mojom::LifetimeMode::ONLY_THIS_TIME); - } else if (button == ButtonType::kAlwaysAllow) { - delegate_->Accept(); - } else if (button == ButtonType::kNeverAllow) { -diff --git a/chrome/browser/ui/views/permissions/permission_prompt_bubble_base_view.cc b/chrome/browser/ui/views/permissions/permission_prompt_bubble_base_view.cc ---- a/chrome/browser/ui/views/permissions/permission_prompt_bubble_base_view.cc -+++ b/chrome/browser/ui/views/permissions/permission_prompt_bubble_base_view.cc -@@ -294,7 +294,7 @@ void PermissionPromptBubbleBaseView::RunButtonCallback(int button_id) { - delegate_->Accept(); - return; - case PermissionDialogButton::kAcceptOnce: -- delegate_->AcceptThisTime(); -+ delegate_->AcceptThisTime(content_settings::mojom::LifetimeMode::ONLY_THIS_TIME); - return; - case PermissionDialogButton::kDeny: - #if BUILDFLAG(IS_CHROMEOS) -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 -@@ -689,6 +689,11 @@ public class SingleWebsiteSettings extends BaseSiteSettingsFragment - } - - @RequiresNonNull({"mSite"}) -+ private boolean isSessionPermission(@ContentSettingsType.EnumType int type) { -+ return mSite.getPermissionInfo(type) != null && -+ mSite.getPermissionInfo(type).getSessionModel() == SessionModel.USER_SESSION; -+ } -+ - private void setUpClearDataPreference() { - ClearWebsiteStorage preference = findPreference(PREF_CLEAR_DATA); - long usage = mSite.getTotalUsage(); -@@ -1295,6 +1300,10 @@ public class SingleWebsiteSettings extends BaseSiteSettingsFragment - .getDefaultColor()); - } - } -+ if (preference instanceof ChromeSwitchPreference && isSessionPermission(contentType)) { -+ ((ChromeSwitchPreference)preference).setSummary(preference.getSummary() + " " + -+ getString(R.string.page_info_android_permission_session_permission)); -+ } - } - - /** -diff --git a/components/browser_ui/site_settings/android/website_preference_bridge.cc b/components/browser_ui/site_settings/android/website_preference_bridge.cc ---- a/components/browser_ui/site_settings/android/website_preference_bridge.cc -+++ b/components/browser_ui/site_settings/android/website_preference_bridge.cc -@@ -224,7 +224,7 @@ void GetOrigins(JNIEnv* env, - seen_origins.push_back(origin); - insertionFunc(env, static_cast(content_type), list, - ConvertOriginToJavaString(env, origin), jembedder, -- /*is_embargoed=*/true, /*is_one_time=*/false); -+ /*is_embargoed=*/true, 0); - } - } - } -diff --git a/components/browser_ui/strings/android/browser_ui_strings.grd b/components/browser_ui/strings/android/browser_ui_strings.grd ---- a/components/browser_ui/strings/android/browser_ui_strings.grd -+++ b/components/browser_ui/strings/android/browser_ui_strings.grd -@@ -649,6 +649,11 @@ - - URL truncated - -+ -+ (only this session) -+ -+ - - Ad privacy - -diff --git a/components/content_settings/core/browser/content_settings_utils.cc b/components/content_settings/core/browser/content_settings_utils.cc ---- a/components/content_settings/core/browser/content_settings_utils.cc -+++ b/components/content_settings/core/browser/content_settings_utils.cc -@@ -182,6 +182,42 @@ bool IsConstraintPersistent(const ContentSettingConstraints& constraints) { - return constraints.session_model() == mojom::SessionModel::DURABLE; - } - -+ContentSettingConstraints GetConstraintSessionExpiration(content_settings::mojom::LifetimeMode lifetime_mode) { -+ int lifetime; -+ base::Time now; -+ if (lifetime_mode == content_settings::mojom::LifetimeMode::ONLY_THIS_TIME) { -+ // note: this content settings will be discarded immediately -+ // 1h is used as a magic constant to identify the one-time lifetime mode -+ lifetime = 1; -+ } else if (lifetime_mode == content_settings::mojom::LifetimeMode::UNTIL_ORIGIN_CLOSED) { -+ now = base::Time::Now(); -+ lifetime = 24; -+ } else { -+ lifetime = 0; -+ } -+ ContentSettingConstraints c(now); -+ c.set_lifetime(base::Hours(lifetime)); -+ c.set_session_model(mojom::SessionModel::USER_SESSION); -+ return c; -+} -+ -+bool IsConstraintSessionExpiration(const ContentSettingPatternSource& source, -+ content_settings::mojom::LifetimeMode lifetime_mode) { -+ if (source.metadata.session_model() != content_settings::mojom::SessionModel::USER_SESSION) -+ return false; -+ -+ mojom::LifetimeMode type; -+ if (source.metadata.lifetime() == base::Hours(24)) { -+ type = content_settings::mojom::LifetimeMode::UNTIL_ORIGIN_CLOSED; -+ } else if (source.metadata.expiration() == (base::Time() + base::Hours(1))) { -+ type = content_settings::mojom::LifetimeMode::ONLY_THIS_TIME; -+ } else { -+ type = content_settings::mojom::LifetimeMode::UNTIL_BROWSER_CLOSED; -+ } -+ -+ return lifetime_mode == type; -+} -+ - bool CanTrackLastVisit(ContentSettingsType type) { - DCHECK(WebsiteSettingsRegistry::GetInstance()->Get(type)) << type; - -@@ -282,10 +318,6 @@ const std::vector& GetTypesWithTemporaryGrants() { - ContentSettingsType::CAPTURED_SURFACE_CONTROL, - #endif - ContentSettingsType::KEYBOARD_LOCK, -- ContentSettingsType::GEOLOCATION, -- ContentSettingsType::GEOLOCATION_WITH_OPTIONS, -- ContentSettingsType::MEDIASTREAM_MIC, -- ContentSettingsType::MEDIASTREAM_CAMERA, - ContentSettingsType::HAND_TRACKING, - ContentSettingsType::SMART_CARD_DATA, - ContentSettingsType::AR, -@@ -301,10 +333,6 @@ const std::vector& GetTypesWithTemporaryGrantsInHcsm() { - ContentSettingsType::CAPTURED_SURFACE_CONTROL, - #endif - ContentSettingsType::KEYBOARD_LOCK, -- ContentSettingsType::GEOLOCATION, -- ContentSettingsType::GEOLOCATION_WITH_OPTIONS, -- ContentSettingsType::MEDIASTREAM_MIC, -- ContentSettingsType::MEDIASTREAM_CAMERA, - ContentSettingsType::HAND_TRACKING, - ContentSettingsType::AR, - ContentSettingsType::VR, -diff --git a/components/content_settings/core/browser/content_settings_utils.h b/components/content_settings/core/browser/content_settings_utils.h ---- a/components/content_settings/core/browser/content_settings_utils.h -+++ b/components/content_settings/core/browser/content_settings_utils.h -@@ -78,6 +78,12 @@ bool IsConstraintPersistent(const ContentSettingConstraints& constraints); - // Returns whether the given type supports tracking last_visit timestamps. - bool CanTrackLastVisit(ContentSettingsType type); - -+ContentSettingConstraints GetConstraintSessionExpiration(mojom::LifetimeMode lifetime_mode); -+ -+bool IsConstraintSessionExpiration( -+ const ContentSettingPatternSource& source, -+ mojom::LifetimeMode lifetime_mode); -+ - // Get a timestamp with week-precision. - base::Time GetCoarseVisitedTime(base::Time time); - -diff --git a/components/content_settings/core/common/content_settings_enums.mojom b/components/content_settings/core/common/content_settings_enums.mojom ---- a/components/content_settings/core/common/content_settings_enums.mojom -+++ b/components/content_settings/core/common/content_settings_enums.mojom -@@ -63,6 +63,15 @@ enum SessionModel { - ONE_TIME = 3, - }; - -+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.content_settings -+// GENERATED_JAVA_CLASS_NAME_OVERRIDE: LifetimeMode -+enum LifetimeMode { -+ ALWAYS = 99, -+ ONLY_THIS_TIME = 1, -+ UNTIL_ORIGIN_CLOSED = 2, -+ UNTIL_BROWSER_CLOSED = 0, -+}; -+ - // Identifies the content settings provider of a content setting. - // GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.content_settings - // GENERATED_JAVA_CLASS_NAME_OVERRIDE: ProviderType -diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java ---- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java -+++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoController.java -@@ -376,8 +376,8 @@ public class PageInfoController - */ - @CalledByNative - private void addPermissionSection( -- String name, String nameMidSentence, int type, boolean allowed) { -- mPermissionParamsListBuilder.addPermissionEntry(name, nameMidSentence, type, allowed); -+ String name, String nameMidSentence, int type, boolean allowed, boolean is_user_session) { -+ mPermissionParamsListBuilder.addPermissionEntry(name, nameMidSentence, type, allowed, is_user_session); - } - - /** Update the permissions view based on the contents of mDisplayedPermissions. */ -diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PermissionParamsListBuilder.java b/components/page_info/android/java/src/org/chromium/components/page_info/PermissionParamsListBuilder.java ---- a/components/page_info/android/java/src/org/chromium/components/page_info/PermissionParamsListBuilder.java -+++ b/components/page_info/android/java/src/org/chromium/components/page_info/PermissionParamsListBuilder.java -@@ -46,8 +46,9 @@ public class PermissionParamsListBuilder { - mEntries = new ArrayList<>(); - } - -- public void addPermissionEntry(String name, String nameMidSentence, int type, boolean allowed) { -- mEntries.add(new PageInfoPermissionEntry(name, nameMidSentence, type, allowed)); -+ public void addPermissionEntry(String name, String nameMidSentence, int type, boolean allowed, -+ boolean is_user_session) { -+ mEntries.add(new PageInfoPermissionEntry(name, nameMidSentence, type, allowed, is_user_session)); - } - - public void clearPermissionEntries() { -@@ -84,6 +85,10 @@ public class PermissionParamsListBuilder { - } else { - warningTextResource = R.string.page_info_android_permission_blocked; - } -+ if (permission.is_user_session) { -+ warningTextResource = -+ R.string.page_info_android_permission_session_permission; -+ } - } - } - -@@ -112,12 +117,14 @@ public class PermissionParamsListBuilder { - public final String nameMidSentence; - public final int type; - public final boolean allowed; -+ public final boolean is_user_session; - -- PageInfoPermissionEntry(String name, String nameMidSentence, int type, boolean allowed) { -+ PageInfoPermissionEntry(String name, String nameMidSentence, int type, boolean allowed, boolean is_user_session) { - this.name = name; - this.nameMidSentence = nameMidSentence; - this.type = type; - this.allowed = allowed; -+ this.is_user_session = is_user_session; - } - - @Override -diff --git a/components/page_info/android/page_info_controller_android.cc b/components/page_info/android/page_info_controller_android.cc ---- a/components/page_info/android/page_info_controller_android.cc -+++ b/components/page_info/android/page_info_controller_android.cc -@@ -199,6 +199,8 @@ void PageInfoControllerAndroid::SetPermissionInfo( - - std::map - user_specified_settings_to_display; -+ std::map -+ user_specified_settings_is_user_session; - - for (const auto& permission : permission_info_list) { - if (base::Contains(permissions_to_display, permission.type)) { -@@ -211,6 +213,8 @@ void PageInfoControllerAndroid::SetPermissionInfo( - - user_specified_settings_to_display[permission.type] = - info->delegate().IsAnyPermissionAllowed(*setting_to_display); -+ user_specified_settings_is_user_session[permission.type] = -+ permission.is_user_session; - } - } - } -@@ -227,7 +231,8 @@ void PageInfoControllerAndroid::SetPermissionInfo( - ConvertUTF16ToJavaString(env, setting_title), - ConvertUTF16ToJavaString(env, setting_title_mid_sentence), - static_cast(permission), -- user_specified_settings_to_display[permission]); -+ user_specified_settings_to_display[permission], -+ user_specified_settings_is_user_session[permission]); - } - } - -@@ -240,7 +245,8 @@ void PageInfoControllerAndroid::SetPermissionInfo( - env, controller_jobject_, ConvertUTF16ToJavaString(env, object_title), - ConvertUTF16ToJavaString(env, object_title), - static_cast(chosen_object->ui_info->content_settings_type), -- static_cast(CONTENT_SETTING_ALLOW)); -+ static_cast(CONTENT_SETTING_ALLOW), -+ /* is_user_session */ false); - } - - Java_PageInfoController_updatePermissionDisplay(env, controller_jobject_); -diff --git a/components/page_info/page_info.cc b/components/page_info/page_info.cc ---- a/components/page_info/page_info.cc -+++ b/components/page_info/page_info.cc -@@ -1303,6 +1303,8 @@ void PageInfo::PopulatePermissionInfo(PermissionInfo& permission_info, - permission_info.is_one_time = - (info.metadata.session_model() == - content_settings::mojom::SessionModel::ONE_TIME); -+ permission_info.is_user_session = -+ (info.metadata.session_model() == content_settings::mojom::SessionModel::USER_SESSION); - - auto* setting_info = - content_settings::PermissionSettingsRegistry::GetInstance()->Get( -diff --git a/components/page_info/page_info.h b/components/page_info/page_info.h ---- a/components/page_info/page_info.h -+++ b/components/page_info/page_info.h -@@ -151,6 +151,7 @@ class PageInfo : private content_settings::CookieControlsObserver, - content_settings::SettingSource::kNone; - // Whether the permission is a one-time grant. - bool is_one_time = false; -+ bool is_user_session = false; - // Only set for settings that can have multiple permissions for different - // embedded origins. - std::optional requesting_origin; -diff --git a/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogDelegate.java b/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogDelegate.java ---- a/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogDelegate.java -+++ b/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogDelegate.java -@@ -16,6 +16,7 @@ import org.jni_zero.NativeMethods; - import org.chromium.build.annotations.NullMarked; - import org.chromium.build.annotations.Nullable; - import org.chromium.ui.base.WindowAndroid; -+import org.chromium.components.content_settings.LifetimeMode; - - import java.util.ArrayList; - import java.util.List; -@@ -67,6 +68,9 @@ public class PermissionDialogDelegate { - // Prompt(screen) variant we want to display on the dialog. - private @EmbeddedPromptVariant int mEmbeddedPromptVariant; - -+ /** Lifetime option selected by the user. */ -+ private int mSelectedLifetimeOption = LifetimeMode.ALWAYS; -+ - /** - * Defines a (potentially empty) list of ranges represented as pairs of , - * which shall be used by the UI to format the specified ranges as bold text. -@@ -139,6 +143,15 @@ public class PermissionDialogDelegate { - PermissionDialogDelegateJni.get().acceptThisTime(mNativeDelegatePtr); - } - -+ public void setSelectedLifetimeOption(int idx) { -+ mSelectedLifetimeOption = idx; -+ } -+ -+ @CalledByNative -+ public int getSelectedLifetimeOption() { -+ return mSelectedLifetimeOption; -+ } -+ - public void onDeny() { - assert mNativeDelegatePtr != 0; - PermissionDialogDelegateJni.get().deny(mNativeDelegatePtr); -diff --git a/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogModelFactory.java b/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogModelFactory.java ---- a/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogModelFactory.java -+++ b/components/permissions/android/java/src/org/chromium/components/permissions/PermissionDialogModelFactory.java -@@ -13,6 +13,18 @@ import org.chromium.ui.UiUtils; - import org.chromium.ui.modaldialog.ModalDialogProperties; - import org.chromium.ui.modelutil.PropertyModel; - -+import java.util.Arrays; -+import java.util.List; -+import android.view.ViewGroup.LayoutParams; -+import android.widget.LinearLayout; -+import android.widget.RadioButton; -+import android.widget.RadioGroup; -+import android.widget.TextView; -+import org.chromium.base.ApiCompatibilityUtils; -+import org.chromium.ui.base.ViewUtils; -+import org.chromium.components.content_settings.ContentSettingsType; -+import org.chromium.components.content_settings.LifetimeMode; -+ - /** This class creates the model for the permission dialog. */ - @NullMarked - class PermissionDialogModelFactory { -@@ -67,7 +79,76 @@ class PermissionDialogModelFactory { - ModalDialogProperties.ButtonStyles.PRIMARY_FILLED_NEGATIVE_OUTLINE) - .with(ModalDialogProperties.CHANGE_CUSTOM_VIEW_OR_BUTTONS, true); - } -- return builder.build(); -+ -+ PropertyModel pm = builder.build(); -+ int[] types = delegate.getContentSettingsTypes(); -+ if (contains(types, ContentSettingsType.GEOLOCATION) || -+ contains(types, ContentSettingsType.GEOLOCATION_WITH_OPTIONS) || -+ contains(types, ContentSettingsType.MEDIASTREAM_MIC) || -+ contains(types, ContentSettingsType.MEDIASTREAM_CAMERA)) -+ { -+ LinearLayout layout = (LinearLayout) customView; -+ -+ // Create a text label before the lifetime selector. -+ TextView lifetimeOptionsText = new TextView(context); -+ lifetimeOptionsText.setText(context.getString( -+ org.chromium.components.permissions.R.string.session_permissions_title)); -+ lifetimeOptionsText.setTextAppearance( -+ lifetimeOptionsText.getContext(), R.style.TextAppearance_TextMedium_Primary); -+ -+ LinearLayout.LayoutParams lifetimeOptionsTextLayoutParams = -+ new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); -+ lifetimeOptionsTextLayoutParams.setMargins(0, 0, 0, ViewUtils.dpToPx(context, 8)); -+ lifetimeOptionsText.setLayoutParams(lifetimeOptionsTextLayoutParams); -+ layout.addView(lifetimeOptionsText); -+ -+ // Create radio buttons with lifetime options. -+ RadioGroup radioGroup = new RadioGroup(context); -+ -+ RadioButton radioButton = new RadioButton(context); -+ radioButton.setText(context.getString( -+ org.chromium.components.permissions.R.string.session_permissions_only_this_this)); -+ radioButton.setId(LifetimeMode.ONLY_THIS_TIME); -+ radioGroup.addView(radioButton); -+ -+ radioButton = new RadioButton(context); -+ radioButton.setText(context.getString( -+ org.chromium.components.permissions.R.string.session_permissions_until_page_close)); -+ radioButton.setId(LifetimeMode.UNTIL_ORIGIN_CLOSED); -+ radioGroup.addView(radioButton); -+ -+ radioButton = new RadioButton(context); -+ radioButton.setText(context.getString( -+ org.chromium.components.permissions.R.string.session_permissions_until_browser_close)); -+ radioButton.setId(LifetimeMode.UNTIL_BROWSER_CLOSED); -+ radioGroup.addView(radioButton); -+ -+ radioButton = new RadioButton(context); -+ radioButton.setText(context.getString( -+ org.chromium.components.permissions.R.string.session_permissions_forever)); -+ radioButton.setId(LifetimeMode.ALWAYS); -+ radioGroup.addView(radioButton); -+ -+ radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { -+ @Override -+ public void onCheckedChanged(RadioGroup group, int checkedId) { -+ delegate.setSelectedLifetimeOption(checkedId); -+ } -+ }); -+ radioGroup.check(1); -+ layout.addView(radioGroup); -+ } -+ -+ return pm; -+ } -+ -+ private static boolean contains(final int[] array, final int key) { -+ int length = array.length; -+ for(int i = 0; i < length; i++) { -+ if (array[i] == key) -+ return true; -+ } -+ return false; - } - - public static ModalDialogProperties.ModalDialogButtonSpec[] getButtonSpecs( -diff --git a/components/permissions/android/permission_prompt/embedded_permission_prompt_android.cc b/components/permissions/android/permission_prompt/embedded_permission_prompt_android.cc ---- a/components/permissions/android/permission_prompt/embedded_permission_prompt_android.cc -+++ b/components/permissions/android/permission_prompt/embedded_permission_prompt_android.cc -@@ -118,7 +118,8 @@ void EmbeddedPermissionPromptAndroid::Acknowledge() { - delegate()->FinalizeCurrentRequests(); - } - --void EmbeddedPermissionPromptAndroid::AcceptThisTime() { -+void EmbeddedPermissionPromptAndroid::AcceptThisTime( -+ content_settings::mojom::LifetimeMode lifetimeOption) { - prompt_model_->PrecalculateVariantsForMetrics(); - prompt_model_->RecordPermissionActionUKM( - permissions::ElementAnchoredBubbleAction::kGrantedOnce); -diff --git a/components/permissions/android/permission_prompt/embedded_permission_prompt_android.h b/components/permissions/android/permission_prompt/embedded_permission_prompt_android.h ---- a/components/permissions/android/permission_prompt/embedded_permission_prompt_android.h -+++ b/components/permissions/android/permission_prompt/embedded_permission_prompt_android.h -@@ -45,7 +45,7 @@ class EmbeddedPermissionPromptAndroid : public PermissionPromptAndroid { - const override; - void Closing() override; - void Accept() override; -- void AcceptThisTime() override; -+ void AcceptThisTime(content_settings::mojom::LifetimeMode lifetimeOption) override; - void Acknowledge() override; - void Deny() override; - void Resumed() override; -diff --git a/components/permissions/android/permission_prompt/permission_dialog_delegate.cc b/components/permissions/android/permission_prompt/permission_dialog_delegate.cc ---- a/components/permissions/android/permission_prompt/permission_dialog_delegate.cc -+++ b/components/permissions/android/permission_prompt/permission_dialog_delegate.cc -@@ -137,6 +137,11 @@ void PermissionDialogJavaDelegate::UpdateDialog() { - static_cast(permission_prompt_->GetEmbeddedPromptVariant())); - } - -+int PermissionDialogJavaDelegate::GetSelectedLifetimeOption() { -+ JNIEnv* env = base::android::AttachCurrentThread(); -+ return Java_PermissionDialogDelegate_getSelectedLifetimeOption(env, j_delegate_); -+} -+ - // static - std::unique_ptr PermissionDialogDelegate::Create( - content::WebContents* web_contents, -@@ -165,12 +170,22 @@ PermissionDialogDelegate::CreateForTesting( - - void PermissionDialogDelegate::Accept(JNIEnv* env) { - CHECK(permission_prompt_); -+ content_settings::mojom::LifetimeMode lifetimeOption = -+ static_cast( -+ java_delegate_->GetSelectedLifetimeOption()); -+ if (lifetimeOption != content_settings::mojom::LifetimeMode::ALWAYS) { -+ permission_prompt_->AcceptThisTime(lifetimeOption); -+ return; -+ } - permission_prompt_->Accept(); - } - - void PermissionDialogDelegate::AcceptThisTime(JNIEnv* env) { - CHECK(permission_prompt_); -- permission_prompt_->AcceptThisTime(); -+ content_settings::mojom::LifetimeMode lifetimeOption = -+ static_cast( -+ java_delegate_->GetSelectedLifetimeOption()); -+ permission_prompt_->AcceptThisTime(lifetimeOption); - } - - void PermissionDialogDelegate::Acknowledge(JNIEnv* env) { -@@ -180,6 +195,13 @@ void PermissionDialogDelegate::Acknowledge(JNIEnv* env) { - - void PermissionDialogDelegate::Deny(JNIEnv* env) { - CHECK(permission_prompt_); -+ content_settings::mojom::LifetimeMode lifetimeOption = -+ static_cast( -+ java_delegate_->GetSelectedLifetimeOption()); -+ if (lifetimeOption != content_settings::mojom::LifetimeMode::ALWAYS) { -+ permission_prompt_->DenyThisTime(lifetimeOption); -+ return; -+ } - permission_prompt_->Deny(); - } - -diff --git a/components/permissions/android/permission_prompt/permission_dialog_delegate.h b/components/permissions/android/permission_prompt/permission_dialog_delegate.h ---- a/components/permissions/android/permission_prompt/permission_dialog_delegate.h -+++ b/components/permissions/android/permission_prompt/permission_dialog_delegate.h -@@ -42,6 +42,7 @@ class PermissionDialogJavaDelegate { - const favicon_base::FaviconRawBitmapResult& favicon_result); - - virtual void DismissDialog(); -+ virtual int GetSelectedLifetimeOption(); - - virtual void UpdateDialog(); - -diff --git a/components/permissions/android/permission_prompt/permission_prompt_android.cc b/components/permissions/android/permission_prompt/permission_prompt_android.cc ---- a/components/permissions/android/permission_prompt/permission_prompt_android.cc -+++ b/components/permissions/android/permission_prompt/permission_prompt_android.cc -@@ -85,8 +85,12 @@ void PermissionPromptAndroid::Accept() { - delegate_->Accept(); - } - --void PermissionPromptAndroid::AcceptThisTime() { -- delegate_->AcceptThisTime(); -+void PermissionPromptAndroid::AcceptThisTime(content_settings::mojom::LifetimeMode lifetimeOption) { -+ delegate_->AcceptThisTime(lifetimeOption); -+} -+ -+void PermissionPromptAndroid::DenyThisTime(content_settings::mojom::LifetimeMode lifetimeOption) { -+ delegate_->DenyThisTime(lifetimeOption); - } - - void PermissionPromptAndroid::Deny() { -diff --git a/components/permissions/android/permission_prompt/permission_prompt_android.h b/components/permissions/android/permission_prompt/permission_prompt_android.h ---- a/components/permissions/android/permission_prompt/permission_prompt_android.h -+++ b/components/permissions/android/permission_prompt/permission_prompt_android.h -@@ -56,9 +56,10 @@ class PermissionPromptAndroid : public PermissionPrompt { - const; - virtual void Closing(); - virtual void Accept(); -- virtual void AcceptThisTime(); -+ virtual void AcceptThisTime(content_settings::mojom::LifetimeMode lifetimeOption); - virtual void Acknowledge() {} - virtual void Deny(); -+ virtual void DenyThisTime(content_settings::mojom::LifetimeMode lifetimeOption); - virtual void Resumed() {} - virtual void SystemSettingsShown() {} - virtual void SystemPermissionResolved(bool accepted) {} -diff --git a/components/permissions/android/permissions_android_strings.grd b/components/permissions/android/permissions_android_strings.grd ---- a/components/permissions/android/permissions_android_strings.grd -+++ b/components/permissions/android/permissions_android_strings.grd -@@ -267,6 +267,23 @@ - Unknown or unsupported device (%1$sA1:B2:C3:D4:E5:F6) - - -+ -+ -+ Remember my decision -+ -+ -+ Only this time -+ -+ -+ Until all pages of this origin are closed -+ -+ -+ Until Bromite is closed -+ -+ -+ Forever -+ -+ - - - %1$sitem_name (%2$sitem id) -diff --git a/components/permissions/contexts/geolocation_permission_context_android.cc b/components/permissions/contexts/geolocation_permission_context_android.cc ---- a/components/permissions/contexts/geolocation_permission_context_android.cc -+++ b/components/permissions/contexts/geolocation_permission_context_android.cc -@@ -194,7 +194,18 @@ void GeolocationPermissionContextAndroid::NotifyPermissionSet( - PermissionDecision decision, - bool is_final_decision) { - DCHECK(is_final_decision); -+ NotifyPermissionSetWithLifetime(request_data, -+ std::move(callback), persist, decision, is_final_decision, -+ content_settings::mojom::LifetimeMode::ALWAYS); -+} - -+void GeolocationPermissionContextAndroid::NotifyPermissionSetWithLifetime( -+ const PermissionRequestData& request_data, -+ BrowserPermissionCallback callback, -+ bool persist, -+ PermissionDecision decision, -+ bool is_final_decision, -+ content_settings::mojom::LifetimeMode lifetime_option) { - bool is_default_search = - IsRequestingOriginDSE(request_data.requesting_origin); - if (decision == PermissionDecision::kAllow && -@@ -209,7 +220,7 @@ void GeolocationPermissionContextAndroid::NotifyPermissionSet( - FinishNotifyPermissionSet(request_data.id, request_data.requesting_origin, - request_data.embedding_origin, - std::move(callback), false /* persist */, -- PermissionDecision::kDeny, -+ PermissionDecision::kDeny, lifetime_option, - request_data.prompt_options); - return; - } -@@ -230,7 +241,7 @@ void GeolocationPermissionContextAndroid::NotifyPermissionSet( - FinishNotifyPermissionSet(request_data.id, request_data.requesting_origin, - request_data.embedding_origin, - std::move(callback), false /* persist */, -- PermissionDecision::kDeny, -+ PermissionDecision::kDeny, lifetime_option, - request_data.prompt_options); - return; - } -@@ -243,14 +254,14 @@ void GeolocationPermissionContextAndroid::NotifyPermissionSet( - base::BindOnce( - &GeolocationPermissionContextAndroid::OnLocationSettingsDialogShown, - weak_factory_.GetWeakPtr(), request_data.requesting_origin, -- request_data.embedding_origin, persist, decision, -+ request_data.embedding_origin, persist, decision, lifetime_option, - request_data.prompt_options)); - return; - } - - FinishNotifyPermissionSet(request_data.id, request_data.requesting_origin, - request_data.embedding_origin, std::move(callback), -- persist, decision, request_data.prompt_options); -+ persist, decision, lifetime_option, request_data.prompt_options); - } - - content::PermissionResult -@@ -427,7 +438,7 @@ void GeolocationPermissionContextAndroid::OnLocationSettingsDialogShown( - const GURL& requesting_origin, - const GURL& embedding_origin, - bool persist, -- PermissionDecision decision, -+ PermissionDecision decision, content_settings::mojom::LifetimeMode lifetime_option, - std::optional prompt_options, - LocationSettingsDialogOutcome prompt_outcome) { - bool is_default_search = IsRequestingOriginDSE(requesting_origin); -@@ -447,7 +458,7 @@ void GeolocationPermissionContextAndroid::OnLocationSettingsDialogShown( - FinishNotifyPermissionSet(location_settings_dialog_request_id_, - requesting_origin, embedding_origin, - std::move(location_settings_dialog_callback_), -- persist, decision, prompt_options); -+ persist, decision, lifetime_option, prompt_options); - - location_settings_dialog_request_id_ = - PermissionRequestID(content::GlobalRenderFrameHostId(0, 0), -@@ -460,7 +471,7 @@ void GeolocationPermissionContextAndroid::FinishNotifyPermissionSet( - const GURL& embedding_origin, - BrowserPermissionCallback callback, - bool persist, -- PermissionDecision decision, -+ PermissionDecision decision, content_settings::mojom::LifetimeMode lifetime_option, - std::optional prompt_options) { - PermissionRequestData request_data( - this, id, -@@ -469,9 +480,10 @@ void GeolocationPermissionContextAndroid::FinishNotifyPermissionSet( - blink::PermissionType::GEOLOCATION)), - requesting_origin, embedding_origin); - request_data.prompt_options = prompt_options.value_or(std::monostate()); -- GeolocationPermissionContext::NotifyPermissionSet( -+ GeolocationPermissionContext::NotifyPermissionSetImpl( - request_data, -- std::move(callback), persist, decision, /*is_final_decision=*/true); -+ std::move(callback), persist, decision, /*is_final_decision=*/true, -+ /*use_lifetime_option*/ true, lifetime_option); - } - - void GeolocationPermissionContextAndroid::SetLocationSettingsForTesting( -diff --git a/components/permissions/contexts/geolocation_permission_context_android.h b/components/permissions/contexts/geolocation_permission_context_android.h ---- a/components/permissions/contexts/geolocation_permission_context_android.h -+++ b/components/permissions/contexts/geolocation_permission_context_android.h -@@ -92,6 +92,12 @@ class GeolocationPermissionContextAndroid - bool persist, - PermissionDecision decision, - bool is_final_decision) override; -+ void NotifyPermissionSetWithLifetime(const PermissionRequestData& request_data, -+ BrowserPermissionCallback callback, -+ bool persist, -+ PermissionDecision decision, -+ bool is_final_decision, -+ content_settings::mojom::LifetimeMode lifetime_option) override; - content::PermissionResult UpdatePermissionStatusWithDeviceStatus( - content::WebContents* web_contents, - content::PermissionResult result, -@@ -136,6 +142,7 @@ class GeolocationPermissionContextAndroid - const GURL& embedding_origin, - bool persist, - PermissionDecision decision, -+ content_settings::mojom::LifetimeMode lifetime_option, - std::optional prompt_options, - LocationSettingsDialogOutcome prompt_outcome); - -@@ -145,6 +152,7 @@ class GeolocationPermissionContextAndroid - BrowserPermissionCallback callback, - bool persist, - PermissionDecision decision, -+ content_settings::mojom::LifetimeMode lifetime_option, - std::optional prompt_options); - - std::unique_ptr location_settings_; -diff --git a/components/permissions/embedded_permission_prompt_flow_model.cc b/components/permissions/embedded_permission_prompt_flow_model.cc ---- a/components/permissions/embedded_permission_prompt_flow_model.cc -+++ b/components/permissions/embedded_permission_prompt_flow_model.cc -@@ -294,7 +294,7 @@ void EmbeddedPermissionPromptFlowModel::SetDelegateAction( - delegate_->Accept(); - break; - case DelegateAction::kAllowThisTime: -- delegate_->AcceptThisTime(); -+ delegate_->AcceptThisTime(content_settings::mojom::LifetimeMode::ONLY_THIS_TIME); - break; - case DelegateAction::kDeny: - delegate_->Deny(); -diff --git a/components/permissions/permission_context_base.cc b/components/permissions/permission_context_base.cc ---- a/components/permissions/permission_context_base.cc -+++ b/components/permissions/permission_context_base.cc -@@ -267,6 +267,17 @@ PermissionContextBase::CreatePermissionRequest( - std::move(request_finished_callback), UsesAutomaticEmbargo()); - } - -+std::unique_ptr -+PermissionContextBase::CreatePermissionRequest( -+ content::WebContents* web_contents, -+ std::unique_ptr request_data, -+ PermissionRequest::PermissionDecidedCallbackWithLifetime permission_decided_callback, -+ base::OnceClosure request_finished_callback) const { -+ return std::make_unique( -+ std::move(request_data), std::move(permission_decided_callback), -+ std::move(request_finished_callback), UsesAutomaticEmbargo()); -+} -+ - bool PermissionContextBase::UsesAutomaticEmbargo() const { - return true; - } -@@ -572,7 +583,8 @@ void PermissionContextBase::DecidePermission( - void PermissionContextBase::PermissionDecided( - PermissionDecision decision, - bool is_final_decision, -- const PermissionRequestData& request_data) { -+ const PermissionRequestData& request_data, -+ content_settings::mojom::LifetimeMode lifetime_option) { - UserMadePermissionDecision(request_data.id, request_data.requesting_origin, - request_data.embedding_origin, decision); - -@@ -585,11 +597,12 @@ void PermissionContextBase::PermissionDecided( - // missing if a permission prompt was preignored and we already notified an - // origin about it. - if (request->second.second) { -- NotifyPermissionSet(request_data, std::move(request->second.second), -- persist, decision, is_final_decision); -+ NotifyPermissionSetWithLifetime(request_data, std::move(request->second.second), -+ persist, decision, is_final_decision, -+ lifetime_option); - } else { -- NotifyPermissionSet(request_data, base::DoNothing(), persist, decision, -- is_final_decision); -+ NotifyPermissionSetWithLifetime(request_data, base::DoNothing(), persist, decision, -+ is_final_decision, lifetime_option); - } - } - -@@ -674,6 +687,30 @@ void PermissionContextBase::NotifyPermissionSet( - bool persist, - PermissionDecision decision, - bool is_final_decision) { -+ NotifyPermissionSetImpl(request_data, std::move(callback), -+ persist, decision, is_final_decision, /*use_lifetime_option*/ false, -+ content_settings::mojom::LifetimeMode::ALWAYS); -+} -+ -+void PermissionContextBase::NotifyPermissionSetWithLifetime( -+ const PermissionRequestData& request_data, -+ BrowserPermissionCallback callback, -+ bool persist, -+ PermissionDecision decision, -+ bool is_final_decision, -+ content_settings::mojom::LifetimeMode lifetime_option) { -+ NotifyPermissionSetImpl(request_data, std::move(callback), -+ persist, decision, is_final_decision, /*use_lifetime_option*/ true, -+ lifetime_option); -+} -+ -+void PermissionContextBase::NotifyPermissionSetImpl( -+ const PermissionRequestData& request_data, -+ BrowserPermissionCallback callback, -+ bool persist, -+ PermissionDecision decision, -+ bool is_final_decision, bool use_lifetime_option, -+ content_settings::mojom::LifetimeMode lifetime_option) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - - // Note that rfh may be null, see crbug.com/426909787. -@@ -689,8 +726,8 @@ void PermissionContextBase::NotifyPermissionSet( - - if (persist) { - // Clone new value, because we need it again for the callback. -- UpdateSetting(request_data, new_value, -- decision == PermissionDecision::kAllowThisTime); -+ UpdateSettingImpl(request_data, new_value, -+ decision == PermissionDecision::kAllowThisTime, use_lifetime_option, lifetime_option); - } - - if (is_final_decision) { -@@ -728,6 +765,17 @@ void PermissionContextBase::UpdateSetting( - const PermissionRequestData& request_data, - PermissionSetting setting, - bool is_one_time) { -+ UpdateSettingImpl(request_data, std::move(setting), -+ is_one_time, -+ /*use_lifetime_option*/ false, -+ content_settings::mojom::LifetimeMode::ALWAYS); -+} -+ -+void PermissionContextBase::UpdateSettingImpl(const PermissionRequestData& request_data, -+ PermissionSetting setting, -+ bool is_one_time, -+ bool use_lifetime_option, -+ content_settings::mojom::LifetimeMode lifetime_option) { - DCHECK_EQ(request_data.requesting_origin, - request_data.requesting_origin.DeprecatedGetOriginAsURL()); - DCHECK_EQ(request_data.embedding_origin, -@@ -737,6 +785,8 @@ void PermissionContextBase::UpdateSetting( - constraints.set_session_model( - is_one_time ? content_settings::mojom::SessionModel::ONE_TIME - : content_settings::mojom::SessionModel::DURABLE); -+ if (use_lifetime_option) -+ constraints = content_settings::GetConstraintSessionExpiration(lifetime_option); - - // The unused permissions module in Safety check will revoke unused site - // permissions after a finite amount of time if the permission can be revoked. -diff --git a/components/permissions/permission_context_base.h b/components/permissions/permission_context_base.h ---- a/components/permissions/permission_context_base.h -+++ b/components/permissions/permission_context_base.h -@@ -192,6 +192,18 @@ class PermissionContextBase : public content_settings::Observer { - - // Updates stored setting if persist is set, updates tab indicators - // and runs the callback to finish the request. -+ void NotifyPermissionSetImpl(const PermissionRequestData& request_data, -+ BrowserPermissionCallback callback, -+ bool persist, -+ PermissionDecision decision, -+ bool is_final_decision, bool use_lifetime_option, -+ content_settings::mojom::LifetimeMode lifetime_option); -+ virtual void NotifyPermissionSetWithLifetime(const PermissionRequestData& request_data, -+ BrowserPermissionCallback callback, -+ bool persist, -+ PermissionDecision decision, -+ bool is_final_decision, -+ content_settings::mojom::LifetimeMode lifetime_option); - virtual void NotifyPermissionSet(const PermissionRequestData& request_data, - BrowserPermissionCallback callback, - bool persist, -@@ -209,6 +221,11 @@ class PermissionContextBase : public content_settings::Observer { - - // Store the decided permission state. Virtual since the permission might be - // stored with different restrictions (for example for desktop notifications). -+ void UpdateSettingImpl(const PermissionRequestData& request_data, -+ PermissionSetting setting, -+ bool is_one_time, -+ bool use_lifetime_option, -+ content_settings::mojom::LifetimeMode lifetime_option); - virtual void UpdateSetting(const PermissionRequestData& request_data, - PermissionSetting setting, - bool is_one_time); -@@ -238,6 +255,12 @@ class PermissionContextBase : public content_settings::Observer { - PermissionRequest::PermissionDecidedCallback permission_decided_callback, - base::OnceClosure request_finished_callback) const; - -+ virtual std::unique_ptr CreatePermissionRequest( -+ content::WebContents* web_contents, -+ std::unique_ptr request_data, -+ PermissionRequest::PermissionDecidedCallbackWithLifetime permission_decided_callback, -+ base::OnceClosure request_finished_callback) const; -+ - // Implementors can override this method to avoid using automatic embargo. - virtual bool UsesAutomaticEmbargo() const; - -@@ -271,7 +294,8 @@ class PermissionContextBase : public content_settings::Observer { - // allows/blocks/dismisses a permission prompt. - void PermissionDecided(PermissionDecision decision, - bool is_final_decision, -- const PermissionRequestData& request_data); -+ const PermissionRequestData& request_data, -+ content_settings::mojom::LifetimeMode lifetime_option); - - void NotifyObservers(const ContentSettingsPattern& primary_pattern, - const ContentSettingsPattern& secondary_pattern, -diff --git a/components/permissions/permission_prompt.h b/components/permissions/permission_prompt.h ---- a/components/permissions/permission_prompt.h -+++ b/components/permissions/permission_prompt.h -@@ -70,8 +70,9 @@ class PermissionPrompt { - virtual GURL GetEmbeddingOrigin() const = 0; - - virtual void Accept() = 0; -- virtual void AcceptThisTime() = 0; -+ virtual void AcceptThisTime(content_settings::mojom::LifetimeMode lifetime_option) = 0; - virtual void Deny() = 0; -+ virtual void DenyThisTime(content_settings::mojom::LifetimeMode lifetime_option) = 0; - virtual void Dismiss() = 0; - virtual void Ignore() = 0; - -diff --git a/components/permissions/permission_request.cc b/components/permissions/permission_request.cc ---- a/components/permissions/permission_request.cc -+++ b/components/permissions/permission_request.cc -@@ -36,6 +36,16 @@ PermissionRequest::PermissionRequest( - request_finished_callback_(std::move(request_finished_callback)), - uses_automatic_embargo_(uses_automatic_embargo) {} - -+PermissionRequest::PermissionRequest( -+ std::unique_ptr request_data, -+ PermissionDecidedCallbackWithLifetime permission_decided_callback, -+ base::OnceClosure request_finished_callback, -+ bool uses_automatic_embargo) -+ : data_(std::move(request_data)), -+ permission_decided_callback_withlifetime_(std::move(permission_decided_callback)), -+ request_finished_callback_(std::move(request_finished_callback)), -+ uses_automatic_embargo_(uses_automatic_embargo) {} -+ - PermissionRequest::~PermissionRequest() { - std::move(request_finished_callback_).Run(); - } -@@ -424,20 +434,40 @@ bool PermissionRequest::ShouldUseTwoOriginPrompt() const { - return request_type() == RequestType::kStorageAccess; - } - --void PermissionRequest::PermissionGranted(bool is_one_time) { -+void PermissionRequest::PermissionGranted(bool is_one_time, -+ content_settings::mojom::LifetimeMode lifetime_option) { -+ if (permission_decided_callback_withlifetime_) { -+ std::move(permission_decided_callback_withlifetime_) -+ .Run(is_one_time ? PermissionDecision::kAllowThisTime -+ : PermissionDecision::kAllow, -+ /*is_final_decision=*/true, *data_, lifetime_option); -+ return; -+ } - std::move(permission_decided_callback_) - .Run(is_one_time ? PermissionDecision::kAllowThisTime - : PermissionDecision::kAllow, - /*is_final_decision=*/true, /*request_data=*/*data_); - } - --void PermissionRequest::PermissionDenied() { -+void PermissionRequest::PermissionDenied(bool is_one_time, -+ content_settings::mojom::LifetimeMode lifetime_option) { -+ if (permission_decided_callback_withlifetime_) { -+ std::move(permission_decided_callback_withlifetime_) -+ .Run(PermissionDecision::kDeny, /*is_final_decision=*/true, *data_, lifetime_option); -+ return; -+ } - std::move(permission_decided_callback_) - .Run(PermissionDecision::kDeny, - /*is_final_decision=*/true, /*request_data=*/*data_); - } - - void PermissionRequest::Cancelled(bool is_final_decision) { -+ if (permission_decided_callback_withlifetime_) { -+ std::move(permission_decided_callback_withlifetime_) -+ .Run(PermissionDecision::kNone, is_final_decision, *data_, -+ content_settings::mojom::LifetimeMode::ALWAYS); -+ return; -+ } - if (permission_decided_callback_) { - permission_decided_callback_.Run(PermissionDecision::kNone, - is_final_decision, -diff --git a/components/permissions/permission_request.h b/components/permissions/permission_request.h ---- a/components/permissions/permission_request.h -+++ b/components/permissions/permission_request.h -@@ -52,6 +52,12 @@ class PermissionRequest { - bool /*is_final_decision*/, - const PermissionRequestData& /*request_data*/)>; - -+ using PermissionDecidedCallbackWithLifetime = base::RepeatingCallback; -+ - // `permission_decided_callback` is called when the permission request is - // resolved by the user (see comment on PermissionDecidedCallback above). - // `request_finished_callback` is called when the permission request is being -@@ -66,6 +72,11 @@ class PermissionRequest { - base::OnceClosure request_finished_callback = base::DoNothing(), - bool uses_automatic_embargo = true); - -+ PermissionRequest(std::unique_ptr request_data, -+ PermissionDecidedCallbackWithLifetime permission_decided_callback, -+ base::OnceClosure request_finished_callback = base::DoNothing(), -+ bool uses_automatic_embargo = true); -+ - PermissionRequest(const PermissionRequest&) = delete; - PermissionRequest& operator=(const PermissionRequest&) = delete; - -@@ -172,10 +183,10 @@ class PermissionRequest { - // If |is_one_time| is true the permission will last until all tabs of - // |origin| are closed or navigated away from, and then the permission will - // automatically expire after 1 day. -- void PermissionGranted(bool is_one_time); -+ void PermissionGranted(bool is_one_time, content_settings::mojom::LifetimeMode lifetime_option); - - // Called when the user has denied the requested permission. -- void PermissionDenied(); -+ void PermissionDenied(bool is_one_time, content_settings::mojom::LifetimeMode lifetime_option); - - // Called when the user has cancelled the permission request. This - // corresponds to a denial, but is segregated in case the context needs to -@@ -234,6 +245,9 @@ class PermissionRequest { - // Called once a decision is made about the permission. - PermissionDecidedCallback permission_decided_callback_; - -+ // Called once a decision is made about the permission (with lifetime option). -+ PermissionDecidedCallbackWithLifetime permission_decided_callback_withlifetime_; -+ - // Called when the request is finished to perform bookkeeping tasks. - base::OnceClosure request_finished_callback_; - -diff --git a/components/permissions/permission_request_manager.cc b/components/permissions/permission_request_manager.cc ---- a/components/permissions/permission_request_manager.cc -+++ b/components/permissions/permission_request_manager.cc -@@ -201,7 +201,7 @@ void PermissionRequestManager::AddRequest( - - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDenyPermissionPrompts)) { -- request->PermissionDenied(); -+ request->PermissionDenied(/*is_one_time*/false, content_settings::mojom::LifetimeMode::ALWAYS); - return; - } - -@@ -270,7 +270,7 @@ void PermissionRequestManager::AddRequest( - - if (should_auto_approve_request) { - if (should_auto_approve_request == PermissionAction::GRANTED) { -- request->PermissionGranted(/*is_one_time=*/true); -+ request->PermissionGranted(/*is_one_time=*/true, content_settings::mojom::LifetimeMode::UNTIL_ORIGIN_CLOSED); - } - return; - } -@@ -597,7 +597,8 @@ void PermissionRequestManager::Accept() { - (*requests_iter)->request_type(), - PermissionAction::GRANTED); - PermissionGrantedIncludingDuplicates(requests_iter->get(), -- /*is_one_time=*/false); -+ /*is_one_time=*/false, -+ content_settings::mojom::LifetimeMode::ALWAYS); - - #if !BUILDFLAG(IS_ANDROID) - std::optional content_settings_type = -@@ -615,7 +616,7 @@ void PermissionRequestManager::Accept() { - CurrentRequestsDecided(PermissionAction::GRANTED); - } - --void PermissionRequestManager::AcceptThisTime() { -+void PermissionRequestManager::AcceptThisTime(content_settings::mojom::LifetimeMode mode) { - if (ignore_callbacks_from_prompt_) { - return; - } -@@ -629,7 +630,8 @@ void PermissionRequestManager::AcceptThisTime() { - (*requests_iter)->request_type(), - PermissionAction::GRANTED_ONCE); - PermissionGrantedIncludingDuplicates(requests_iter->get(), -- /*is_one_time=*/true); -+ /*is_one_time=*/true, -+ mode); - } - - NotifyRequestDecided(PermissionAction::GRANTED_ONCE); -@@ -637,6 +639,15 @@ void PermissionRequestManager::AcceptThisTime() { - } - - void PermissionRequestManager::Deny() { -+ Deny_(/*is_one_time*/ false, content_settings::mojom::LifetimeMode::ALWAYS); -+} -+ -+void PermissionRequestManager::DenyThisTime(content_settings::mojom::LifetimeMode mode) { -+ Deny_(/*is_one_time*/ true, mode); -+} -+ -+void PermissionRequestManager::Deny_(bool is_one_time, -+ content_settings::mojom::LifetimeMode lifetime_option) { - if (ignore_callbacks_from_prompt_) { - return; - } -@@ -659,7 +670,7 @@ void PermissionRequestManager::Deny() { - StorePermissionActionForUMA((*requests_iter)->requesting_origin(), - (*requests_iter)->request_type(), - PermissionAction::DENIED); -- PermissionDeniedIncludingDuplicates(requests_iter->get()); -+ PermissionDeniedIncludingDuplicates(requests_iter->get(), is_one_time, lifetime_option); - } - - NotifyRequestDecided(PermissionAction::DENIED); -@@ -1283,32 +1294,32 @@ PermissionRequestManager::VisitDuplicateRequests( - - void PermissionRequestManager::PermissionGrantedIncludingDuplicates( - PermissionRequest* request, -- bool is_one_time) { -+ bool is_one_time, content_settings::mojom::LifetimeMode lifetime_option) { - CHECK(RequestExistsExactlyOnce(request, pending_permission_requests_, - requests_)) - << "Only requests in [pending_permission_]requests_ can have duplicates"; -- request->PermissionGranted(is_one_time); -+ request->PermissionGranted(is_one_time, lifetime_option); - VisitDuplicateRequests( - base::BindRepeating( -- [](bool is_one_time, -+ [](bool is_one_time, content_settings::mojom::LifetimeMode lifetime_option, - const std::unique_ptr& request) { -- request->PermissionGranted(is_one_time); -+ request->PermissionGranted(is_one_time, lifetime_option); - }, -- is_one_time), -+ is_one_time, lifetime_option), - request); - } - - void PermissionRequestManager::PermissionDeniedIncludingDuplicates( -- PermissionRequest* request) { -+ PermissionRequest* request, bool is_one_time, content_settings::mojom::LifetimeMode lifetime_option) { - CHECK(RequestExistsExactlyOnce(request, pending_permission_requests_, - requests_)) - << "Only requests in [pending_permission_]requests_ can have duplicates"; -- request->PermissionDenied(); -+ request->PermissionDenied(is_one_time, lifetime_option); - VisitDuplicateRequests( - base::BindRepeating( -- [](const std::unique_ptr& request) { -- request->PermissionDenied(); -- }), -+ [](bool is_one_time, content_settings::mojom::LifetimeMode lifetime_option, const std::unique_ptr& request) { -+ request->PermissionDenied(is_one_time, lifetime_option); -+ }, is_one_time, lifetime_option), - request); - } - -@@ -1578,7 +1589,7 @@ void PermissionRequestManager::DoAutoResponseForTesting() { - } - switch (auto_response_for_test_) { - case ACCEPT_ONCE: -- AcceptThisTime(); -+ AcceptThisTime(content_settings::mojom::LifetimeMode::ONLY_THIS_TIME); - break; - case ACCEPT_ALL: - Accept(); -diff --git a/components/permissions/permission_request_manager.h b/components/permissions/permission_request_manager.h ---- a/components/permissions/permission_request_manager.h -+++ b/components/permissions/permission_request_manager.h -@@ -168,8 +168,10 @@ class PermissionRequestManager - GURL GetRequestingOrigin() const override; - GURL GetEmbeddingOrigin() const override; - void Accept() override; -- void AcceptThisTime() override; -+ void AcceptThisTime(content_settings::mojom::LifetimeMode lifetime_option) override; - void Deny() override; -+ void Deny_(bool is_one_time, content_settings::mojom::LifetimeMode lifetime_option); -+ void DenyThisTime(content_settings::mojom::LifetimeMode lifetime_option) override; - void Dismiss() override; - void Ignore() override; - void FinalizeCurrentRequests() override; -@@ -419,9 +421,12 @@ class PermissionRequestManager - - // Calls PermissionGranted on a request and all its duplicates. - void PermissionGrantedIncludingDuplicates(PermissionRequest* request, -- bool is_one_time); -+ bool is_one_time, -+ content_settings::mojom::LifetimeMode lifetime_option); - // Calls PermissionDenied on a request and all its duplicates. -- void PermissionDeniedIncludingDuplicates(PermissionRequest* request); -+ void PermissionDeniedIncludingDuplicates(PermissionRequest* request, -+ bool is_one_time, -+ content_settings::mojom::LifetimeMode lifetime_option); - // Calls Cancelled on a request and all its duplicates. - void CancelRequestIncludingDuplicates(PermissionRequest* request, - bool is_final_decision = true); --- diff --git a/build/cromite_patches/Add-menu-item-to-bookmark-all-tabs.patch b/build/cromite_patches/Add-menu-item-to-bookmark-all-tabs.patch deleted file mode 100644 index a2425da4..00000000 --- a/build/cromite_patches/Add-menu-item-to-bookmark-all-tabs.patch +++ /dev/null @@ -1,931 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Thu, 18 Feb 2021 21:22:52 +0100 -Subject: Add menu item to bookmark all tabs - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - chrome/android/java/res/values/ids.xml | 1 + - .../chrome/browser/ChromeTabbedActivity.java | 43 +++++++++++++++++++ - .../TabbedAppMenuPropertiesDelegate.java | 15 +++++++ - .../bookmarks/android/bookmark_bridge.cc | 42 ++++++++++++++++++ - .../bookmarks/android/bookmark_bridge.h | 8 ++++ - .../browser/bookmarks/BookmarkBridge.java | 41 ++++++++++++++++++ - .../browser/bookmarks/bookmark_html_writer.cc | 14 +++++- - .../bookmarks/bookmark_parent_folder.cc | 1 + - .../permanent_folder_ordering_tracker.cc | 2 + - .../dialogs/DownloadLocationCustomView.java | 4 +- - .../strings/android_chrome_strings.grd | 3 ++ - .../bookmark_ui_operations_helper.cc | 2 + - .../bookmark_bar_page_handler.cc | 2 + - components/bookmark_bar_strings.grdp | 6 +++ - .../bookmarks/browser/bookmark_codec.cc | 20 +++++++-- - components/bookmarks/browser/bookmark_codec.h | 7 ++- - .../browser/bookmark_load_details.cc | 15 +++++-- - .../bookmarks/browser/bookmark_load_details.h | 2 + - .../bookmarks/browser/bookmark_model.cc | 3 +- - components/bookmarks/browser/bookmark_model.h | 7 +++ - components/bookmarks/browser/bookmark_node.cc | 13 ++++++ - components/bookmarks/browser/bookmark_node.h | 4 ++ - .../bookmarks/browser/bookmark_storage.cc | 2 + - .../bookmarks/browser/bookmark_uuids.cc | 3 ++ - components/bookmarks/browser/bookmark_uuids.h | 1 + - components/bookmarks/browser/model_loader.cc | 9 +++- - .../bookmark_specifics_conversions.cc | 1 + - 27 files changed, 257 insertions(+), 14 deletions(-) - -diff --git a/chrome/android/java/res/values/ids.xml b/chrome/android/java/res/values/ids.xml ---- a/chrome/android/java/res/values/ids.xml -+++ b/chrome/android/java/res/values/ids.xml -@@ -191,6 +191,7 @@ found in the LICENSE file. - - - -+ - - - -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 -@@ -100,6 +100,7 @@ import org.chromium.chrome.browser.bookmarks.BookmarkPane; - import org.chromium.chrome.browser.bookmarks.BookmarkUtils; - import org.chromium.chrome.browser.browserservices.intents.WebappConstants; - import org.chromium.chrome.browser.compositor.CompositorViewHolder; -+import org.chromium.chrome.browser.bookmarks.BookmarkModel; - import org.chromium.chrome.browser.compositor.layouts.Layout; - import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChrome; - import org.chromium.chrome.browser.compositor.layouts.LayoutManagerChromePhone; -@@ -296,6 +297,9 @@ import org.chromium.chrome.browser.ui.browser_window.ChromeAndroidTaskTrackerFac - import org.chromium.chrome.browser.ui.desktop_windowing.AppHeaderUtils; - import org.chromium.chrome.browser.ui.edge_to_edge.EdgeToEdgeUtils; - import org.chromium.chrome.browser.ui.extensions.windowing.ExtensionWindowControllerBridgeFactory; -+import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar; -+import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; -+import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager.SnackbarController; - import org.chromium.chrome.browser.ui.searchactivityutils.SearchActivityClient; - import org.chromium.chrome.browser.ui.searchactivityutils.SearchActivityExtras.IntentOrigin; - import org.chromium.chrome.browser.ui.signin.BottomSheetSigninAndHistorySyncConfig; -@@ -309,6 +313,8 @@ import org.chromium.chrome.browser.usage_stats.UsageStatsService; - import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; - import org.chromium.chrome.browser.xr.scenecore.XrSceneCoreSessionInitializerImpl; - import org.chromium.chrome.browser.xr.scenecore.XrSceneCoreSessionManagerImpl; -+import org.chromium.components.bookmarks.BookmarkId; -+import org.chromium.components.bookmarks.BookmarkItem; - import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; - import org.chromium.components.browser_ui.util.BrowserControlsVisibilityDelegate; - import org.chromium.components.browser_ui.util.ComposedBrowserControlsVisibilityDelegate; -@@ -3910,6 +3916,8 @@ public class ChromeTabbedActivity extends ChromeActivity { - CloseAllTabsDialog.show( - this, getModalDialogManagerSupplier(), tabModelSelector, closeAllTabsRunnable); - RecordUserAction.record("MobileMenuCloseAllTabs"); -+ } else if (id == R.id.bookmark_all_tabs_menu_id) { -+ bookmarkAllTabs(); - } else if (id == R.id.close_all_incognito_tabs_menu_id) { - boolean allowUndo = TabClosureParamsUtils.shouldAllowUndo(triggeringMotion); - -@@ -4030,6 +4038,41 @@ public class ChromeTabbedActivity extends ChromeActivity { - getTabModalLifetimeHandler().onOmniboxFocusChanged(hasFocus); - } - -+ private void bookmarkAllTabs() { -+ TabModel tabModel = getTabModelSelector().getCurrentModel(); -+ int count = tabModel.getCount(); -+ Log.i(TAG, "bookmarkAllTabs(): %d tabs to bookmark", count); -+ if (count == 0) { -+ return; -+ } -+ -+ final BookmarkModel bookmarkModel = mBookmarkModelSupplier.get(); -+ bookmarkModel.finishLoadingBookmarkModel(() -> { -+ for (int i = 0; i < tabModel.getCount(); i++) { -+ Tab tab = tabModel.getTabAt(i); -+ if (tab.isNativePage()) { -+ continue; -+ } -+ bookmarkModel.addToTabsCollection(tab); -+ } -+ BookmarkId parent = bookmarkModel.getTabsCollectionFolderId(); -+ BookmarkItem bookmarkItem = bookmarkModel.getBookmarkById(parent); -+ String folderName = ""; -+ if (bookmarkItem != null) { -+ folderName = bookmarkItem.getTitle(); -+ } -+ SnackbarController snackbarController = new SnackbarController() { -+ @Override -+ public void onAction(Object actionData) { -+ } -+ }; -+ Snackbar snackbar = Snackbar.make(folderName, snackbarController, Snackbar.TYPE_ACTION, -+ Snackbar.UMA_BOOKMARK_ADDED) -+ .setTemplateText(getString(R.string.bookmark_page_saved_folder)); -+ getSnackbarManager().showSnackbar(snackbar); -+ }); -+ } -+ - private void recordLauncherShortcutAction(boolean isIncognito) { - if (isIncognito) { - RecordUserAction.record("Android.LauncherShortcut.NewIncognitoTab"); -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java -@@ -291,6 +291,14 @@ public class TabbedAppMenuPropertiesDelegate extends AppMenuPropertiesDelegateIm - // Bookmarks - modelList.add(buildBookmarksItem()); - -+ // Add bookmark all item -+ modelList.add(new MVCListAdapter.ListItem( -+ AppMenuHandler.AppMenuItemType.STANDARD, -+ buildModelForStandardMenuItem( -+ R.id.bookmark_all_tabs_menu_id, -+ R.string.menu_bookmark_all_tabs, -+ shouldShowIconBeforeItem() ? R.drawable.ic_folder_blue_24dp : 0))); -+ - // Recent Tabs - if (shouldShowRecentTabsItem()) modelList.add(buildRecentTabsItem()); - -@@ -466,6 +474,13 @@ public class TabbedAppMenuPropertiesDelegate extends AppMenuPropertiesDelegateIm - } - modelList.add(buildCloseAllTabsItem()); - if (shouldShowTinkerTank()) modelList.add(buildTinkerTankItem()); -+ // Add bookmark all item -+ modelList.add(new MVCListAdapter.ListItem( -+ AppMenuHandler.AppMenuItemType.STANDARD, -+ buildModelForStandardMenuItem( -+ R.id.bookmark_all_tabs_menu_id, -+ R.string.menu_bookmark_all_tabs, -+ shouldShowIconBeforeItem() ? R.drawable.ic_folder_blue_24dp : 0))); - modelList.add(buildSelectTabsItem()); - if (shouldShowQuickDeleteItem()) modelList.add(buildQuickDeleteItem()); - modelList.add(buildSettingsItem()); -diff --git a/chrome/browser/bookmarks/android/bookmark_bridge.cc b/chrome/browser/bookmarks/android/bookmark_bridge.cc ---- a/chrome/browser/bookmarks/android/bookmark_bridge.cc -+++ b/chrome/browser/bookmarks/android/bookmark_bridge.cc -@@ -340,6 +340,33 @@ jboolean BookmarkBridge::AreAccountBookmarkFoldersActive(JNIEnv* env) { - return bookmark_model_->account_mobile_node() != nullptr; - } - -+base::android::ScopedJavaLocalRef -+BookmarkBridge::GetBookmarkIdForTabsCollection( -+ JNIEnv* env, -+ const JavaParamRef& url) { -+ DCHECK_CURRENTLY_ON(BrowserThread::UI); -+ -+ GURL gurl = url::GURLAndroid::ToNativeGURL(env, url); -+ -+ bookmarks::BookmarkModel* model = -+ BookmarkModelFactory::GetForBrowserContext(profile_); -+ -+ std::vector> nodes = -+ model->GetNodesByURL(gurl); -+ std::sort(nodes.begin(), nodes.end(), &bookmarks::MoreRecentlyAdded); -+ -+ for (const BookmarkNode* node : nodes) { -+ for (const auto& child : model->tabs_collection_node()->children()) { -+ if (node->id() == child->id()) { -+ return JavaBookmarkIdCreateBookmarkId(env, node->id(), -+ GetBookmarkType(node)); -+ } -+ } -+ } -+ -+ return nullptr; -+} -+ - base::android::ScopedJavaLocalRef - BookmarkBridge::GetMostRecentlyAddedUserBookmarkIdForUrl(JNIEnv* env, - const GURL& url) { -@@ -452,6 +479,7 @@ void BookmarkBridge::GetAllFoldersWithDepths( - // Vector to temporarily contain all child bookmarks at same level for sorting - std::vector bookmarks = { - bookmark_model_->mobile_node(), -+ bookmark_model_->tabs_collection_node(), - bookmark_model_->bookmark_bar_node(), - bookmark_model_->other_node(), - }; -@@ -560,6 +588,9 @@ std::vector BookmarkBridge::GetTopLevelFolderIdsImpl( - top_level_folders.push_back(other_node); - } - -+ const BookmarkNode* tabs_collection_node = bookmark_model_->tabs_collection_node(); -+ top_level_folders.push_back(tabs_collection_node); -+ - const BookmarkNode* reading_list_node = - local_or_syncable_reading_list_manager_->GetRoot(); - if (IsPermanentFolderVisible( -@@ -1237,6 +1268,17 @@ void BookmarkBridge::GetBookmarksOfType( - AddBookmarkNodesToBookmarkIdList(env, j_list, results); - } - -+ScopedJavaLocalRef BookmarkBridge::GetTabsCollectionFolderId( -+ JNIEnv* env, -+ const JavaParamRef& obj) { -+ DCHECK_CURRENTLY_ON(BrowserThread::UI); -+ const BookmarkNode* tabs_collection_node = bookmark_model_->tabs_collection_node(); -+ ScopedJavaLocalRef folder_id_obj = -+ JavaBookmarkIdCreateBookmarkId( -+ env, tabs_collection_node->id(), GetBookmarkType(tabs_collection_node)); -+ return folder_id_obj; -+} -+ - ScopedJavaLocalRef BookmarkBridge::AddFolder( - JNIEnv* env, - const JavaParamRef& j_parent_id_obj, -diff --git a/chrome/browser/bookmarks/android/bookmark_bridge.h b/chrome/browser/bookmarks/android/bookmark_bridge.h ---- a/chrome/browser/bookmarks/android/bookmark_bridge.h -+++ b/chrome/browser/bookmarks/android/bookmark_bridge.h -@@ -106,6 +106,10 @@ class BookmarkBridge : public ProfileObserver, - - jboolean AreAccountBookmarkFoldersActive(JNIEnv* env); - -+ base::android::ScopedJavaLocalRef GetBookmarkIdForTabsCollection( -+ JNIEnv* env, -+ const base::android::JavaParamRef& url); -+ - base::android::ScopedJavaLocalRef - GetMostRecentlyAddedUserBookmarkIdForUrl(JNIEnv* env, const GURL& url); - const bookmarks::BookmarkNode* GetMostRecentlyAddedUserBookmarkIdForUrlImpl( -@@ -245,6 +249,10 @@ class BookmarkBridge : public ProfileObserver, - const base::android::JavaParamRef& j_list, - jint type); - -+ base::android::ScopedJavaLocalRef GetTabsCollectionFolderId( -+ JNIEnv* env, -+ const base::android::JavaParamRef& obj); -+ - base::android::ScopedJavaLocalRef AddFolder( - JNIEnv* env, - const base::android::JavaParamRef& j_parent_id_obj, -diff --git a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java ---- a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java -+++ b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java -@@ -16,6 +16,7 @@ import org.jni_zero.JniType; - import org.jni_zero.NativeMethods; - - import org.chromium.base.ContextUtils; -+import org.chromium.base.Log; - import org.chromium.base.ObserverList; - import org.chromium.base.ThreadUtils; - import org.chromium.base.metrics.RecordUserAction; -@@ -26,6 +27,7 @@ import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksShim; - import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; - import org.chromium.chrome.browser.preferences.ChromeSharedPreferences; - import org.chromium.chrome.browser.profiles.Profile; -+import org.chromium.chrome.browser.tab.Tab; - import org.chromium.components.bookmarks.BookmarkId; - import org.chromium.components.bookmarks.BookmarkItem; - import org.chromium.components.bookmarks.BookmarkType; -@@ -47,6 +49,7 @@ import java.util.function.BiConsumer; - class BookmarkBridge { - private static final OneshotSupplierImpl - sPartnerBookmarkIteratorSupplier = new OneshotSupplierImpl<>(); -+ private static final String TAG = "BookmarkBridge"; - - private final ObserverList mObservers = new ObserverList<>(); - private final Profile mProfile; -@@ -385,6 +388,16 @@ class BookmarkBridge { - return mMobileFolderId; - } - -+ /** -+ * @return The BookmarkId for the Tabs collecction folder node -+ */ -+ public BookmarkId getTabsCollectionFolderId() { -+ ThreadUtils.assertOnUiThread(); -+ assert mIsNativeBookmarkModelLoaded; -+ return BookmarkBridgeJni.get().getTabsCollectionFolderId( -+ mNativeBookmarkBridge, BookmarkBridge.this); -+ } -+ - /** Returns Id representing the special "other" folder from bookmark model. */ - public @Nullable BookmarkId getOtherFolderId() { - ThreadUtils.assertOnUiThread(); -@@ -882,6 +895,29 @@ class BookmarkBridge { - .addToReadingList(mNativeBookmarkBridge, parentId, title, url); - } - -+ // Used to bookmark all tabs in a specific folder, created if not existing -+ public BookmarkId addToTabsCollection(Tab tab) { -+ BookmarkId parent = getTabsCollectionFolderId(); -+ BookmarkId existingId = BookmarkBridgeJni.get().getBookmarkIdForTabsCollection( -+ mNativeBookmarkBridge, tab.getOriginalUrl()); -+ if (existingId != null && existingId.getId() != BookmarkId.INVALID_ID) { -+ BookmarkId existingBookmarkId = new BookmarkId(existingId.getId(), BookmarkType.NORMAL); -+ BookmarkItem existingBookmark = getBookmarkById(existingBookmarkId); -+ if (parent.equals(existingBookmark.getParentId())) { -+ // bookmark already exists in the tabs collection folder -+ return existingBookmarkId; -+ } -+ } -+ BookmarkId bookmarkId = -+ addBookmark(parent, getChildCount(parent), tab.getTitle(), tab.getUrl()); -+ -+ if (bookmarkId == null) { -+ Log.e(TAG, -+ "Failed to add bookmarks: parentTypeAndId %s", parent); -+ } -+ return bookmarkId; -+ } -+ - /** - * Helper method to mark an item as read. - * -@@ -1099,6 +1135,9 @@ class BookmarkBridge { - BookmarkId getMostRecentlyAddedUserBookmarkIdForUrl( - long nativeBookmarkBridge, @JniType("GURL") GURL url); - -+ BookmarkId getBookmarkIdForTabsCollection( -+ long nativeBookmarkBridge, GURL url); -+ - BookmarkItem getBookmarkById(long nativeBookmarkBridge, long id, int type); - - void getTopLevelFolderIds( -@@ -1120,6 +1159,8 @@ class BookmarkBridge { - - BookmarkId getRootFolderId(long nativeBookmarkBridge); - -+ BookmarkId getTabsCollectionFolderId(long nativeBookmarkBridge, BookmarkBridge caller); -+ - BookmarkId getMobileFolderId(long nativeBookmarkBridge); - - BookmarkId getOtherFolderId(long nativeBookmarkBridge); -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 -@@ -169,14 +169,15 @@ class Writer : public base::RefCountedThreadSafe { - BookmarkCodec codec; - local_bookmarks_ = - codec.Encode(model->bookmark_bar_node(), model->other_node(), -- model->mobile_node(), /*sync_metadata_str=*/std::string()); -+ model->mobile_node(), model->tabs_collection_node(), -+ /*sync_metadata_str=*/std::string()); - - if (model->account_bookmark_bar_node()) { - CHECK(model->account_other_node()); - CHECK(model->account_mobile_node()); - account_bookmarks_ = codec.Encode( - model->account_bookmark_bar_node(), model->account_other_node(), -- model->account_mobile_node(), /*sync_metadata_str=*/std::string()); -+ model->account_mobile_node(), /*tabs_folder_node*/ nullptr, /*sync_metadata_str=*/std::string()); - } else { - CHECK(!model->account_other_node()); - CHECK(!model->account_mobile_node()); -@@ -210,6 +211,9 @@ class Writer : public base::RefCountedThreadSafe { - base::Value::Dict* mobile_folder_value = local_permanent_folders->FindDict( - BookmarkCodec::kMobileBookmarkFolderNameKey); - CHECK(mobile_folder_value); -+ base::Value::Dict* tabs_collection_value = -+ local_permanent_folders->FindDict(BookmarkCodec::kTabsBookmarkFolderNameKey); -+ CHECK(tabs_collection_value); - - base::Value::Dict* account_permanent_folders = - account_bookmarks_.FindDict(BookmarkCodec::kRootsKey); -@@ -285,6 +289,10 @@ class Writer : public base::RefCountedThreadSafe { - return bookmark_html_writer::Result::kCouldNotWriteNodes; - } - -+ if (!WriteDescendants(*tabs_collection_value)) { -+ return bookmark_html_writer::Result::kCouldNotWriteNodes; -+ } -+ - DecrementIndent(); - - if (!Write(kFolderChildrenEnd) || !Write(kNewline)) { -@@ -431,6 +439,7 @@ class Writer : public base::RefCountedThreadSafe { - case BookmarkNode::URL: - case BookmarkNode::OTHER_NODE: - case BookmarkNode::MOBILE: -+ case BookmarkNode::TABS_COLLECTION: - NOTREACHED(); - } - -@@ -559,6 +568,7 @@ void BookmarkFaviconFetcher::ExportBookmarks() { - ExtractUrls(model->bookmark_bar_node()); - ExtractUrls(model->other_node()); - ExtractUrls(model->mobile_node()); -+ ExtractUrls(model->tabs_collection_node()); - - if (model->account_bookmark_bar_node()) { - CHECK(model->account_other_node()); -diff --git a/chrome/browser/bookmarks/bookmark_parent_folder.cc b/chrome/browser/bookmarks/bookmark_parent_folder.cc ---- a/chrome/browser/bookmarks/bookmark_parent_folder.cc -+++ b/chrome/browser/bookmarks/bookmark_parent_folder.cc -@@ -18,6 +18,7 @@ BookmarkParentFolder GetBookmarkParentFolderFromPermanentNode( - CHECK(node->is_permanent_node()); - switch (node->type()) { - case bookmarks::BookmarkNode::URL: -+ case bookmarks::BookmarkNode::TABS_COLLECTION: - NOTREACHED(); - case bookmarks::BookmarkNode::FOLDER: - // TODO(crbug.com/381252292): Consider extending type with a value -diff --git a/chrome/browser/bookmarks/permanent_folder_ordering_tracker.cc b/chrome/browser/bookmarks/permanent_folder_ordering_tracker.cc ---- a/chrome/browser/bookmarks/permanent_folder_ordering_tracker.cc -+++ b/chrome/browser/bookmarks/permanent_folder_ordering_tracker.cc -@@ -26,6 +26,7 @@ bool IsValidTrackedType(BookmarkNode::Type type) { - switch (type) { - case bookmarks::BookmarkNode::URL: - case bookmarks::BookmarkNode::FOLDER: -+ case bookmarks::BookmarkNode::TABS_COLLECTION: - NOTREACHED(); - - case bookmarks::BookmarkNode::BOOKMARK_BAR: -@@ -303,6 +304,7 @@ void PermanentFolderOrderingTracker::SetTrackedPermanentNodes() { - switch (tracked_type_) { - case bookmarks::BookmarkNode::URL: - case bookmarks::BookmarkNode::FOLDER: -+ case bookmarks::BookmarkNode::TABS_COLLECTION: - NOTREACHED(); - - case bookmarks::BookmarkNode::BOOKMARK_BAR: -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 -@@ -88,7 +88,7 @@ public class DownloadLocationCustomView extends ScrollView - mDirectoryAdapter.update(); - } - -- void setTitle(CharSequence title) { -+ public void setTitle(CharSequence title) { - mTitle.setText(title); - } - -@@ -96,7 +96,7 @@ public class DownloadLocationCustomView extends ScrollView - mSubtitleView.setText(subtitle); - } - -- void setFileName(CharSequence fileName) { -+ public void setFileName(CharSequence fileName) { - mFileName.setText(fileName); - } - -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 -@@ -4437,6 +4437,9 @@ To change this setting, BEGIN_LINKdelete the Chrome d - - Select tabs - -+ -+ Bookmark all tabs -+ - - Get image descriptions - -diff --git a/chrome/browser/ui/bookmarks/bookmark_ui_operations_helper.cc b/chrome/browser/ui/bookmarks/bookmark_ui_operations_helper.cc ---- a/chrome/browser/ui/bookmarks/bookmark_ui_operations_helper.cc -+++ b/chrome/browser/ui/bookmarks/bookmark_ui_operations_helper.cc -@@ -105,6 +105,8 @@ ui::mojom::DragOperation BookmarkUIOperationsHelper::DropBookmarks( - if (is_reorder) { - base::UmaHistogramEnumeration("Bookmarks.ReorderDropTarget", target); - switch (target_parent()->GetType()) { -+ case bookmarks::BookmarkNode::TABS_COLLECTION: -+ break; - case bookmarks::BookmarkNode::URL: - NOTREACHED(); - case bookmarks::BookmarkNode::FOLDER: -diff --git a/chrome/browser/ui/webui_browser/bookmark_bar_page_handler.cc b/chrome/browser/ui/webui_browser/bookmark_bar_page_handler.cc ---- a/chrome/browser/ui/webui_browser/bookmark_bar_page_handler.cc -+++ b/chrome/browser/ui/webui_browser/bookmark_bar_page_handler.cc -@@ -37,6 +37,8 @@ bookmark_bar::mojom::BookmarkType ConvertType( - return bookmark_bar::mojom::BookmarkType::OTHER_NODE; - case bookmarks::BookmarkNode::MOBILE: - return bookmark_bar::mojom::BookmarkType::MOBILE; -+ case bookmarks::BookmarkNode::TABS_COLLECTION: -+ NOTREACHED(); - } - NOTREACHED(); - } -diff --git a/components/bookmark_bar_strings.grdp b/components/bookmark_bar_strings.grdp ---- a/components/bookmark_bar_strings.grdp -+++ b/components/bookmark_bar_strings.grdp -@@ -15,6 +15,9 @@ - - Mobile bookmarks - -+ -+ Tabs collection -+ - - Other bookmarks - -@@ -29,6 +32,9 @@ - - Mobile Bookmarks - -+ -+ Tabs Collection -+ - - Other Bookmarks - -diff --git a/components/bookmarks/browser/bookmark_codec.cc b/components/bookmarks/browser/bookmark_codec.cc ---- a/components/bookmarks/browser/bookmark_codec.cc -+++ b/components/bookmarks/browser/bookmark_codec.cc -@@ -39,6 +39,7 @@ const char BookmarkCodec::kBookmarkBarFolderNameKey[] = "bookmark_bar"; - const char BookmarkCodec::kOtherBookmarkFolderNameKey[] = "other"; - // The value is left as 'synced' for historical reasons. - const char BookmarkCodec::kMobileBookmarkFolderNameKey[] = "synced"; -+const char BookmarkCodec::kTabsBookmarkFolderNameKey[] = "tabs"; - const char BookmarkCodec::kVersionKey[] = "version"; - const char BookmarkCodec::kChecksumKey[] = "checksum"; - const char BookmarkCodec::kChecksumSHA256Key[] = "checksum_sha256"; -@@ -99,6 +100,7 @@ base::Value::Dict BookmarkCodec::Encode( - const BookmarkNode* bookmark_bar_node, - const BookmarkNode* other_folder_node, - const BookmarkNode* mobile_folder_node, -+ const BookmarkNode* tabs_folder_node, - std::string sync_metadata_str) { - ids_reassigned_ = false; - uuids_reassigned_ = false; -@@ -124,6 +126,8 @@ base::Value::Dict BookmarkCodec::Encode( - roots.Set(kBookmarkBarFolderNameKey, EncodeNode(bookmark_bar_node)); - roots.Set(kOtherBookmarkFolderNameKey, EncodeNode(other_folder_node)); - roots.Set(kMobileBookmarkFolderNameKey, EncodeNode(mobile_folder_node)); -+ if (tabs_folder_node) -+ roots.Set(kTabsBookmarkFolderNameKey, EncodeNode(tabs_folder_node)); - } else { - // No permanent node should have been provided. - CHECK(!other_folder_node); -@@ -148,6 +152,7 @@ bool BookmarkCodec::Decode(const base::Value::Dict& value, - BookmarkNode* bb_node, - BookmarkNode* other_folder_node, - BookmarkNode* mobile_folder_node, -+ BookmarkNode* tabs_folder_node, - int64_t* max_id, - std::string* sync_metadata_str) { - const int64_t max_already_assigned_id = -@@ -162,7 +167,8 @@ bool BookmarkCodec::Decode(const base::Value::Dict& value, - base::Uuid::ParseLowercase(kBookmarkBarNodeUuid), - base::Uuid::ParseLowercase(kOtherBookmarksNodeUuid), - base::Uuid::ParseLowercase(kMobileBookmarksNodeUuid), -- base::Uuid::ParseLowercase(kManagedNodeUuid)}; -+ base::Uuid::ParseLowercase(kManagedNodeUuid), -+ base::Uuid::ParseLowercase(kTabsCollectionBookmarksNodeUuid)}; - ids_reassigned_ = false; - uuids_reassigned_ = false; - ids_valid_ = true; -@@ -171,6 +177,7 @@ bool BookmarkCodec::Decode(const base::Value::Dict& value, - stored_sha256_checksum_.clear(); - InitializeChecksum(); - bool success = DecodeHelper(bb_node, other_folder_node, mobile_folder_node, -+ tabs_folder_node, - value, sync_metadata_str); - FinalizeChecksum(); - -@@ -180,7 +187,7 @@ bool BookmarkCodec::Decode(const base::Value::Dict& value, - if (!ids_valid_ || (computed_checksum_ != stored_checksum_) || - (use_sha256 && computed_sha256_checksum_ != stored_sha256_checksum_)) { - maximum_id_ = max_already_assigned_id; -- ReassignIDs(bb_node, other_folder_node, mobile_folder_node); -+ ReassignIDs(bb_node, other_folder_node, mobile_folder_node, tabs_folder_node); - } - *max_id = maximum_id_ + 1; - return success; -@@ -239,6 +246,7 @@ base::Value::Dict BookmarkCodec::EncodeMetaInfo( - bool BookmarkCodec::DecodeHelper(BookmarkNode* bb_node, - BookmarkNode* other_folder_node, - BookmarkNode* mobile_folder_node, -+ BookmarkNode* tabs_folder_node, - const base::Value::Dict& value, - std::string* sync_metadata_str) { - std::optional version = value.FindInt(kVersionKey); -@@ -284,6 +292,8 @@ bool BookmarkCodec::DecodeHelper(BookmarkNode* bb_node, - roots->FindDict(kOtherBookmarkFolderNameKey); - const base::Value::Dict* mobile_folder_value = - roots->FindDict(kMobileBookmarkFolderNameKey); -+ const base::Value::Dict* tabs_folder_value = -+ roots->FindDict(kTabsBookmarkFolderNameKey); - - if (!bb_value || !other_folder_value || !mobile_folder_value) - return false; -@@ -291,6 +301,8 @@ bool BookmarkCodec::DecodeHelper(BookmarkNode* bb_node, - DecodeNode(*bb_value, nullptr, bb_node); - DecodeNode(*other_folder_value, nullptr, other_folder_node); - DecodeNode(*mobile_folder_value, nullptr, mobile_folder_node); -+ if (tabs_folder_value) -+ DecodeNode(*tabs_folder_value, nullptr, tabs_folder_node); - - // Need to reset the title as the title is persisted and restored from - // the file. -@@ -499,12 +511,14 @@ void BookmarkCodec::DecodeMetaInfoHelper( - - void BookmarkCodec::ReassignIDs(BookmarkNode* bb_node, - BookmarkNode* other_node, -- BookmarkNode* mobile_node) { -+ BookmarkNode* mobile_node, -+ BookmarkNode* tabs_folder_node) { - ids_.clear(); - reassigned_ids_per_old_id_.clear(); - ReassignIDsHelper(bb_node); - ReassignIDsHelper(other_node); - ReassignIDsHelper(mobile_node); -+ ReassignIDsHelper(tabs_folder_node); - ids_reassigned_ = true; - } - -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 -@@ -44,6 +44,7 @@ class BookmarkCodec { - const BookmarkNode* bookmark_bar_node, - const BookmarkNode* other_folder_node, - const BookmarkNode* mobile_folder_node, -+ const BookmarkNode* tabs_folder_node, - std::string sync_metadata_str); - - // Decodes the previously encoded value to the specified nodes as well as -@@ -62,6 +63,7 @@ class BookmarkCodec { - BookmarkNode* bb_node, - BookmarkNode* other_folder_node, - BookmarkNode* mobile_folder_node, -+ BookmarkNode* tabs_folder_node, - int64_t* max_node_id, - std::string* sync_metadata_str); - -@@ -100,6 +102,7 @@ class BookmarkCodec { - static const char kBookmarkBarFolderNameKey[]; - static const char kOtherBookmarkFolderNameKey[]; - static const char kMobileBookmarkFolderNameKey[]; -+ static const char kTabsBookmarkFolderNameKey[]; - static const char kVersionKey[]; - static const char kChecksumKey[]; - static const char kChecksumSHA256Key[]; -@@ -133,6 +136,7 @@ class BookmarkCodec { - bool DecodeHelper(BookmarkNode* bb_node, - BookmarkNode* other_folder_node, - BookmarkNode* mobile_folder_node, -+ BookmarkNode* tabs_folder_node, - const base::Value::Dict& value, - std::string* sync_metadata_str); - -@@ -143,7 +147,8 @@ class BookmarkCodec { - // Reassigns bookmark IDs for all nodes. - void ReassignIDs(BookmarkNode* bb_node, - BookmarkNode* other_node, -- BookmarkNode* mobile_node); -+ BookmarkNode* mobile_node, -+ BookmarkNode* tabs_folder_node); - - // Helper to recursively reassign IDs. - void ReassignIDsHelper(BookmarkNode* node); -diff --git a/components/bookmarks/browser/bookmark_load_details.cc b/components/bookmarks/browser/bookmark_load_details.cc ---- a/components/bookmarks/browser/bookmark_load_details.cc -+++ b/components/bookmarks/browser/bookmark_load_details.cc -@@ -16,7 +16,7 @@ namespace { - - // Number of top-level permanent folders excluding the managed node and account - // bookmarks. --constexpr size_t kNumDefaultTopLevelPermanentFolders = 3u; -+constexpr size_t kNumDefaultTopLevelPermanentFolders = 4u; - - void UpdateUserFolderStatsRecursively(const BookmarkNode& node, - bool top_level, -@@ -63,6 +63,9 @@ BookmarkLoadDetails::BookmarkLoadDetails() - mobile_folder_node_ = static_cast( - root_node_->Add(BookmarkPermanentNode::CreateMobileBookmarks( - /*id=*/0, /*is_account_node=*/false))); -+ tabs_collection_folder_node_ = static_cast( -+ root_node_->Add(BookmarkPermanentNode::CreateTabsCollectionBookmarks( -+ /*id=*/0, /*is_account_node=*/false))); - - // Set the nodes' `date_added` to the same time so that there is no inherent - // hierarchy in terms of their added time between them. This is relevant for -@@ -119,6 +122,10 @@ void BookmarkLoadDetails::PopulateNodeIdsForLocalOrSyncablePermanentNodes() { - if (mobile_folder_node_->id() == 0) { - mobile_folder_node_->set_id(max_id_++); - } -+ -+ if (tabs_collection_folder_node_->id() == 0) { -+ tabs_collection_folder_node_->set_id(max_id_++); -+ } - } - - void BookmarkLoadDetails::AddManagedNode( -@@ -131,6 +138,7 @@ void BookmarkLoadDetails::AddManagedNode( - CHECK_NE(bb_node_->id(), 0); - CHECK_NE(other_folder_node_->id(), 0); - CHECK_NE(mobile_folder_node_->id(), 0); -+ CHECK_NE(tabs_collection_folder_node_->id(), 0); - - has_managed_node_ = true; - root_node_->Add(std::move(managed_node)); -@@ -138,8 +146,8 @@ void BookmarkLoadDetails::AddManagedNode( - - void BookmarkLoadDetails::CreateIndices() { - local_or_syncable_uuid_index_.insert(root_node_.get()); -- static_assert(kNumDefaultTopLevelPermanentFolders == 3u, -- "The code below assumes three permanent nodes"); -+ static_assert(kNumDefaultTopLevelPermanentFolders == 4u, -+ "The code below assumes 4 permanent nodes"); - for (const auto& child : root_node_->children()) { - if (child.get() == account_bb_node_ || - child.get() == account_other_folder_node_ || -@@ -158,6 +166,7 @@ void BookmarkLoadDetails::ResetPermanentNodePointers() { - bb_node_ = nullptr; - other_folder_node_ = nullptr; - mobile_folder_node_ = nullptr; -+ tabs_collection_folder_node_ = nullptr; - account_bb_node_ = nullptr; - account_other_folder_node_ = nullptr; - account_mobile_folder_node_ = nullptr; -diff --git a/components/bookmarks/browser/bookmark_load_details.h b/components/bookmarks/browser/bookmark_load_details.h ---- a/components/bookmarks/browser/bookmark_load_details.h -+++ b/components/bookmarks/browser/bookmark_load_details.h -@@ -41,6 +41,7 @@ class BookmarkLoadDetails { - BookmarkPermanentNode* bb_node() { return bb_node_; } - BookmarkPermanentNode* mobile_folder_node() { return mobile_folder_node_; } - BookmarkPermanentNode* other_folder_node() { return other_folder_node_; } -+ BookmarkPermanentNode* tabs_collection_folder_node() { return tabs_collection_folder_node_; } - - // Account permanent nodes (null unless `AddAccountPermanentNodes()` is - // called). -@@ -156,6 +157,7 @@ class BookmarkLoadDetails { - raw_ptr bb_node_; - raw_ptr other_folder_node_; - raw_ptr mobile_folder_node_; -+ raw_ptr tabs_collection_folder_node_; - raw_ptr account_bb_node_; - raw_ptr account_other_folder_node_; - raw_ptr account_mobile_folder_node_; -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 -@@ -909,7 +909,7 @@ bool BookmarkModel::HasUserCreatedBookmarksOrFolders() const { - (account_bookmark_bar_node_ && - !account_bookmark_bar_node_->children().empty()) || - (account_other_node_ && !account_other_node_->children().empty()) || -- (account_mobile_node_ && !account_mobile_node_->children().empty()); -+ (account_mobile_node_ && !account_mobile_node_->children().empty() && tabs_collection_node_->children().empty()); - } - - bool BookmarkModel::IsBookmarked(const GURL& url) const { -@@ -1241,6 +1241,7 @@ void BookmarkModel::DoneLoading(std::unique_ptr details) { - bookmark_bar_node_ = details->bb_node(); - other_node_ = details->other_folder_node(); - mobile_node_ = details->mobile_folder_node(); -+ tabs_collection_node_ = details->tabs_collection_folder_node(); - - account_bookmark_bar_node_ = details->account_bb_node(); - account_other_node_ = details->account_other_folder_node(); -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 -@@ -150,6 +150,12 @@ class BookmarkModel : public BookmarkUndoProvider, - // bookmarks in the account storage). - const BookmarkPermanentNode* account_mobile_node() const; - -+ // Returns the 'mobile' node. This is NULL until loaded. -+ const BookmarkPermanentNode* tabs_collection_node() const { -+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); -+ return tabs_collection_node_; -+ } -+ - bool is_root_node(const BookmarkNode* node) const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return node == root_; -@@ -628,6 +634,7 @@ class BookmarkModel : public BookmarkUndoProvider, - raw_ptr account_bookmark_bar_node_ = nullptr; - raw_ptr account_other_node_ = nullptr; - raw_ptr account_mobile_node_ = nullptr; -+ raw_ptr tabs_collection_node_ = nullptr; - - // The maximum ID assigned to the bookmark nodes in the model. - int64_t next_node_id_ = 1; -diff --git a/components/bookmarks/browser/bookmark_node.cc b/components/bookmarks/browser/bookmark_node.cc ---- a/components/bookmarks/browser/bookmark_node.cc -+++ b/components/bookmarks/browser/bookmark_node.cc -@@ -161,6 +161,8 @@ bool BookmarkPermanentNode::IsTypeVisibleWhenEmpty(Type type) { - #endif - - switch (type) { -+ case bookmarks::BookmarkNode::TABS_COLLECTION: -+ return !is_desktop; - case BookmarkNode::URL: - NOTREACHED(); - case BookmarkNode::FOLDER: -@@ -213,6 +215,17 @@ BookmarkPermanentNode::CreateMobileBookmarks(int64_t id, - is_account_node)); - } - -+// static -+std::unique_ptr -+BookmarkPermanentNode::CreateTabsCollectionBookmarks(int64_t id, -+ bool is_account_node) { -+ // base::WrapUnique() used because the constructor is private. -+ return base::WrapUnique(new BookmarkPermanentNode( -+ id, TABS_COLLECTION, base::Uuid::ParseLowercase(kTabsCollectionBookmarksNodeUuid), -+ l10n_util::GetStringUTF16(IDS_BOOKMARK_BAR_TABS_COLLECTION_FOLDER_NAME), -+ is_account_node)); -+} -+ - BookmarkPermanentNode::BookmarkPermanentNode(int64_t id, - Type type, - const base::Uuid& uuid, -diff --git a/components/bookmarks/browser/bookmark_node.h b/components/bookmarks/browser/bookmark_node.h ---- a/components/bookmarks/browser/bookmark_node.h -+++ b/components/bookmarks/browser/bookmark_node.h -@@ -35,6 +35,7 @@ class BookmarkNode : public ui::TreeNode, public TitledUrlNode { - FOLDER, - BOOKMARK_BAR, - OTHER_NODE, -+ TABS_COLLECTION, - MOBILE - }; - -@@ -249,6 +250,9 @@ class BookmarkPermanentNode : public BookmarkNode { - static std::unique_ptr CreateMobileBookmarks( - int64_t id, - bool is_account_node); -+ static std::unique_ptr CreateTabsCollectionBookmarks( -+ int64_t id, -+ bool is_account_node); - - // Returns whether the permanent node of type `type` should be visible even - // when it is empty (i.e. no children). -diff --git a/components/bookmarks/browser/bookmark_storage.cc b/components/bookmarks/browser/bookmark_storage.cc ---- a/components/bookmarks/browser/bookmark_storage.cc -+++ b/components/bookmarks/browser/bookmark_storage.cc -@@ -45,6 +45,7 @@ base::Value::Dict EncodeModelToDict( - case BookmarkStorage::kSelectLocalOrSyncableNodes: - return codec.Encode( - model->bookmark_bar_node(), model->other_node(), model->mobile_node(), -+ model->tabs_collection_node(), - model->client()->EncodeLocalOrSyncableBookmarkSyncMetadata()); - case BookmarkStorage::kSelectAccountNodes: - // Either all permanent folders or none should exist. -@@ -61,6 +62,7 @@ base::Value::Dict EncodeModelToDict( - return codec.Encode(model->account_bookmark_bar_node(), - model->account_other_node(), - model->account_mobile_node(), -+ nullptr, - model->client()->EncodeAccountBookmarkSyncMetadata()); - } - -diff --git a/components/bookmarks/browser/bookmark_uuids.cc b/components/bookmarks/browser/bookmark_uuids.cc ---- a/components/bookmarks/browser/bookmark_uuids.cc -+++ b/components/bookmarks/browser/bookmark_uuids.cc -@@ -35,6 +35,9 @@ const char kManagedNodeUuid[] = "323123f4-9381-5aee-80e6-ea5fca2f7672"; - // see https://crbug.com/1484372 for details. - const char kShoppingCollectionUuid[] = "89fc5b66-beb6-56c1-a99b-70635d7df201"; - -+const char kTabsCollectionBookmarksNodeUuid[] = -+ "00000000-0000-4000-a000-000000000006"; -+ - // This value is the result of exercising sync's function - // syncer::InferGuidForLegacyBookmark() with an empty input. - const char kBannedUuidDueToPastSyncBug[] = -diff --git a/components/bookmarks/browser/bookmark_uuids.h b/components/bookmarks/browser/bookmark_uuids.h ---- a/components/bookmarks/browser/bookmark_uuids.h -+++ b/components/bookmarks/browser/bookmark_uuids.h -@@ -14,6 +14,7 @@ extern const char kBookmarkBarNodeUuid[]; - extern const char kOtherBookmarksNodeUuid[]; - extern const char kMobileBookmarksNodeUuid[]; - extern const char kManagedNodeUuid[]; -+extern const char kTabsCollectionBookmarksNodeUuid[]; - extern const char kShoppingCollectionUuid[]; - - // A bug in sync caused some problematic UUIDs to be produced. -diff --git a/components/bookmarks/browser/model_loader.cc b/components/bookmarks/browser/model_loader.cc ---- a/components/bookmarks/browser/model_loader.cc -+++ b/components/bookmarks/browser/model_loader.cc -@@ -74,6 +74,9 @@ std::unique_ptr LoadBookmarks( - std::unique_ptr account_mobile_folder_node = - BookmarkPermanentNode::CreateMobileBookmarks( - 0, /*is_account_node=*/true); -+ std::unique_ptr tabs_collection_folder_node = -+ BookmarkPermanentNode::CreateTabsCollectionBookmarks( -+ 0, /*is_account_node=*/true); - - std::optional root_dict = - LoadFileToDict(account_file_path); -@@ -81,7 +84,8 @@ std::unique_ptr LoadBookmarks( - if (root_dict.has_value() && - codec.Decode(*root_dict, /*already_assigned_ids=*/{}, - account_bb_node.get(), account_other_folder_node.get(), -- account_mobile_folder_node.get(), &max_node_id, -+ account_mobile_folder_node.get(), -+ tabs_collection_folder_node.get(), &max_node_id, - &sync_metadata_str)) { - ids_assigned_to_account_nodes = codec.release_assigned_ids(); - -@@ -118,7 +122,8 @@ std::unique_ptr LoadBookmarks( - if (root_dict.has_value() && - codec.Decode(*root_dict, std::move(ids_assigned_to_account_nodes), - details->bb_node(), details->other_folder_node(), -- details->mobile_folder_node(), &max_node_id, -+ details->mobile_folder_node(), -+ details->tabs_collection_folder_node(), &max_node_id, - &sync_metadata_str)) { - details->set_local_or_syncable_sync_metadata_str( - std::move(sync_metadata_str)); -diff --git a/components/sync_bookmarks/bookmark_specifics_conversions.cc b/components/sync_bookmarks/bookmark_specifics_conversions.cc ---- a/components/sync_bookmarks/bookmark_specifics_conversions.cc -+++ b/components/sync_bookmarks/bookmark_specifics_conversions.cc -@@ -447,6 +447,7 @@ sync_pb::BookmarkSpecifics::Type GetProtoTypeFromBookmarkNode( - case bookmarks::BookmarkNode::BOOKMARK_BAR: - case bookmarks::BookmarkNode::OTHER_NODE: - case bookmarks::BookmarkNode::MOBILE: -+ case bookmarks::BookmarkNode::TABS_COLLECTION: - DCHECK(node->is_folder()); - return sync_pb::BookmarkSpecifics::FOLDER; - } --- diff --git a/build/cromite_patches/Add-menu-item-to-view-source.patch b/build/cromite_patches/Add-menu-item-to-view-source.patch deleted file mode 100644 index 4c89e086..00000000 --- a/build/cromite_patches/Add-menu-item-to-view-source.patch +++ /dev/null @@ -1,128 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Mon, 13 Jul 2020 00:37:06 +0200 -Subject: Add menu item to view source - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - chrome/android/java/res/values/ids.xml | 1 + - .../chrome/browser/ChromeTabbedActivity.java | 2 ++ - .../chrome/browser/app/ChromeActivity.java | 5 ++++ - .../AppMenuPropertiesDelegateImpl.java | 24 +++++++++++++++++++ - .../CustomTabAppMenuPropertiesDelegate.java | 3 +++ - .../TabbedAppMenuPropertiesDelegate.java | 3 +++ - .../strings/android_chrome_strings.grd | 4 ++++ - 7 files changed, 42 insertions(+) - -diff --git a/chrome/android/java/res/values/ids.xml b/chrome/android/java/res/values/ids.xml ---- a/chrome/android/java/res/values/ids.xml -+++ b/chrome/android/java/res/values/ids.xml -@@ -133,6 +133,7 @@ found in the LICENSE file. - - - -+ - - - -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 -@@ -3946,6 +3946,8 @@ public class ChromeTabbedActivity extends ChromeActivity { - NewTabPageUma.recordAction(NewTabPageUma.ACTION_OPENED_DOWNLOADS_MANAGER); - } - RecordUserAction.record("MobileMenuDownloadManager"); -+ } else if (id == R.id.view_source_id) { -+ currentTab.getWebContents().getNavigationController().loadUrl(new LoadUrlParams("view-source:"+currentTab.getUrl().getSpec())); - } else if (id == R.id.open_recently_closed_tab) { - TabModel currentModel = mTabModelSelector.getCurrentModel(); - if (!currentModel.isIncognito()) currentModel.openMostRecentlyClosedEntry(); -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 -@@ -2697,6 +2697,11 @@ public abstract class ChromeActivity extends AsyncInitializationActivity - return doOpenWebApk(currentTab); - } - -+ if (id == R.id.view_source_id) { -+ currentTab.getWebContents().getNavigationController().loadUrl(new LoadUrlParams("view-source:"+currentTab.getUrl().getSpec())); -+ return true; -+ } -+ - if (id == R.id.request_desktop_site_id || id == R.id.request_desktop_site_check_id) { - boolean usingDesktopUserAgent = - currentTab.getWebContents().getNavigationController().getUseDesktopUserAgent(); -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 -@@ -989,6 +989,30 @@ public abstract class AppMenuPropertiesDelegateImpl implements AppMenuProperties - return false; - } - -+ /** -+ * Updates the view source menu item's state. -+ * -+ * @param menu {@link Menu} for view source. -+ * @param currentTab Current tab being displayed. -+ */ -+ protected void buildAddViewSourceItem( -+ MVCListAdapter.ModelList modelList, -+ @Nullable Tab currentTab) { -+ boolean visible = false; -+ if (currentTab != null) { -+ String url = currentTab.getUrl().getSpec(); -+ visible = !url.isEmpty() && !url.startsWith("view-source:"); -+ } -+ if (visible) { -+ modelList.add(new MVCListAdapter.ListItem( -+ AppMenuHandler.AppMenuItemType.STANDARD, -+ buildModelForStandardMenuItem( -+ R.id.view_source_id, -+ R.string.view_source, -+ shouldShowIconBeforeItem() ? R.drawable.ic_drive_document_24dp : 0))); -+ } -+ } -+ - /** - * Updates the bookmark item's visibility. - * -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 -@@ -378,6 +378,9 @@ public class CustomTabAppMenuPropertiesDelegate extends AppMenuPropertiesDelegat - modelList.add(buildAddToHomescreenListItem(currentTab, false)); - } - -+ // Add view source item -+ buildAddViewSourceItem(modelList, currentTab); -+ - // --- Request Desktop Site --- - if (requestDesktopSiteVisible) { - MVCListAdapter.ListItem rdsListItem = -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedAppMenuPropertiesDelegate.java -@@ -358,6 +358,9 @@ public class TabbedAppMenuPropertiesDelegate extends AppMenuPropertiesDelegateIm - modelList.add(buildAddToHomescreenListItem(currentTab, shouldShowIconBeforeItem())); - } - -+ // Add view source item -+ buildAddViewSourceItem(modelList, currentTab); -+ - // RDS - MVCListAdapter.ListItem rdsListItem = - maybeBuildRequestDesktopSiteListItem( -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 -@@ -324,6 +324,10 @@ CHAR_LIMIT guidelines: - Collaboration - - -+ -+ View source -+ -+ - - - You and Google --- diff --git a/build/cromite_patches/Add-option-to-force-tablet-UI.patch b/build/cromite_patches/Add-option-to-force-tablet-UI.patch deleted file mode 100644 index 930d9de0..00000000 --- a/build/cromite_patches/Add-option-to-force-tablet-UI.patch +++ /dev/null @@ -1,747 +0,0 @@ -From: uazo -Date: Sun, 5 May 2024 09:34:39 +0000 -Subject: Add option to force tablet UI - -License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html ---- - .../layout/custom_tabs_control_container.xml | 2 +- - .../java/res/layout/recent_tabs_page.xml | 2 +- - .../java/res/values-sw600dp/dimens.xml | 4 ++-- - chrome/android/java/res/values/dimens.xml | 6 +++++- - .../browser/ChromeBaseAppCompatActivity.java | 3 +++ - .../chrome/browser/WarmupManager.java | 5 ++++- - .../ChromeAccessibilitySettingsDelegate.java | 19 ++++++++++++++++++ - .../chrome/browser/app/ChromeActivity.java | 4 +++- - .../overlays/strip/StripLayoutHelper.java | 10 ++++++++-- - .../strip/StripLayoutHelperManager.java | 6 +++++- - .../scene_layer/TabStripSceneLayer.java | 8 ++++++++ - .../init/ChromeBrowserInitializer.java | 2 ++ - .../tabbed_mode/TabbedRootUiCoordinator.java | 4 +++- - .../chrome/browser/ui/RootUiCoordinator.java | 6 +++++- - chrome/browser/preferences/BUILD.gn | 1 + - .../preferences/ChromePreferenceKeys.java | 1 + - .../preferences/ChromeSharedPreferences.java | 12 +++++++++++ - .../LegacyChromePreferenceKeys.java | 1 + - .../AppHeaderCoordinator.java | 2 ++ - .../omnibox/LocationBarCoordinator.java | 2 +- - .../strings/android_chrome_strings.grd | 7 +++++++ - .../java/res/layout/control_container.xml | 8 ++++---- - .../java/res/layout/toolbar_tablet.xml | 2 +- - .../java/res/values-sw600dp/dimens.xml | 5 +++-- - .../toolbar/java/res/values/dimens.xml | 6 ++++-- - .../browser/toolbar/ControlContainer.java | 2 +- - .../toolbar/top/ToolbarControlContainer.java | 20 ++++++++++++++++++- - .../browser/toolbar/top/ToolbarLayout.java | 5 ++++- - .../tab_strip/HeightTransitionHandler.java | 2 ++ - .../TabStripTransitionCoordinator.java | 6 +++++- - .../res/xml/accessibility_preferences.xml | 5 +++++ - .../accessibility/AccessibilitySettings.java | 13 ++++++++++++ - .../AccessibilitySettingsDelegate.java | 2 ++ - .../chromium/ui/base/DeviceFormFactor.java | 14 +++++++++++++ - 34 files changed, 171 insertions(+), 26 deletions(-) - -diff --git a/chrome/android/java/res/layout/custom_tabs_control_container.xml b/chrome/android/java/res/layout/custom_tabs_control_container.xml ---- a/chrome/android/java/res/layout/custom_tabs_control_container.xml -+++ b/chrome/android/java/res/layout/custom_tabs_control_container.xml -@@ -31,7 +31,7 @@ found in the LICENSE file. - android:id="@+id/find_toolbar_stub" - android:inflatedId="@+id/find_toolbar" - android:visibility="gone" -- android:layout_marginTop="@dimen/tab_strip_height" -+ android:layout_marginTop="@dimen/tab_strip_height_cromite" - android:layout_width="match_parent" - android:layout_height="@dimen/custom_tabs_control_container_height" - android:layout="@layout/find_toolbar" /> -diff --git a/chrome/android/java/res/layout/recent_tabs_page.xml b/chrome/android/java/res/layout/recent_tabs_page.xml ---- a/chrome/android/java/res/layout/recent_tabs_page.xml -+++ b/chrome/android/java/res/layout/recent_tabs_page.xml -@@ -11,7 +11,7 @@ found in the LICENSE file. - android:id="@+id/history_navigation" - android:layout_width="match_parent" - android:layout_height="match_parent" -- android:paddingTop="@dimen/tab_strip_height" > -+ android:paddingTop="@dimen/tab_strip_height_cromite" > - - 14sp - - -- 96dp -- 64dp -+ 96dp -+ 96dp - - - 60dp -diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml ---- a/chrome/android/java/res/values/dimens.xml -+++ b/chrome/android/java/res/values/dimens.xml -@@ -119,9 +119,13 @@ found in the LICENSE file. - 16dp - - -- @dimen/default_action_bar_height -+ @dimen/default_action_bar_height -+ 96dp - @dimen/default_action_bar_height - -+ -+ 56dp -+ - - 375dp - 64dp -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java -@@ -64,6 +64,7 @@ import org.chromium.chrome.browser.ui.edge_to_edge.EdgeToEdgeController; - import org.chromium.chrome.browser.ui.edge_to_edge.EdgeToEdgeControllerCreator; - import org.chromium.chrome.browser.ui.edge_to_edge.EdgeToEdgeFieldTrialImpl; - import org.chromium.chrome.browser.ui.edge_to_edge.EdgeToEdgeUtils; -+import org.chromium.chrome.browser.preferences.ChromeSharedPreferences; - import org.chromium.chrome.browser.ui.edge_to_edge.SimpleEdgeToEdgeController; - import org.chromium.components.browser_ui.styles.SemanticColorUtils; - import org.chromium.components.browser_ui.util.AutomotiveUtils; -@@ -145,6 +146,8 @@ public class ChromeBaseAppCompatActivity extends AppCompatActivity - protected void attachBaseContext(Context newBase) { - super.attachBaseContext(newBase); - -+ ChromeSharedPreferences.warmUp(); -+ - // Make sure the "chrome" split is loaded before checking if ClassLoaders are equal. - SplitChromeApplication.finishPreload(CHROME_SPLIT_NAME); - ClassLoader chromeModuleClassLoader = ChromeBaseAppCompatActivity.class.getClassLoader(); -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java b/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/WarmupManager.java -@@ -63,6 +63,7 @@ import org.chromium.chrome.browser.toolbar.ControlContainer; - import org.chromium.components.embedder_support.util.UrlConstants; - import org.chromium.content_public.browser.WebContents; - import org.chromium.ui.LayoutInflaterUtils; -+import org.chromium.ui.base.DeviceFormFactor; - import org.chromium.ui.base.WindowAndroid; - import org.chromium.ui.display.DisplayUtil; - import org.chromium.url.GURL; -@@ -472,7 +473,9 @@ public class WarmupManager { - ControlContainer controlContainer = mainView.findViewById(R.id.control_container); - - if (toolbarId != ActivityUtils.NO_RESOURCE_ID && controlContainer != null) { -- controlContainer.initWithToolbar(toolbarId); -+ controlContainer.initWithToolbar(toolbarId, -+ DeviceFormFactor.isForceTabletUI() -+ ? R.dimen.control_container_height_tabletui : 0); - } - return mainView; - } catch (InflateException e) { -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/accessibility/settings/ChromeAccessibilitySettingsDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/accessibility/settings/ChromeAccessibilitySettingsDelegate.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/accessibility/settings/ChromeAccessibilitySettingsDelegate.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/accessibility/settings/ChromeAccessibilitySettingsDelegate.java -@@ -65,6 +65,25 @@ public class ChromeAccessibilitySettingsDelegate implements AccessibilitySetting - } - } - -+ private static class ForceTabletUIDelegate implements BooleanPreferenceDelegate { -+ @Override -+ public boolean getValue() { -+ return ChromeSharedPreferences.getInstance().readBoolean( -+ ChromePreferenceKeys.FLAGS_FORCE_TABLET_UI_ENABLED, false); -+ } -+ -+ @Override -+ public void setValue(boolean value) { -+ ChromeSharedPreferences.getInstance().writeBoolean( -+ ChromePreferenceKeys.FLAGS_FORCE_TABLET_UI_ENABLED, value); -+ } -+ } -+ -+ @Override -+ public BooleanPreferenceDelegate getForceTabletUIDelegate() { -+ return new ForceTabletUIDelegate(); -+ } -+ - private final Profile mProfile; - - /** -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 -@@ -808,7 +808,9 @@ public abstract class ChromeActivity extends AsyncInitializationActivity - // Inflate the correct toolbar layout for the device. - int toolbarLayoutId = getToolbarLayoutId(); - if (toolbarLayoutId != ActivityUtils.NO_RESOURCE_ID && controlContainer != null) { -- controlContainer.initWithToolbar(toolbarLayoutId); -+ controlContainer.initWithToolbar(toolbarLayoutId, -+ DeviceFormFactor.isForceTabletUI() -+ ? R.dimen.control_container_height_tabletui : 0); - } - onInitialLayoutInflationComplete(); - } -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java -@@ -132,6 +132,7 @@ import org.chromium.components.tab_group_sync.TabGroupSyncService; - import org.chromium.components.tab_group_sync.TriggerSource; - import org.chromium.components.tab_groups.TabGroupColorId; - import org.chromium.ui.accessibility.AccessibilityState; -+import org.chromium.ui.base.DeviceFormFactor; - import org.chromium.ui.base.LocalizationUtils; - import org.chromium.ui.base.WindowAndroid; - import org.chromium.ui.util.ColorUtils; -@@ -5039,8 +5040,13 @@ public class StripLayoutHelper - mCloseButtonMenu.setAnchorView(tabView); - // 3. Set the vertical offset to align the close button menu with bottom of the tab strip - int tabHeight = mManagerHost.getHeight(); -- int verticalOffset = -- -(tabHeight - (int) mContext.getResources().getDimension(R.dimen.tab_strip_height)); -+ int tab_strip_height = -+ (int) mContext.getResources().getDimension(R.dimen.tab_strip_height_cromite); -+ if (DeviceFormFactor.isForceTabletUI()) { -+ tab_strip_height = -+ (int) mContext.getResources().getDimension(R.dimen.tab_strip_height_tabletui); -+ } -+ int verticalOffset = -(tabHeight - tab_strip_height); - mCloseButtonMenu.setVerticalOffset(verticalOffset); - - // 4. Set the horizontal offset to align the close button menu with the right side of the -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperManager.java -@@ -105,6 +105,7 @@ import org.chromium.components.browser_ui.desktop_windowing.DesktopWindowStateMa - import org.chromium.components.browser_ui.styles.SemanticColorUtils; - import org.chromium.components.browser_ui.widget.scrim.ScrimProperties; - import org.chromium.content_public.browser.LoadUrlParams; -+import org.chromium.ui.base.DeviceFormFactor; - import org.chromium.ui.base.LocalizationUtils; - import org.chromium.ui.base.PageTransition; - import org.chromium.ui.base.WindowAndroid; -@@ -498,7 +499,10 @@ public class StripLayoutHelperManager - mIsLayoutOptimizationsEnabled = - ToolbarFeatures.isTabStripWindowLayoutOptimizationEnabled( - /* isTablet= */ true, DisplayUtil.isContextInDefaultDisplay(mContext)); -- mScrollableStripHeight = res.getDimension(R.dimen.tab_strip_height) / mDensity; -+ mScrollableStripHeight = -+ (DeviceFormFactor.isForceTabletUI() -+ ? res.getDimension(R.dimen.tab_strip_height_tabletui) -+ : res.getDimension(R.dimen.tab_strip_height_cromite)) / mDensity; - mHeight = - mIsLayoutOptimizationsEnabled - ? toolbarManager.getTabStripHeightSupplier().get() / mDensity -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java -@@ -120,6 +120,14 @@ public class TabStripSceneLayer extends SceneOverlayLayer { - if (mNativePtr == 0) return; - final boolean visible = yOffset > -layoutHelper.getHeight(); - -+ if (DeviceFormFactor.isNonMultiDisplayContextOnTablet(ContextUtils.getApplicationContext())) { -+ TintedCompositorButton newTabButton = layoutHelper.getNewTabButton(); -+ if (newTabButton.isVisible()) { -+ rightPaddingDp += newTabButton.getWidth() + layoutHelper.getNewTabBtnVisualOffset() -+ + StripLayoutGroupTitle.REORDER_BACKGROUND_PADDING_END; -+ } -+ } -+ - // This will hide the tab strips if necessary. - TabStripSceneLayerJni.get() - .beginBuildingFrame(mNativePtr, visible, resourceManager, layerTitleCache); -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java -@@ -18,6 +18,7 @@ import org.chromium.base.task.TaskTraits; - import org.chromium.build.annotations.NullMarked; - import org.chromium.build.annotations.Nullable; - import org.chromium.chrome.browser.flags.ChromeSwitches; -+import org.chromium.chrome.browser.preferences.ChromeSharedPreferences; - import org.chromium.chrome.browser.profiles.ProfileManager; - import org.chromium.chrome.browser.signin.SigninCheckerProvider; - import org.chromium.components.background_task_scheduler.BackgroundTaskSchedulerFactory; -@@ -110,6 +111,7 @@ public class ChromeBrowserInitializer { - public void handlePreNativeStartupAndLoadLibraries(final BrowserParts parts) { - ThreadUtils.checkUiThread(); - if (parts.isActivityFinishingOrDestroyed()) return; -+ ChromeSharedPreferences.warmUp(); - ProcessInitializationHandler.getInstance().initializePreNative(); - ProcessInitializationHandler.getInstance().initializePreNativeLibraryLoad(); - try (TraceEvent e = TraceEvent.scoped("ChromeBrowserInitializer.preInflationStartup")) { -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 -@@ -768,7 +768,9 @@ public class TabbedRootUiCoordinator extends RootUiCoordinator { - - @Override - public int getControlContainerHeightResource() { -- return R.dimen.control_container_height; -+ if (DeviceFormFactor.isForceTabletUI()) -+ return R.dimen.control_container_height_tabletui; -+ return R.dimen.control_container_height_cromite; - } - - @Override -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 -@@ -110,6 +110,8 @@ import org.chromium.chrome.browser.paint_preview.DemoPaintPreview; - import org.chromium.chrome.browser.password_manager.ManagePasswordsReferrer; - import org.chromium.chrome.browser.password_manager.PasswordManagerLauncher; - import org.chromium.chrome.browser.pdf.PdfPage; -+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; -+import org.chromium.chrome.browser.preferences.ChromeSharedPreferences; - import org.chromium.chrome.browser.profiles.Profile; - import org.chromium.chrome.browser.quick_delete.QuickDeleteController; - import org.chromium.chrome.browser.quick_delete.QuickDeleteDelegateImpl; -@@ -1803,7 +1805,9 @@ public class RootUiCoordinator - if (!mSupportsFindInPageSupplier.getAsBoolean()) return; - - int stubId = R.id.find_toolbar_stub; -- if (DeviceFormFactor.isNonMultiDisplayContextOnTablet(mActivity)) { -+ if (DeviceFormFactor.isNonMultiDisplayContextOnTablet(mActivity) && -+ !ChromeSharedPreferences.getInstance().readBoolean( -+ ChromePreferenceKeys.FLAGS_FORCE_TABLET_UI_ENABLED, false)) { - stubId = R.id.find_toolbar_tablet_stub; - } - mFindToolbarManager = -diff --git a/chrome/browser/preferences/BUILD.gn b/chrome/browser/preferences/BUILD.gn ---- a/chrome/browser/preferences/BUILD.gn -+++ b/chrome/browser/preferences/BUILD.gn -@@ -25,6 +25,7 @@ android_library("java") { - "//components/cached_flags:java", - "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/jni_zero:jni_zero_java", -+ "//ui/android:ui_java", - ] - - srcjar_deps = [ -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 -@@ -337,6 +337,7 @@ public final class ChromePreferenceKeys { - /** Whether the app-specific history info text was already seen by users. */ - public static final String HISTORY_APP_SPECIFIC_INFO_SEEN = - "Chrome.History.AppSpecificInfoSeen"; -+ public static final String FLAGS_FORCE_TABLET_UI_ENABLED = "force_tablet_ui_enabled"; - - /** Keys used to save settings related to homepage. */ - public static final String DEPRECATED_HOMEPAGE_CUSTOM_URI = "homepage_custom_uri"; -diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromeSharedPreferences.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromeSharedPreferences.java ---- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromeSharedPreferences.java -+++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromeSharedPreferences.java -@@ -14,6 +14,8 @@ import org.chromium.build.annotations.NullMarked; - import org.chromium.build.annotations.Nullable; - import org.chromium.build.annotations.OptimizeAsNonNull; - -+import org.chromium.ui.base.DeviceFormFactor; -+ - @JNINamespace("android::shared_preferences") - @NullMarked - public class ChromeSharedPreferences { -@@ -26,6 +28,16 @@ public class ChromeSharedPreferences { - LegacyChromePreferenceKeys.getPrefixesInUse()) - : null); - -+ static { -+ DeviceFormFactor.setForceTabletUI( -+ ChromeSharedPreferences.getInstance().readBoolean( -+ ChromePreferenceKeys.FLAGS_FORCE_TABLET_UI_ENABLED, false)); -+ } -+ -+ public static void warmUp() { -+ // intentionally empty -+ } -+ - /** - * @return The //base SharedPreferencesManager singleton. - */ -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 -@@ -56,6 +56,7 @@ public class LegacyChromePreferenceKeys { - ChromePreferenceKeys.FIRST_RUN_FLOW_COMPLETE, - ChromePreferenceKeys.FIRST_RUN_FLOW_SIGNIN_SETUP, - ChromePreferenceKeys.FIRST_RUN_LIGHTWEIGHT_FLOW_COMPLETE, -+ ChromePreferenceKeys.FLAGS_FORCE_TABLET_UI_ENABLED, - ChromePreferenceKeys.FIRST_RUN_SKIP_WELCOME_PAGE, - ChromePreferenceKeys.HISTORY_SHOW_HISTORY_INFO, - ChromePreferenceKeys.HOMEPAGE_ENABLED, -diff --git a/chrome/browser/ui/android/desktop_windowing/java/src/org/chromium/chrome/browser/ui/desktop_windowing/AppHeaderCoordinator.java b/chrome/browser/ui/android/desktop_windowing/java/src/org/chromium/chrome/browser/ui/desktop_windowing/AppHeaderCoordinator.java ---- a/chrome/browser/ui/android/desktop_windowing/java/src/org/chromium/chrome/browser/ui/desktop_windowing/AppHeaderCoordinator.java -+++ b/chrome/browser/ui/android/desktop_windowing/java/src/org/chromium/chrome/browser/ui/desktop_windowing/AppHeaderCoordinator.java -@@ -42,6 +42,7 @@ import org.chromium.components.browser_ui.desktop_windowing.DesktopWindowStateMa - import org.chromium.ui.display.DisplayUtil; - import org.chromium.ui.edge_to_edge.EdgeToEdgeStateProvider; - import org.chromium.ui.insets.CaptionBarInsetsRectProvider; -+import org.chromium.ui.base.DeviceFormFactor; - import org.chromium.ui.insets.InsetObserver; - import org.chromium.ui.insets.InsetObserver.WindowInsetsConsumer; - import org.chromium.ui.insets.InsetsRectProvider; -@@ -281,6 +282,7 @@ public class AppHeaderCoordinator - InsetsRectProvider insetsRectProvider, - @DesktopWindowHeuristicResult int currentResult, - boolean isOnExternalDisplay) { -+ if (DeviceFormFactor.isForceTabletUI()) return DesktopWindowHeuristicResult.IN_DESKTOP_WINDOW; - @DesktopWindowHeuristicResult int newResult; - - Insets captionBarInset = insetsRectProvider.getCachedInset(); -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 -@@ -869,7 +869,7 @@ public class LocationBarCoordinator - } - - private boolean isTabletWindow() { -- return DeviceFormFactor.isWindowOnTablet(mWindowAndroid); -+ return DeviceFormFactor.isWindowOnTablet(mWindowAndroid) || isTabletLayout(); - } - - /* package */ LocationBarMediator getMediatorForTesting() { -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 -@@ -1489,6 +1489,13 @@ Your Google account may have other forms of browsing history like searches and a - Privacy guide explanation closed - - -+ -+ Open chromium in Tablet Mode -+ -+ -+ Force Tablet Mode -+ -+ - - - Safety check -diff --git a/chrome/browser/ui/android/toolbar/java/res/layout/control_container.xml b/chrome/browser/ui/android/toolbar/java/res/layout/control_container.xml ---- a/chrome/browser/ui/android/toolbar/java/res/layout/control_container.xml -+++ b/chrome/browser/ui/android/toolbar/java/res/layout/control_container.xml -@@ -9,7 +9,7 @@ found in the LICENSE file. - android:id="@+id/control_container" - android:layout_width="match_parent" - android:layout_height="wrap_content" -- android:minHeight="@dimen/control_container_height"> -+ android:minHeight="@dimen/control_container_height_cromite"> - - - -@@ -29,13 +29,13 @@ found in the LICENSE file. - android:layout_width="match_parent" - android:layout_height="wrap_content" - app:layout_anchorGravity="bottom" -- /> -+ android:layout_marginTop="@dimen/control_container_height_cromite" /> - - -diff --git a/chrome/browser/ui/android/toolbar/java/res/layout/toolbar_tablet.xml b/chrome/browser/ui/android/toolbar/java/res/layout/toolbar_tablet.xml ---- a/chrome/browser/ui/android/toolbar/java/res/layout/toolbar_tablet.xml -+++ b/chrome/browser/ui/android/toolbar/java/res/layout/toolbar_tablet.xml -@@ -15,7 +15,7 @@ found in the LICENSE file. - android:id="@+id/toolbar" - android:layout_width="match_parent" - android:layout_height="@dimen/toolbar_height_no_shadow" -- android:layout_marginTop="@dimen/tab_strip_height" -+ android:layout_marginTop="@dimen/tab_strip_height_tabletui" - android:background="@macro/default_bg_color" - > - -diff --git a/chrome/browser/ui/android/toolbar/java/res/values-sw600dp/dimens.xml b/chrome/browser/ui/android/toolbar/java/res/values-sw600dp/dimens.xml ---- a/chrome/browser/ui/android/toolbar/java/res/values-sw600dp/dimens.xml -+++ b/chrome/browser/ui/android/toolbar/java/res/values-sw600dp/dimens.xml -@@ -7,6 +7,7 @@ found in the LICENSE file. - - - -- 40dp -- 2dp -+ 40dp -+ 40dp -+ 2dp - -diff --git a/chrome/browser/ui/android/toolbar/java/res/values/dimens.xml b/chrome/browser/ui/android/toolbar/java/res/values/dimens.xml ---- a/chrome/browser/ui/android/toolbar/java/res/values/dimens.xml -+++ b/chrome/browser/ui/android/toolbar/java/res/values/dimens.xml -@@ -10,8 +10,10 @@ found in the LICENSE file. - 9dp - - -- 0dp -- 0dp -+ 0dp -+ 40dp -+ 0dp -+ 2dp - - 64dp - 72dp -diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ControlContainer.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ControlContainer.java ---- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ControlContainer.java -+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ControlContainer.java -@@ -26,7 +26,7 @@ public interface ControlContainer { - * - * @param toolbarLayoutId The ID of the toolbar layout to use. - */ -- void initWithToolbar(int toolbarLayoutId); -+ void initWithToolbar(int toolbarLayoutId, int controlContainerHeightOverrideId); - - /** - * @return The {@link ViewResourceAdapter} that exposes this {@link View} as a CC resource. -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 -@@ -7,6 +7,7 @@ package org.chromium.chrome.browser.toolbar.top; - import static org.chromium.build.NullUtil.assumeNonNull; - - import android.content.Context; -+import android.content.res.Resources; - import android.graphics.Canvas; - import android.graphics.Color; - import android.graphics.PorterDuff; -@@ -170,8 +171,25 @@ public class ToolbarControlContainer extends OptimizedFrameLayout - - @Override - @Initializer -- public void initWithToolbar(int toolbarLayoutId) { -+ public void initWithToolbar(int toolbarLayoutId, int controlContainerHeightOverrideId) { - try (TraceEvent te = TraceEvent.scoped("ToolbarControlContainer.initWithToolbar")) { -+ if (controlContainerHeightOverrideId != 0) { -+ Resources res = getContext().getResources(); -+ setMinimumHeight((int) res.getDimension(controlContainerHeightOverrideId)); -+ int tab_strip_height = -+ (int) res.getDimension(R.dimen.tab_strip_height_tabletui); -+ -+ View view = findViewById(R.id.toolbar_stub); -+ if (view != null) -+ ((MarginLayoutParams)view.getLayoutParams()).topMargin = tab_strip_height; -+ -+ view = findViewById(R.id.toolbar_hairline); -+ if (view != null) view.setVisibility(View.GONE); -+ -+ view = findViewById(R.id.find_toolbar_stub); -+ if (view != null) -+ ((MarginLayoutParams)view.getLayoutParams()).topMargin = tab_strip_height; -+ } - mToolbarContainer = findViewById(R.id.toolbar_container); - ViewStub toolbarStub = findViewById(R.id.toolbar_stub); - toolbarStub.setLayoutResource(toolbarLayoutId); -diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java ---- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java -+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java -@@ -64,6 +64,7 @@ import org.chromium.chrome.browser.util.BrowserUiUtils.ModuleTypeOnStartAndNtp; - import org.chromium.components.feature_engagement.Tracker; - import org.chromium.ui.base.ViewUtils; - import org.chromium.ui.util.MotionEventUtils; -+import org.chromium.ui.base.DeviceFormFactor; - import org.chromium.ui.util.TokenHolder; - import org.chromium.url.GURL; - -@@ -581,7 +582,9 @@ public abstract class ToolbarLayout extends FrameLayout - * not have a tab strip. - */ - protected int getTabStripHeightFromResource() { -- return getResources().getDimensionPixelSize(R.dimen.tab_strip_height); -+ if (DeviceFormFactor.isForceTabletUI()) -+ return getResources().getDimensionPixelSize(R.dimen.tab_strip_height_tabletui); -+ return getResources().getDimensionPixelSize(R.dimen.tab_strip_height_cromite); - } - - /** Triggered when the content view for the specified tab has changed. */ -diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/tab_strip/HeightTransitionHandler.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/tab_strip/HeightTransitionHandler.java ---- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/tab_strip/HeightTransitionHandler.java -+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/tab_strip/HeightTransitionHandler.java -@@ -30,6 +30,7 @@ import org.chromium.chrome.browser.toolbar.top.ToolbarLayout; - import org.chromium.chrome.browser.toolbar.top.tab_strip.TabStripTransitionCoordinator.TabStripHeightObserver; - import org.chromium.chrome.browser.toolbar.top.tab_strip.TabStripTransitionCoordinator.TabStripTransitionDelegate; - import org.chromium.ui.base.ViewUtils; -+import org.chromium.ui.base.DeviceFormFactor; - import org.chromium.ui.resources.dynamics.DynamicResourceReadyOnceCallback; - import org.chromium.ui.util.TokenHolder; - -@@ -562,6 +563,7 @@ class HeightTransitionHandler { - if (TabStripTransitionCoordinator.sHeightTransitionThresholdForTesting != null) { - return TabStripTransitionCoordinator.sHeightTransitionThresholdForTesting; - } -+ if (DeviceFormFactor.isForceTabletUI()) return 0; - return TRANSITION_THRESHOLD_DP; - } - -diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/tab_strip/TabStripTransitionCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/tab_strip/TabStripTransitionCoordinator.java ---- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/tab_strip/TabStripTransitionCoordinator.java -+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/tab_strip/TabStripTransitionCoordinator.java -@@ -29,6 +29,7 @@ import org.chromium.chrome.browser.ui.desktop_windowing.AppHeaderUtils; - import org.chromium.components.browser_ui.desktop_windowing.AppHeaderState; - import org.chromium.components.browser_ui.desktop_windowing.DesktopWindowStateManager; - import org.chromium.components.browser_ui.desktop_windowing.DesktopWindowStateManager.AppHeaderObserver; -+import org.chromium.ui.base.DeviceFormFactor; - - /** Class used to manage tab strip visibility and height updates. */ - @NullMarked -@@ -148,7 +149,10 @@ public class TabStripTransitionCoordinator implements ComponentCallbacks, AppHea - mTabStripReservedTopPadding = - controlContainerView() - .getResources() -- .getDimensionPixelSize(R.dimen.tab_strip_reserved_top_padding); -+ .getDimensionPixelSize( -+ DeviceFormFactor.isForceTabletUI() -+ ? R.dimen.tab_strip_reserved_top_padding_tabletui -+ : R.dimen.tab_strip_reserved_top_padding_cromite); - - mOnLayoutChangedListener = - (view, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { -diff --git a/components/browser_ui/accessibility/android/java/res/xml/accessibility_preferences.xml b/components/browser_ui/accessibility/android/java/res/xml/accessibility_preferences.xml ---- a/components/browser_ui/accessibility/android/java/res/xml/accessibility_preferences.xml -+++ b/components/browser_ui/accessibility/android/java/res/xml/accessibility_preferences.xml -@@ -36,6 +36,11 @@ found in the LICENSE file. - android:summary="@string/jump_start_omnibox_summary" - android:title="@string/jump_start_omnibox_title" /> - -+ -+ - -diff --git a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/AccessibilitySettings.java b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/AccessibilitySettings.java ---- a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/AccessibilitySettings.java -+++ b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/AccessibilitySettings.java -@@ -29,6 +29,7 @@ import org.chromium.content_public.browser.ContentFeatureList; - import org.chromium.content_public.browser.ContentFeatureMap; - - import org.chromium.chrome.browser.settings.ChromeBaseSettingsFragment; -+import org.chromium.components.browser_ui.accessibility.AccessibilitySettingsDelegate.BooleanPreferenceDelegate; - - /** Fragment to keep track of all the accessibility related preferences. */ - @NullMarked -@@ -44,6 +45,9 @@ public class AccessibilitySettings extends ChromeBaseSettingsFragment - public static final String PREF_ZOOM_INFO = "zoom_info"; - public static final String PREF_IMAGE_DESCRIPTIONS = "image_descriptions"; - -+ private BooleanPreferenceDelegate mForceTabletUIDelegate; -+ static final String PREF_FORCE_TABLET_UI = "force_tablet_ui"; -+ - private PageZoomPreference mPageZoomDefaultZoomPref; - private ChromeSwitchPreference mPageZoomIncludeOSAdjustment; - private ChromeSwitchPreference mPageZoomAlwaysShowPref; -@@ -117,6 +121,12 @@ public class AccessibilitySettings extends ChromeBaseSettingsFragment - mDelegate.getReaderAccessibilityDelegate().getValue()); - readerForAccessibilityPref.setOnPreferenceChangeListener(this); - -+ ChromeSwitchPreference forceTabletUiPref = -+ (ChromeSwitchPreference) findPreference(PREF_FORCE_TABLET_UI); -+ mForceTabletUIDelegate = mDelegate.getForceTabletUIDelegate(); -+ forceTabletUiPref.setChecked(mForceTabletUIDelegate.getValue()); -+ forceTabletUiPref.setOnPreferenceChangeListener(this); -+ - Preference captions = findPreference(PREF_CAPTIONS); - captions.setOnPreferenceClickListener( - preference -> { -@@ -176,6 +186,9 @@ public class AccessibilitySettings extends ChromeBaseSettingsFragment - public boolean onPreferenceChange(Preference preference, Object newValue) { - if (PREF_FORCE_ENABLE_ZOOM.equals(preference.getKey())) { - mDelegate.getForceEnableZoomAccessibilityDelegate().setValue((Boolean) newValue); -+ } else if (PREF_FORCE_TABLET_UI.equals(preference.getKey())) { -+ mForceTabletUIDelegate.setValue((Boolean) newValue); -+ mDelegate.requestRestart(getActivity()); - } else if (PREF_READER_FOR_ACCESSIBILITY.equals(preference.getKey())) { - boolean readerModeEnabled = (Boolean) newValue; - mDelegate.getReaderAccessibilityDelegate().setValue(readerModeEnabled); -diff --git a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/AccessibilitySettingsDelegate.java b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/AccessibilitySettingsDelegate.java ---- a/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/AccessibilitySettingsDelegate.java -+++ b/components/browser_ui/accessibility/android/java/src/org/chromium/components/browser_ui/accessibility/AccessibilitySettingsDelegate.java -@@ -41,6 +41,8 @@ public interface AccessibilitySettingsDelegate { - */ - BrowserContextHandle getBrowserContextHandle(); - -+ BooleanPreferenceDelegate getForceTabletUIDelegate(); -+ - /** - * @return boolean value specifying if the Image Descriptions user setting should be shown. - */ -diff --git a/ui/android/java/src/org/chromium/ui/base/DeviceFormFactor.java b/ui/android/java/src/org/chromium/ui/base/DeviceFormFactor.java ---- a/ui/android/java/src/org/chromium/ui/base/DeviceFormFactor.java -+++ b/ui/android/java/src/org/chromium/ui/base/DeviceFormFactor.java -@@ -79,6 +79,14 @@ public class DeviceFormFactor { - /** See {@link #setIsTabletForTesting(boolean)}. */ - private static @Nullable Boolean sIsTabletForTesting; - -+ private static boolean mForceTabletUI = false; -+ public static void setForceTabletUI(boolean forceTabletUI) { -+ mForceTabletUI = forceTabletUI; -+ } -+ public static boolean isForceTabletUI() { -+ return mForceTabletUI; -+ } -+ - /** - * Each activity could be on a different display, and this will just tell you whether the - * display associated with the application context is "tablet sized". Use {@link -@@ -87,6 +95,7 @@ public class DeviceFormFactor { - @CalledByNative - @Deprecated - public static boolean isTablet() { -+ if (mForceTabletUI) return true; - if (sIsTabletForTesting != null) { - return sIsTabletForTesting; - } -@@ -117,6 +126,7 @@ public class DeviceFormFactor { - * E.g. http://developer.samsung.com/samsung-dex/testing - */ - public static boolean isNonMultiDisplayContextOnTablet(Context context) { -+ if (mForceTabletUI) return true; - return detectScreenWidthBucket(context) >= SCREEN_BUCKET_TABLET; - } - -@@ -151,6 +161,7 @@ public class DeviceFormFactor { - * @return The screen width bucket the device is in (see constants at the top of this class). - */ - private static int detectScreenWidthBucket(Context context) { -+ if (mForceTabletUI) return SCREEN_BUCKET_TABLET; - return context.getResources().getInteger(R.integer.min_screen_width_bucket); - } - -@@ -158,6 +169,7 @@ public class DeviceFormFactor { - ThreadUtils.assertOnUiThread(); - Context context = windowAndroid.getContext().get(); - if (context == null) return 0; -+ if (mForceTabletUI) return SCREEN_BUCKET_TABLET; - return context.getResources().getInteger(R.integer.min_screen_width_bucket); - } - -@@ -167,6 +179,7 @@ public class DeviceFormFactor { - */ - @UiThread - public static int getNonMultiDisplayMinimumTabletWidthPx(Context context) { -+ if (mForceTabletUI) return 0; - return getMinimumTabletWidthPx(DisplayAndroid.getNonMultiDisplay(context)); - } - -@@ -175,6 +188,7 @@ public class DeviceFormFactor { - * layout. - */ - public static int getMinimumTabletWidthPx(DisplayAndroid display) { -+ if (mForceTabletUI) return 0; - return DisplayUtil.dpToPx(display, DeviceFormFactor.MINIMUM_TABLET_WIDTH_DP); - } - } --- diff --git a/build/cromite_patches/Add-option-to-not-persist-tabs-across-sessions.patch b/build/cromite_patches/Add-option-to-not-persist-tabs-across-sessions.patch deleted file mode 100644 index cf0e4938..00000000 --- a/build/cromite_patches/Add-option-to-not-persist-tabs-across-sessions.patch +++ /dev/null @@ -1,120 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Sat, 7 Sep 2019 15:07:42 +0200 -Subject: Add option to not persist tabs across sessions - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../android/java/res/xml/privacy_preferences.xml | 5 +++++ - .../chrome/browser/ChromeTabbedActivity.java | 5 ++++- - .../browser/privacy/settings/PrivacySettings.java | 15 ++++++++++++++- - .../ui/android/strings/android_chrome_strings.grd | 6 ++++++ - 4 files changed, 29 insertions(+), 2 deletions(-) - -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 -@@ -95,6 +95,11 @@ found in the LICENSE file. - android:title="@string/incognito_settings_title" - android:summary="@string/incognito_settings_summary" - android:fragment="org.chromium.chrome.browser.privacy.settings.IncognitoSettings"/> -+ - -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 -@@ -47,6 +47,7 @@ import org.chromium.base.Callback; - import org.chromium.base.CallbackController; - import org.chromium.base.CallbackUtils; - import org.chromium.base.CommandLine; -+import org.chromium.base.ContextUtils; - import org.chromium.base.IntentUtils; - import org.chromium.base.Log; - import org.chromium.base.MemoryPressureListener; -@@ -2218,8 +2219,10 @@ public class ChromeTabbedActivity extends ChromeActivity { - boolean hadCipherData = - CipherLazyHolder.sCipherInstance.restoreFromBundle(getSavedInstanceState()); - -+ String PREF_CLOSE_TABS_ON_EXIT = "close_tabs_on_exit"; - boolean noRestoreState = -- CommandLine.getInstance().hasSwitch(ChromeSwitches.NO_RESTORE_STATE); -+ CommandLine.getInstance().hasSwitch(ChromeSwitches.NO_RESTORE_STATE) || -+ ContextUtils.getAppSharedPreferences().getBoolean(PREF_CLOSE_TABS_ON_EXIT, false); - boolean shouldShowNtpAsHomeSurfaceAtStartup = false; - final AtomicBoolean isActiveUrlNtp = new AtomicBoolean(false); - if (noRestoreState) { -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 -@@ -9,6 +9,7 @@ import static org.chromium.components.content_settings.PrefNames.COOKIE_CONTROLS - - import android.content.Context; - import android.content.Intent; -+import android.content.SharedPreferences; - import android.graphics.drawable.Drawable; - import android.os.Bundle; - import android.text.SpannableString; -@@ -22,6 +23,7 @@ import androidx.annotation.VisibleForTesting; - import androidx.preference.Preference; - - import org.chromium.base.Callback; -+import org.chromium.base.ContextUtils; - import org.chromium.base.IntentUtils; - import org.chromium.base.metrics.RecordHistogram; - import org.chromium.base.metrics.RecordUserAction; -@@ -114,6 +116,8 @@ public class PrivacySettings extends ChromeBaseSettingsFragment - private final SharedPreferencesManager mSharedPreferencesManager = - ChromeSharedPreferences.getInstance(); - -+ private static final String PREF_CLOSE_TABS_ON_EXIT = "close_tabs_on_exit"; -+ - private ManagedPreferenceDelegate mManagedPreferenceDelegate; - @VisibleForTesting static final String PREF_THIRD_PARTY_COOKIES = "third_party_cookies"; - @VisibleForTesting static final String PREF_TRACKING_PROTECTION = "tracking_protection"; -@@ -382,7 +386,11 @@ public class PrivacySettings extends ChromeBaseSettingsFragment - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - String key = preference.getKey(); -- if (PREF_CAN_MAKE_PAYMENT.equals(key)) { -+ if (PREF_CLOSE_TABS_ON_EXIT.equals(key)) { -+ SharedPreferences.Editor sharedPreferencesEditor = ContextUtils.getAppSharedPreferences().edit(); -+ sharedPreferencesEditor.putBoolean(PREF_CLOSE_TABS_ON_EXIT, (boolean)newValue); -+ sharedPreferencesEditor.apply(); -+ } else if (PREF_CAN_MAKE_PAYMENT.equals(key)) { - UserPrefs.get(getProfile()) - .setBoolean(Pref.CAN_MAKE_PAYMENT_ENABLED, (boolean) newValue); - } else if (PREF_HTTPS_FIRST_MODE_LEGACY.equals(key)) { -@@ -442,6 +450,11 @@ public class PrivacySettings extends ChromeBaseSettingsFragment - getContext(), getProfile())); - } - -+ ChromeSwitchPreference closeTabsOnExitPref = -+ (ChromeSwitchPreference) findPreference(PREF_CLOSE_TABS_ON_EXIT); -+ closeTabsOnExitPref.setOnPreferenceChangeListener(this); -+ closeTabsOnExitPref.setManagedPreferenceDelegate(mManagedPreferenceDelegate); -+ - Preference secureDnsPref = findPreference(PREF_SECURE_DNS); - if (secureDnsPref != null && secureDnsPref.isVisible()) { - secureDnsPref.setSummary(SecureDnsSettings.getSummary(getContext())); -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 -@@ -2856,6 +2856,12 @@ To change this setting, BEGIN_LINKdelete the Chrome d - - All tabs - -+ -+ Close all open tabs on exit -+ -+ -+ Don't persist tabs between browsing sessions. Caution: parameters in urls allow linking between different sessions. -+ - - Loading… - --- diff --git a/build/cromite_patches/Add-option-to-use-home-page-as-NTP.patch b/build/cromite_patches/Add-option-to-use-home-page-as-NTP.patch deleted file mode 100644 index ac639836..00000000 --- a/build/cromite_patches/Add-option-to-use-home-page-as-NTP.patch +++ /dev/null @@ -1,294 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Sat, 20 Nov 2021 15:36:54 +0000 -Subject: Add option to use home page as NTP - -And allow use about:blank as default homepage - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../tab_management/TabGridDialogMediator.java | 12 +++++++++++- - .../tasks/tab_management/TabGroupUiMediator.java | 8 +++++++- - .../java/res/xml/homepage_preferences.xml | 5 +++++ - .../strip/TabGroupContextMenuCoordinator.java | 11 ++++++++++- - .../chrome/browser/homepage/HomepageManager.java | 16 ++++++++++++++++ - .../homepage/settings/HomepageSettings.java | 12 ++++++++++++ - .../chrome/browser/metrics/LaunchMetrics.java | 1 - - .../browser/tabmodel/ChromeTabCreator.java | 8 ++++++++ - .../preferences/ChromePreferenceKeys.java | 1 + - .../preferences/LegacyChromePreferenceKeys.java | 1 + - .../android/strings/android_chrome_strings.grd | 3 +++ - chrome/browser/ui/browser_ui_prefs.cc | 2 ++ - chrome/common/pref_names.h | 4 ++++ - 13 files changed, 80 insertions(+), 4 deletions(-) - -diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java ---- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java -+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java -@@ -100,6 +100,7 @@ import org.chromium.components.collaboration.messaging.PersistentNotificationTyp - import org.chromium.components.data_sharing.DataSharingService; - import org.chromium.components.data_sharing.GroupMember; - import org.chromium.components.data_sharing.member_role.MemberRole; -+import org.chromium.components.embedder_support.util.UrlConstants; - import org.chromium.components.tab_group_sync.EitherId.EitherGroupId; - import org.chromium.components.tab_group_sync.LocalTabGroupId; - import org.chromium.components.tab_group_sync.TabGroupSyncService; -@@ -120,6 +121,9 @@ import java.util.Objects; - import java.util.Set; - import java.util.function.Supplier; - -+import org.chromium.chrome.browser.homepage.HomepageManager; -+import org.chromium.url.GURL; -+ - /** - * A mediator for the TabGridDialog component, responsible for communicating with the components' - * coordinator as well as managing the business logic for dialog show/hide. -@@ -1033,9 +1037,15 @@ public class TabGridDialogMediator - UrlConstantResolver urlConstantResolver = - UrlConstantResolverFactory.getForProfile(profile); - -+ String url = urlConstantResolver.getNtpUrl(); -+ if (UrlConstants.NTP_URL.equals(url) -+ && HomepageManager.getInstance().getPrefNTPIsHomepageEnabled()) { -+ GURL gurl = HomepageManager.getInstance().getHomepageGurl(); -+ url = gurl != null ? gurl.getSpec() : url; -+ } - TabGroupUtils.openUrlInGroup( - assumeNonNull(mCurrentTabGroupModelFilterSupplier.get()), -- urlConstantResolver.getNtpUrl(), -+ url, - tabsInGroup.get(tabsInGroup.size() - 1).getId(), - TabLaunchType.FROM_TAB_GROUP_UI); - RecordUserAction.record("MobileNewTabOpened." + mComponentName); -diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java ---- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java -+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGroupUiMediator.java -@@ -35,6 +35,7 @@ import org.chromium.chrome.browser.data_sharing.DataSharingServiceFactory; - import org.chromium.chrome.browser.data_sharing.ui.shared_image_tiles.SharedImageTilesConfig; - import org.chromium.chrome.browser.data_sharing.ui.shared_image_tiles.SharedImageTilesCoordinator; - import org.chromium.chrome.browser.layouts.LayoutStateProvider; -+import org.chromium.chrome.browser.homepage.HomepageManager; - import org.chromium.chrome.browser.layouts.LayoutStateProvider.LayoutStateObserver; - import org.chromium.chrome.browser.layouts.LayoutType; - import org.chromium.chrome.browser.profiles.Profile; -@@ -425,10 +426,15 @@ public class TabGroupUiMediator implements BackPressHandler { - UrlConstantResolverFactory.getForProfile(currentTabProfile); - - Tab parentTabToAttach = relatedTabs.get(relatedTabs.size() - 1); -+ String url = urlConstantResolver.getNtpUrl(); -+ if (HomepageManager.getInstance().getPrefNTPIsHomepageEnabled()) { -+ GURL gurl = HomepageManager.getInstance().getHomepageGurl(); -+ url = gurl != null ? gurl.getSpec() : url; -+ } - mTabCreatorManager - .getTabCreator(currentTab.isIncognito()) - .createNewTab( -- new LoadUrlParams(urlConstantResolver.getNtpUrl()), -+ new LoadUrlParams(url), - TabLaunchType.FROM_TAB_GROUP_UI, - parentTabToAttach); - RecordUserAction.record( -diff --git a/chrome/android/java/res/xml/homepage_preferences.xml b/chrome/android/java/res/xml/homepage_preferences.xml ---- a/chrome/android/java/res/xml/homepage_preferences.xml -+++ b/chrome/android/java/res/xml/homepage_preferences.xml -@@ -14,6 +14,11 @@ found in the LICENSE file. - android:summaryOn="@string/text_on" - android:summaryOff="@string/text_off" /> - -+ -+ - mPageTitle = new ObservableSupplierImpl<>(); -@@ -102,6 +105,15 @@ public class HomepageSettings extends ChromeBaseSettingsFragment { - mRadioButtons.setOnHomepagePreferenceChangeListener(this::onRadioButtonGroupChanged); - mRadioButtons.setupPreferenceValues(createPreferenceValuesForRadioGroup()); - -+ ChromeSwitchPreference mNTPIsHomepageSwitch = -+ (ChromeSwitchPreference) findPreference(PREF_NTP_HOMEPAGE_SWITCH); -+ boolean isHomepageNTPEnabled = mHomepageManager.getPrefNTPIsHomepageEnabled(); -+ mNTPIsHomepageSwitch.setChecked(isHomepageNTPEnabled); -+ mNTPIsHomepageSwitch.setOnPreferenceChangeListener((preference, newValue) -> { -+ mHomepageManager.setPrefNTPIsHomepageEnabled((boolean) newValue); -+ return true; -+ }); -+ - RecordUserAction.record("Settings.Homepage.Opened"); - } - -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/LaunchMetrics.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/LaunchMetrics.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/LaunchMetrics.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/LaunchMetrics.java -@@ -117,7 +117,6 @@ public class LaunchMetrics { - public static void recordHomePageLaunchMetrics( - boolean showHomeButton, boolean homepageIsNtp, GURL homepageGurl) { - if (homepageGurl.isEmpty()) { -- assert !showHomeButton : "Homepage should be disabled for an empty GURL"; - } - LaunchMetricsJni.get() - .recordHomePageLaunchMetrics(showHomeButton, homepageIsNtp, homepageGurl); -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/ChromeTabCreator.java -@@ -27,6 +27,7 @@ import org.chromium.chrome.browser.app.tab_activity_glue.ReparentingTask; - import org.chromium.chrome.browser.compositor.CompositorViewHolder; - import org.chromium.chrome.browser.flags.ChromeFeatureList; - import org.chromium.chrome.browser.multiwindow.MultiInstanceManager; -+import org.chromium.chrome.browser.homepage.HomepageManager; - import org.chromium.chrome.browser.prefetch.settings.PreloadPagesSettingsBridge; - import org.chromium.chrome.browser.prefetch.settings.PreloadPagesState; - import org.chromium.chrome.browser.profiles.Profile; -@@ -572,6 +573,13 @@ public class ChromeTabCreator extends TabCreator - */ - public @Nullable Tab launchUrl( - String url, @TabLaunchType int type, @Nullable Intent intent, long intentTimestamp) { -+ if (!mIncognito && url.equals(UrlConstants.NTP_URL)) { -+ if (HomepageManager.getInstance().getPrefNTPIsHomepageEnabled()) { -+ GURL gurl = HomepageManager.getInstance().getHomepageGurl(); -+ url = gurl != null ? gurl.getSpec() : url; -+ } -+ } -+ - LoadUrlParams loadUrlParams = new LoadUrlParams(url); - loadUrlParams.setIntentReceivedTimestamp(intentTimestamp); - return createNewTab(loadUrlParams, type, null, intent); -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 -@@ -350,6 +350,7 @@ public final class ChromePreferenceKeys { - public static final String HOMEPAGE_USE_CHROME_NTP = "Chrome.Homepage.UseNTP"; - public static final String HOMEPAGE_USE_DEFAULT_URI = "homepage_partner_enabled"; - -+ public static final String HOMEPAGE_NTP_IS_HOMEPAGE = "newtabpage_is_homepage"; - /** Key used to save homepage location set by enterprise policy */ - public static final String DEPRECATED_HOMEPAGE_LOCATION_POLICY = - "Chrome.Policy.HomepageLocation"; -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 -@@ -60,6 +60,7 @@ public class LegacyChromePreferenceKeys { - ChromePreferenceKeys.HISTORY_SHOW_HISTORY_INFO, - ChromePreferenceKeys.HOMEPAGE_ENABLED, - ChromePreferenceKeys.HOMEPAGE_USE_DEFAULT_URI, -+ ChromePreferenceKeys.HOMEPAGE_NTP_IS_HOMEPAGE, - ChromePreferenceKeys.INCOGNITO_SHORTCUT_ADDED, - ChromePreferenceKeys.LATEST_UNSUPPORTED_VERSION, - ChromePreferenceKeys.LOCALE_MANAGER_AUTO_SWITCH, -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 -@@ -1330,6 +1330,9 @@ Your Google account may have other forms of browsing history like searches and a - - Last hour - -+ -+ Use for new tabs -+ - - Last 24 hours - -diff --git a/chrome/browser/ui/browser_ui_prefs.cc b/chrome/browser/ui/browser_ui_prefs.cc ---- a/chrome/browser/ui/browser_ui_prefs.cc -+++ b/chrome/browser/ui/browser_ui_prefs.cc -@@ -119,6 +119,8 @@ void RegisterBrowserUserPrefs(user_prefs::PrefRegistrySyncable* registry) { - - registry->RegisterBooleanPref(prefs::kPinSplitTabButton, false, - pref_registration_flags); -+ registry->RegisterBooleanPref(prefs::kNewTabPageIsHomePage, false, -+ PrefRegistry::NO_REGISTRATION_FLAGS); - - registry->RegisterInt64Pref(prefs::kDefaultBrowserLastDeclined, 0); - registry->RegisterBooleanPref(prefs::kWebAppCreateOnDesktop, true); -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 -@@ -1336,6 +1336,10 @@ inline constexpr char kSplitViewDragAndDropNudgeUsedCount[] = - // by enterprise policy. - inline constexpr char kGeminiSettings[] = "browser.gemini_settings"; - -+// A boolean specifying whether opening a new tab should open the Home page -+// instead of the New Tab page. -+inline constexpr char kNewTabPageIsHomePage[] = "newtabpage_is_homepage"; -+ - // Comma separated list of domain names (e.g. "google.com,school.edu"). - // When this pref is set, the user will be able to access Google Apps - // only using an account that belongs to one of the domains from this pref. --- diff --git a/build/cromite_patches/Add-search-engine.patch b/build/cromite_patches/Add-search-engine.patch deleted file mode 100644 index 5e22cc15..00000000 --- a/build/cromite_patches/Add-search-engine.patch +++ /dev/null @@ -1,418 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Mon, 11 Dec 2017 22:42:11 +0100 -Subject: Add search engine - -Add a Google search engine that forces languages to English, -disable from all its searches RLZ and field experiments querystring parameters. -Add DuckDuckGo Lite - -License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html ---- - .../search_engine_choice/default_favicon.png | Bin 0 -> 903 bytes - components/search_engines/BUILD.gn | 3 ++ - components/search_engines/cromite/BUILD.gn | 12 ++++++ - .../cromite/cromite_prepopulated_engines.json | 37 ++++++++++++++++++ - .../search_engine_choice_utils.cc | 5 +-- - .../search_engines/search_engine_type.h | 5 +++ - .../template_url_prepopulate_data.cc | 21 +++++++++- - .../template_url_prepopulate_data.h | 9 ----- - tools/json_to_struct/json_to_struct.gni | 9 +++++ - tools/json_to_struct/json_to_struct.py | 26 ++++++++---- - tools/json_to_struct/struct_generator.py | 10 +++-- - tools/variations/fieldtrial_to_struct.py | 4 +- - 12 files changed, 113 insertions(+), 28 deletions(-) - create mode 100644 components/resources/default_100_percent/search_engine_choice/default_favicon.png - create mode 100644 components/search_engines/cromite/BUILD.gn - create mode 100644 components/search_engines/cromite/cromite_prepopulated_engines.json - -diff --git a/components/resources/default_100_percent/search_engine_choice/default_favicon.png b/components/resources/default_100_percent/search_engine_choice/default_favicon.png -new file mode 100644 -index 0000000000000000000000000000000000000000..6533419f2d6b40f7735054dec62c51ddf1ee1201 -GIT binary patch -literal 903 -zcmV;219<$2P)u5dJaD%uTpU6K1Ny)MmAo?2~ki?Li;rI(@haGcz+YGo$8ZtH|rstmUBf-W*z< -z`LqMyjQ;vbR=naxn4FxTa$SOo%Y^Yq3CiCp`IM5k@HhA$JOj`EJVrBqK*>90G)Ly==Qj#^Pm*zg`6NIm=nm~RX-}Ss_k_usva+)JncnmH^XI=4jNih$ -zlz0y|WF4^Se4bG8m@v`L_#mWg6DB6I3T(&-XFfHecpOCzcg -zpNwb+@DsmO2`6iI0DN;)MGkB;0q{--kR#0r9={VIfOiJ&qgPlcQV0O=qNN%EZUkK2 -zXVWfZ`h5{40I)Gg`DG2UD`5mlRG3V0I)IO -z^!VFvHvp@&1;F!4TUc56LN -z%3gt$n(-Z(idK@zIi#qli66~IxloAGzuNPP+NSLfTs{_pT7f^J06kI9KUZ>A$&#d( -z+ZUd3gy@cNAuWhQ3vePzWtVK-4H5_iqgo-eCg3jF08o2( -zV+xr@B`n6nQmpYnUx3CSsDwu5Yyvoe1poxnZ<>do)Aj_?EW-9wQ^cQO=(N_*SpEcF -zA!n{N_=ZMrDQ)uj`{u@re$c++TFQW?-c&%TJej=5G2dk -zc*-y0$13Q-mVE%=HZZcm54P~5#qa<$Vkc|B{qUnjjUSTzPpE5qa;Lv>bM_w_-mwYy_S=Aoxnl--Y -d#;kFnu^?NN9uE_uZ002ovPDHLkV1m60sc!%P - -literal 0 -HcmV?d00001 - -diff --git a/components/search_engines/BUILD.gn b/components/search_engines/BUILD.gn ---- a/components/search_engines/BUILD.gn -+++ b/components/search_engines/BUILD.gn -@@ -72,6 +72,7 @@ static_library("search_engines") { - "//third_party/metrics_proto", - "//third_party/omnibox_proto", - "//third_party/search_engines_data:prepopulated_engines", -+ "cromite:cromite_prepopulated_engines", - ] - - deps = [ -@@ -164,6 +165,7 @@ source_set("search_engine_utils") { - ":search_engine_type", - "//components/google/core/common", - "//third_party/search_engines_data:prepopulated_engines", -+ "cromite:cromite_prepopulated_engines", - ] - - deps = [ "//url" ] -@@ -258,6 +260,7 @@ source_set("unit_tests") { - "//testing/gmock", - "//testing/gtest", - "//third_party/search_engines_data:prepopulated_engines", -+ "cromite:cromite_prepopulated_engines", - "//ui/base", - "//url", - ] -diff --git a/components/search_engines/cromite/BUILD.gn b/components/search_engines/cromite/BUILD.gn -new file mode 100644 ---- /dev/null -+++ b/components/search_engines/cromite/BUILD.gn -@@ -0,0 +1,12 @@ -+import("//tools/json_to_struct/json_to_struct.gni") -+ -+json_to_struct("cromite_prepopulated_engines") { -+ visibility = [ "//components/search_engines:*" ] -+ -+ source = "cromite_prepopulated_engines.json" -+ schema_file = "//third_party/search_engines_data/prepopulated_engines_schema.json" -+ namespace = "TemplateURLPrepopulateData" -+ excludetype = true -+ -+ deps = [ "//base" ] -+} -diff --git a/components/search_engines/cromite/cromite_prepopulated_engines.json b/components/search_engines/cromite/cromite_prepopulated_engines.json -new file mode 100644 ---- /dev/null -+++ b/components/search_engines/cromite/cromite_prepopulated_engines.json -@@ -0,0 +1,37 @@ -+{ -+ "additionals_includes": { -+ "third_party/search_engines_data/resources/definitions/prepopulated_engines.h": "" -+ }, -+ "elements": { -+ "duckduckgo_light": { -+ "name": "DuckDuckGo Light", -+ "keyword": "duckduckgo.com/lite", -+ "favicon_url": "https://duckduckgo.com/favicon.ico", -+ "search_url": "https://duckduckgo.com/lite/?q={searchTerms}", -+ "suggest_url": "https://duckduckgo.com/ac/?q={searchTerms}&type=list", -+ "type": "SEARCH_ENGINE_DUCKDUCKGOLIGHT", -+ "id": 12 -+ }, -+ -+ "googleen": { -+ "name": "Google in English", -+ "keyword": "googleen", -+ "favicon_url": "https://www.google.com/favicon.ico", -+ "search_url": "{google:baseURL}search?q={searchTerms}&ie={inputEncoding}&hl=en", -+ "suggest_url": "{google:baseSuggestURL}search?client={google:suggestClient}&q={searchTerms}&hl=en", -+ "image_url": "{google:baseURL}searchbyimage/upload?hl=en", -+ "new_tab_url": "{google:baseURL}_/chrome/newtab?hl=en&ie={inputEncoding}", -+ "contextual_search_url": "{google:baseURL}_/contextualsearch?{google:contextualSearchVersion}{google:contextualSearchContextData}&hl=en", -+ "image_url_post_params": "encoded_image={google:imageThumbnail},image_url={google:imageURL},sbisrc={google:imageSearchSource},original_width={google:imageOriginalWidth},original_height={google:imageOriginalHeight}", -+ "alternate_urls": [ -+ "{google:baseURL}?hl=en#q={searchTerms}", -+ "{google:baseURL}search?hl=en#q={searchTerms}", -+ "{google:baseURL}webhp?hl=en#q={searchTerms}", -+ "{google:baseURL}s?hl=en#q={searchTerms}", -+ "{google:baseURL}s?hl=en&q={searchTerms}" -+ ], -+ "type": "SEARCH_ENGINE_GOOGLE_EN", -+ "id": 13 -+ } -+ } -+} -diff --git a/components/search_engines/search_engine_choice/search_engine_choice_utils.cc b/components/search_engines/search_engine_choice/search_engine_choice_utils.cc ---- a/components/search_engines/search_engine_choice/search_engine_choice_utils.cc -+++ b/components/search_engines/search_engine_choice/search_engine_choice_utils.cc -@@ -172,10 +172,7 @@ void RecordChoiceScreenDefaultSearchProviderType( - } - - void RecordChoiceScreenSelectedIndex(int selected_engine_index) { -- base::UmaHistogramExactLinear( -- kSearchEngineChoiceScreenSelectedEngineIndexHistogram, -- selected_engine_index, -- TemplateURLPrepopulateData::kMaxEeaPrepopulatedEngines); -+ // do nothing in Cromite - } - - void RecordChoiceScreenPositionsCountryMismatch(bool has_mismatch) { -diff --git a/components/search_engines/search_engine_type.h b/components/search_engines/search_engine_type.h ---- a/components/search_engines/search_engine_type.h -+++ b/components/search_engines/search_engine_type.h -@@ -98,11 +98,16 @@ enum SearchEngineType { - SEARCH_ENGINE_FREESPOKE = 78, - SEARCH_ENGINE_KAGI = 79, - SEARCH_ENGINE_STARTER_PACK_AI_MODE = 80, -+ SEARCH_ENGINE_GOOGLE_EN = 81, -+ SEARCH_ENGINE_DUCKDUCKGOLIGHT = 82, - - SEARCH_ENGINE_MAX // Bounding value needed for UMA histogram macro. - }; - // LINT.ThenChange(//tools/metrics/histograms/enums.xml:OmniboxSearchEngineType) - -+static_assert(SEARCH_ENGINE_DUCKDUCKGOLIGHT == (SEARCH_ENGINE_MAX - 1), -+ "Please check this patch"); -+ - // Enum to record the type of search engine a user used in keyword mode. This - // should be kept aligned with the `OmniboxBuiltinEngineType` enum in enums.xml. - // Entries should not be renumbered and numeric values should never be reused. -diff --git a/components/search_engines/template_url_prepopulate_data.cc b/components/search_engines/template_url_prepopulate_data.cc ---- a/components/search_engines/template_url_prepopulate_data.cc -+++ b/components/search_engines/template_url_prepopulate_data.cc -@@ -28,6 +28,8 @@ - #include "components/search_engines/template_url_data_util.h" - #include "third_party/search_engines_data/resources/definitions/prepopulated_engines.h" - -+#include "components/search_engines/cromite/cromite_prepopulated_engines.h" -+ - namespace TemplateURLPrepopulateData { - - // Helpers -------------------------------------------------------------------- -@@ -122,7 +124,7 @@ int GetDataVersion(PrefService* prefs) { - kCurrentDataVersion; - } - --std::vector> GetPrepopulatedEngines( -+std::vector> GetPrepopulatedEnginesChromium( - PrefService& prefs, - std::vector - regional_prepopulated_engines) { -@@ -138,6 +140,17 @@ std::vector> GetPrepopulatedEngines( - &PrepopulatedEngineToTemplateURLData); - } - -+std::vector> GetPrepopulatedEngines( -+ PrefService& prefs, -+ std::vector -+ regional_prepopulated_engines) { -+ std::vector> t_urls = -+ GetPrepopulatedEnginesChromium(prefs, regional_prepopulated_engines); -+ t_urls.push_back(TemplateURLDataFromPrepopulatedEngine(googleen)); -+ t_urls.push_back(TemplateURLDataFromPrepopulatedEngine(duckduckgo_light)); -+ return t_urls; -+} -+ - std::unique_ptr GetPrepopulatedEngine( - PrefService& prefs, - std::vector -@@ -159,10 +172,14 @@ std::vector> GetLocalPrepopulatedEngines( - return std::vector>(); - } - -- return base::ToVector(regional_capabilities::GetPrepopulatedEngines( -+ std::vector> t_urls = -+ base::ToVector(regional_capabilities::GetPrepopulatedEngines( - country_id, prefs, - regional_capabilities::SearchEngineListType::kTopN), - &PrepopulatedEngineToTemplateURLData); -+ t_urls.push_back(TemplateURLDataFromPrepopulatedEngine(googleen)); -+ t_urls.push_back(TemplateURLDataFromPrepopulatedEngine(duckduckgo_light)); -+ return t_urls; - } - - #endif -diff --git a/components/search_engines/template_url_prepopulate_data.h b/components/search_engines/template_url_prepopulate_data.h ---- a/components/search_engines/template_url_prepopulate_data.h -+++ b/components/search_engines/template_url_prepopulate_data.h -@@ -27,15 +27,6 @@ struct PrepopulatedEngine; - - extern const int kMaxPrepopulatedEngineID; - --// The maximum number of prepopulated search engines that can be returned in --// any of the EEA countries by `GetPrepopulatedEngines()`. --// --// Note: If this is increased, please also increase the declared variant count --// for the `Search.ChoiceScreenShowedEngineAt.Index{Index}` histogram. --// TODO(crbug.com/408932087): Investigate moving it to the file that actually --// populates these, `//c/regional_capabilities/r*c*_util.cc`. --inline constexpr size_t kMaxEeaPrepopulatedEngines = 8; -- - // The maximum number of prepopulated search engines that can be returned in - // in the rest of the world by `GetPrepopulatedEngines()`. - // TODO(crbug.com/408932087): Investigate deduping it with the constant -diff --git a/tools/json_to_struct/json_to_struct.gni b/tools/json_to_struct/json_to_struct.gni ---- a/tools/json_to_struct/json_to_struct.gni -+++ b/tools/json_to_struct/json_to_struct.gni -@@ -39,6 +39,11 @@ template("json_to_struct") { - action_name = target_name + "_action" - source_set_name = target_name - -+ excludetype = false -+ if (defined(invoker.excludetype)) { -+ excludetype = invoker.excludetype -+ } -+ - action(action_name) { - visibility = [ ":$source_set_name" ] - script = "//build/gn_run_binary.py" -@@ -63,6 +68,10 @@ template("json_to_struct") { - "--namespace=" + invoker.namespace, - "--schema=" + rebase_path(invoker.schema_file, root_build_dir), - ] -+ -+ if (excludetype) { -+ args += [ "--excludetype=yes" ] -+ } - } - - source_set(source_set_name) { -diff --git a/tools/json_to_struct/json_to_struct.py b/tools/json_to_struct/json_to_struct.py ---- a/tools/json_to_struct/json_to_struct.py -+++ b/tools/json_to_struct/json_to_struct.py -@@ -103,7 +103,7 @@ def _GenerateHeaderGuard(h_filename): - return re.sub(u'^_*', '', result) + u'_' # Remove leading underscores. - - --def _GenerateH(basepath, fileroot, head, namespace, schema, description): -+def _GenerateH(basepath, fileroot, head, namespace, schema, description, excludetype): - """Generates the .h file containing the definition of the structure specified - by the schema. - -@@ -147,11 +147,15 @@ def _GenerateH(basepath, fileroot, head, namespace, schema, description): - f.write(u'#include "%s"\n' % header) - f.write(u'\n') - -+ for header in description.get(u'additionals_includes', []): -+ f.write(u'#include "%s"\n' % header) -+ f.write(u'\n') -+ - if namespace: - f.write(u'namespace %s {\n' % namespace) - f.write(u'\n') - -- f.write(struct_generator.GenerateStruct( -+ f.write(struct_generator.GenerateStruct(excludetype, - schema['type_name'], schema['schema'])) - f.write(u'\n') - -@@ -176,7 +180,7 @@ def _GenerateH(basepath, fileroot, head, namespace, schema, description): - f.write(u'#endif // %s\n' % header_guard) - - --def _GenerateCC(basepath, fileroot, head, namespace, schema, description): -+def _GenerateCC(basepath, fileroot, head, namespace, schema, description, excludetype): - """Generates the .cc file containing the static initializers for the - of the elements specified in the description. - -@@ -211,7 +215,7 @@ def _GenerateCC(basepath, fileroot, head, namespace, schema, description): - f.write(element_generator.GenerateElements(schema['type_name'], - schema['schema'], description)) - -- if not aggregation.export_items: -+ if excludetype == False and not aggregation.export_items: - f.write('\n} // anonymous namespace \n\n') - - aggregated = GenerateCCAggregation(schema['type_name'], aggregation) -@@ -298,7 +302,7 @@ def GenerateClass(basepath, - - - def GenerateStruct(basepath, output_root, namespace, schema, description, -- description_filename, schema_filename, year=None): -+ description_filename, schema_filename, excludetype, year): - """Generates a C++ struct from a JSON description. - - Args: -@@ -317,8 +321,8 @@ def GenerateStruct(basepath, output_root, namespace, schema, description, - """ - year = int(year) if year else datetime.now().year - head = HEAD % (year, schema_filename, description_filename) -- _GenerateH(basepath, output_root, head, namespace, schema, description) -- _GenerateCC(basepath, output_root, head, namespace, schema, description) -+ _GenerateH(basepath, output_root, head, namespace, schema, description, excludetype) -+ _GenerateCC(basepath, output_root, head, namespace, schema, description, excludetype) - - if __name__ == '__main__': - parser = optparse.OptionParser( -@@ -333,11 +337,17 @@ if __name__ == '__main__': - parser.add_option('-s', '--schema', help='path to the schema file, ' - 'mandatory.') - parser.add_option('-o', '--output', help='output filename, ') -+ parser.add_option('-x', '--excludetype', help='exclude type generator, ') - (opts, args) = parser.parse_args() - - if not opts.schema: - parser.error('You must specify a --schema.') - -+ if not opts.excludetype: -+ opts.excludetype = False -+ else: -+ opts.excludetype = True -+ - description_filename = os.path.normpath(args[0]) - root, ext = os.path.splitext(description_filename) - shortroot = opts.output if opts.output else os.path.split(root)[1] -@@ -354,4 +364,4 @@ if __name__ == '__main__': - schema = _Load(opts.schema) - description = _Load(description_filename) - GenerateStruct(basepath, output_root, opts.namespace, schema, description, -- description_filename, opts.schema) -+ description_filename, opts.schema, opts.excludetype, datetime.now().year) -diff --git a/tools/json_to_struct/struct_generator.py b/tools/json_to_struct/struct_generator.py ---- a/tools/json_to_struct/struct_generator.py -+++ b/tools/json_to_struct/struct_generator.py -@@ -30,20 +30,24 @@ def GenerateField(field_info): - else: - raise RuntimeError('Unknown field type "%s"' % type) - --def GenerateStruct(type_name, schema): -+def GenerateStruct(excludetype, type_name, schema): - """Generate a string defining a structure containing the fields specified in - the schema list. - """ - lines = [] -+ if excludetype: -+ lines.append('struct %s;' % type_name) -+ return '\n'.join(lines) + '\n' -+ - lines.append('struct %s {' % type_name) - for field_info in schema: - if field_info['type'] == 'struct': -- lines.insert(0, GenerateStruct(field_info['type_name'], -+ lines.insert(0, GenerateStruct(excludetype, field_info['type_name'], - field_info['fields'])) - elif (field_info['type'] == 'array' - and field_info['contents']['type'] == 'struct'): - contents = field_info['contents'] -- lines.insert(0, GenerateStruct(contents['type_name'], -+ lines.insert(0, GenerateStruct(excludetype, contents['type_name'], - contents['fields'])) - lines.append(' ' + GenerateField(field_info) + ';') - lines.append('};') -diff --git a/tools/variations/fieldtrial_to_struct.py b/tools/variations/fieldtrial_to_struct.py ---- a/tools/variations/fieldtrial_to_struct.py -+++ b/tools/variations/fieldtrial_to_struct.py -@@ -235,14 +235,14 @@ def main(arguments): - json_to_struct.GenerateStruct( - basepath, output_root, opts.namespace, schema, description, - os.path.split(description_filename)[1], os.path.split(opts.schema)[1], -- opts.year) -+ False, opts.year) - - # TODO(peilinwang) filter the schema by platform, form_factor, etc. - if opts.java: - json_to_struct.GenerateClass(basepath, output_root, opts.namespace, schema, - description, - os.path.split(description_filename)[1], -- os.path.split(opts.schema)[1], opts.year) -+ os.path.split(opts.schema)[1], False, opts.year) - - - if __name__ == '__main__': --- diff --git a/build/cromite_patches/Add-site-engagement-flag.patch b/build/cromite_patches/Add-site-engagement-flag.patch deleted file mode 100644 index e005b42c..00000000 --- a/build/cromite_patches/Add-site-engagement-flag.patch +++ /dev/null @@ -1,263 +0,0 @@ -From: uazo -Date: Mon, 2 May 2022 11:48:03 +0000 -Subject: Add site engagement flag - -Disabled by default. - -Original License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - chrome/browser/about_flags.cc | 1 + - .../engagement/important_sites_util.cc | 9 +++++ - .../browser/media/media_engagement_service.cc | 4 ++- - .../internal/tracker_impl.cc | 3 ++ - .../public/feature_configurations.cc | 7 ++++ - .../content/site_engagement_score.cc | 5 +++ - components/site_engagement/core/BUILD.gn | 6 ++++ - components/site_engagement/core/features.cc | 30 ++++++++++++++++ - components/site_engagement/core/features.h | 34 +++++++++++++++++++ - .../Add-site-engagement-flag.inc | 10 ++++++ - 10 files changed, 108 insertions(+), 1 deletion(-) - create mode 100644 components/site_engagement/core/features.cc - create mode 100644 components/site_engagement/core/features.h - create mode 100644 cromite_flags/chrome/browser/about_flags_cc/Add-site-engagement-flag.inc - -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 -@@ -171,6 +171,7 @@ - #include "components/sensitive_content/features.h" - #include "components/services/heap_profiling/public/cpp/switches.h" - #include "components/services/storage/public/cpp/buckets/bucket_info.h" -+#include "components/site_engagement/core/features.h" - #include "components/shared_highlighting/core/common/shared_highlighting_features.h" - #include "components/sharing_message/features.h" - #include "components/signin/core/browser/dice_account_reconcilor_delegate.h" -diff --git a/chrome/browser/engagement/important_sites_util.cc b/chrome/browser/engagement/important_sites_util.cc ---- a/chrome/browser/engagement/important_sites_util.cc -+++ b/chrome/browser/engagement/important_sites_util.cc -@@ -31,6 +31,7 @@ - #include "components/prefs/scoped_user_pref_update.h" - #include "components/site_engagement/content/site_engagement_score.h" - #include "components/site_engagement/content/site_engagement_service.h" -+#include "components/site_engagement/core/features.h" - #include "components/site_engagement/core/mojom/site_engagement_details.mojom.h" - #include "components/webapps/browser/banners/app_banner_settings_helper.h" - #include "net/base/registry_controlled_domains/registry_controlled_domain.h" -@@ -344,6 +345,10 @@ void ImportantSitesUtil::RegisterProfilePrefs( - // static - std::set ImportantSitesUtil::GetInstalledRegisterableDomains( - Profile* profile) { -+ if (!base::FeatureList::IsEnabled(site_engagement::features::kSiteEngagement)) { -+ std::set empty_list; -+ return empty_list; -+ } - std::set installed_origins = GetOriginsWithInstalledWebApps(profile); - std::set registerable_domains; - -@@ -358,6 +363,10 @@ std::vector - ImportantSitesUtil::GetImportantRegisterableDomains(Profile* profile, - size_t max_results) { - SCOPED_UMA_HISTOGRAM_TIMER("Storage.ImportantSites.GenerationTime"); -+ if (!base::FeatureList::IsEnabled(site_engagement::features::kSiteEngagement)) { -+ std::vector empty_list; -+ return empty_list; -+ } - std::map important_info; - std::map engagement_map; - -diff --git a/chrome/browser/media/media_engagement_service.cc b/chrome/browser/media/media_engagement_service.cc ---- a/chrome/browser/media/media_engagement_service.cc -+++ b/chrome/browser/media/media_engagement_service.cc -@@ -25,6 +25,7 @@ - #include "components/history/core/browser/history_service.h" - #include "components/no_state_prefetch/browser/no_state_prefetch_contents.h" - #include "components/prefs/pref_service.h" -+#include "components/site_engagement/core/features.h" - #include "content/public/browser/web_contents.h" - #include "media/base/media_switches.h" - #include "url/origin.h" -@@ -54,7 +55,8 @@ enum class MediaEngagementClearReason { - - // static - bool MediaEngagementService::IsEnabled() { -- return base::FeatureList::IsEnabled(media::kRecordMediaEngagementScores); -+ return base::FeatureList::IsEnabled(media::kRecordMediaEngagementScores) -+ && base::FeatureList::IsEnabled(site_engagement::features::kSiteEngagement); - } - - // static -diff --git a/components/feature_engagement/internal/tracker_impl.cc b/components/feature_engagement/internal/tracker_impl.cc ---- a/components/feature_engagement/internal/tracker_impl.cc -+++ b/components/feature_engagement/internal/tracker_impl.cc -@@ -23,6 +23,7 @@ - #include "base/task/single_thread_task_runner.h" - #include "base/time/clock.h" - #include "build/build_config.h" -+#include "components/site_engagement/core/features.h" - #include "components/feature_engagement/internal/availability_model_impl.h" - #include "components/feature_engagement/internal/blocked_iph_features.h" - #include "components/feature_engagement/internal/chrome_variations_configuration.h" -@@ -291,6 +292,8 @@ TrackerImpl::TrackerImpl( - TrackerImpl::~TrackerImpl() = default; - - void TrackerImpl::NotifyEvent(const std::string& event) { -+ if (!base::FeatureList::IsEnabled(site_engagement::features::kSiteEngagement)) -+ return; - GetEventModelWriter()->IncrementEvent(event, time_provider_->GetCurrentDay()); - stats::RecordNotifyEvent(event, configuration_.get(), - event_model_provider_->IsReady()); -diff --git a/components/feature_engagement/public/feature_configurations.cc b/components/feature_engagement/public/feature_configurations.cc ---- a/components/feature_engagement/public/feature_configurations.cc -+++ b/components/feature_engagement/public/feature_configurations.cc -@@ -6,6 +6,7 @@ - - #include "base/strings/string_util.h" - #include "build/build_config.h" -+#include "components/site_engagement/core/features.h" - #include "components/feature_engagement/public/configuration.h" - #include "components/feature_engagement/public/event_constants.h" - #include "components/feature_engagement/public/feature_constants.h" -@@ -113,6 +114,12 @@ std::optional GetClientSideFeatureConfig( - } - - #endif // BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_WIN) -+ if (!base::FeatureList::IsEnabled(site_engagement::features::kSiteEngagement)) { -+ std::optional config = FeatureConfig(); -+ config->valid = false; -+ return config; -+ } -+ - #if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_LINUX) || \ - BUILDFLAG(IS_CHROMEOS) - if (kIPHPasswordsManagementBubbleAfterSaveFeature.name == feature->name) { -diff --git a/components/site_engagement/content/site_engagement_score.cc b/components/site_engagement/content/site_engagement_score.cc ---- a/components/site_engagement/content/site_engagement_score.cc -+++ b/components/site_engagement/content/site_engagement_score.cc -@@ -19,6 +19,7 @@ - #include "components/content_settings/core/common/content_settings.h" - #include "components/content_settings/core/common/content_settings_types.h" - #include "components/content_settings/core/common/content_settings_utils.h" -+#include "components/site_engagement/core/features.h" - #include "components/site_engagement/content/engagement_type.h" - #include "components/site_engagement/content/site_engagement_metrics.h" - #include "third_party/blink/public/mojom/site_engagement/site_engagement.mojom.h" -@@ -276,6 +277,10 @@ void SiteEngagementScore::Commit() { - if (!UpdateScoreDict(*score_dict_)) - return; - -+ if (!base::FeatureList::IsEnabled(features::kSiteEngagement)) { -+ score_dict_.reset(); -+ return; -+ } - settings_map_->SetWebsiteSettingDefaultScope( - origin_, GURL(), ContentSettingsType::SITE_ENGAGEMENT, - base::Value(std::move(*score_dict_))); -diff --git a/components/site_engagement/core/BUILD.gn b/components/site_engagement/core/BUILD.gn ---- a/components/site_engagement/core/BUILD.gn -+++ b/components/site_engagement/core/BUILD.gn -@@ -4,8 +4,14 @@ - - static_library("core") { - sources = [ -+ "features.cc", -+ "features.h", - "pref_names.cc", - "pref_names.h", - "site_engagement_score_provider.h", - ] -+ -+ deps = [ -+ "//base", -+ ] - } -diff --git a/components/site_engagement/core/features.cc b/components/site_engagement/core/features.cc -new file mode 100644 ---- /dev/null -+++ b/components/site_engagement/core/features.cc -@@ -0,0 +1,30 @@ -+/* -+ 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 . -+*/ -+ -+#include "components/site_engagement/core/features.h" -+ -+#include "base/feature_list.h" -+ -+namespace site_engagement { -+namespace features { -+ -+CROMITE_FEATURE(kSiteEngagement, -+ "SiteEngagement", -+ base::FEATURE_DISABLED_BY_DEFAULT); -+ -+} // namespace features -+} // namespace site_engagement -diff --git a/components/site_engagement/core/features.h b/components/site_engagement/core/features.h -new file mode 100644 ---- /dev/null -+++ b/components/site_engagement/core/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 . -+*/ -+ -+#ifndef SITE_ENGAGEMENT_CORE_FEATURES_H_ -+#define SITE_ENGAGEMENT_CORE_FEATURES_H_ -+ -+#include -+ -+#include "base/feature_list.h" -+ -+namespace site_engagement { -+namespace features { -+ -+// Enable site engagement -+BASE_DECLARE_FEATURE(kSiteEngagement); -+ -+} // namespace features -+} // namespace site_engagement -+ -+#endif // SITE_ENGAGEMENT_CORE_FEATURES_H_ -diff --git a/cromite_flags/chrome/browser/about_flags_cc/Add-site-engagement-flag.inc b/cromite_flags/chrome/browser/about_flags_cc/Add-site-engagement-flag.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/chrome/browser/about_flags_cc/Add-site-engagement-flag.inc -@@ -0,0 +1,10 @@ -+#ifdef FLAG_SECTION -+ -+ {"site-engagement", -+ "Enable site engagement feature", -+ "Site Engagement Service provides information about how " -+ "engaged a user is with a origin; this affects which NTP " -+ "tiles are automatically created.", kOsAll, -+ FEATURE_VALUE_TYPE(site_engagement::features::kSiteEngagement)}, -+ -+#endif --- diff --git a/build/cromite_patches/Add-support-for-ISupportHelpAndFeedback.patch b/build/cromite_patches/Add-support-for-ISupportHelpAndFeedback.patch deleted file mode 100644 index fde685d2..00000000 --- a/build/cromite_patches/Add-support-for-ISupportHelpAndFeedback.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: uazo -Date: Mon, 17 May 2021 12:30:12 +0000 -Subject: Add support for ISupportHelpAndFeedback - -Original License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../chrome/browser/settings/SettingsActivity.java | 9 +++++++-- - .../components/browser_ui/settings/SettingsUtils.java | 4 ++++ - 2 files changed, 11 insertions(+), 2 deletions(-) - -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java -@@ -63,6 +63,7 @@ import org.chromium.chrome.browser.ui.messages.snackbar.Snackbar; - import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; - import org.chromium.components.browser_ui.bottomsheet.BottomSheetControllerFactory; - import org.chromium.components.browser_ui.bottomsheet.ManagedBottomSheetController; -+import org.chromium.components.browser_ui.settings.SettingsUtils; - import org.chromium.components.browser_ui.modaldialog.AppModalPresenter; - import org.chromium.components.browser_ui.settings.EmbeddableSettingsPage; - import org.chromium.components.browser_ui.settings.PreferenceUpdateObserver; -@@ -733,8 +734,12 @@ public class SettingsActivity extends ChromeBaseAppCompatActivity - finishCurrentSettings(mainFragment); - return true; - } else if (item.getItemId() == R.id.menu_id_general_help) { -- HelpAndFeedbackLauncherImpl.getForProfile(mProfile) -- .show(this, getString(R.string.help_context_settings), null); -+ if (mainFragment instanceof SettingsUtils.ISupportHelpAndFeedback) { -+ ((SettingsUtils.ISupportHelpAndFeedback)mainFragment).onHelpAndFeebackPressed(); -+ } else { -+ HelpAndFeedbackLauncherImpl.getForProfile(mProfile) -+ .show(this, getString(R.string.help_context_settings), null); -+ } - return true; - } - return super.onOptionsItemSelected(item); -diff --git a/components/browser_ui/settings/android/java/src/org/chromium/components/browser_ui/settings/SettingsUtils.java b/components/browser_ui/settings/android/java/src/org/chromium/components/browser_ui/settings/SettingsUtils.java ---- a/components/browser_ui/settings/android/java/src/org/chromium/components/browser_ui/settings/SettingsUtils.java -+++ b/components/browser_ui/settings/android/java/src/org/chromium/components/browser_ui/settings/SettingsUtils.java -@@ -33,6 +33,10 @@ import java.util.ArrayList; - /** A helper class for Settings. */ - @NullMarked - public class SettingsUtils { -+ public interface ISupportHelpAndFeedback { -+ void onHelpAndFeebackPressed(); -+ } -+ - /** - * A helper that is used to load preferences from XML resources without causing a - * StrictModeViolation. See http://crbug.com/692125. --- diff --git a/build/cromite_patches/Add-support-for-writing-URIs.patch b/build/cromite_patches/Add-support-for-writing-URIs.patch deleted file mode 100644 index 49836eb4..00000000 --- a/build/cromite_patches/Add-support-for-writing-URIs.patch +++ /dev/null @@ -1,99 +0,0 @@ -From: uazo -Date: Tue, 12 Apr 2022 15:58:01 +0000 -Subject: Add support for writing URIs - -Allows native-side URI file writing - -Original License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - base/android/content_uri_utils.cc | 10 ++++++ - base/android/content_uri_utils.h | 4 +++ - .../org/chromium/base/ContentUriUtils.java | 33 +++++++++++++++++++ - 3 files changed, 47 insertions(+) - -diff --git a/base/android/content_uri_utils.cc b/base/android/content_uri_utils.cc ---- a/base/android/content_uri_utils.cc -+++ b/base/android/content_uri_utils.cc -@@ -137,6 +137,16 @@ void JNI_ContentUriUtils_AddFileInfoToVector(JNIEnv* env, - Time::FromMillisecondsSinceUnixEpoch(last_modified)); - } - -+File OpenContentUriForWrite(const FilePath& content_uri) { -+ JNIEnv* env = base::android::AttachCurrentThread(); -+ ScopedJavaLocalRef j_uri = -+ ConvertUTF8ToJavaString(env, content_uri.value()); -+ jint fd = Java_ContentUriUtils_openContentUriForWrite(env, j_uri); -+ if (fd < 0) -+ return File(); -+ return File(fd); -+} -+ - std::string GetContentUriMimeType(const FilePath& content_uri) { - JNIEnv* env = android::AttachCurrentThread(); - return Java_ContentUriUtils_getMimeType(env, content_uri.value()); -diff --git a/base/android/content_uri_utils.h b/base/android/content_uri_utils.h ---- a/base/android/content_uri_utils.h -+++ b/base/android/content_uri_utils.h -@@ -46,6 +46,10 @@ int ContentUriGetFd( - void ContentUriClose( - const base::android::JavaRef& java_parcel_file_descriptor); - -+// Opens a content URI for write and returns the file descriptor to the caller. -+// Returns -1 if the URI is invalid. -+BASE_EXPORT File OpenContentUriForWrite(const FilePath& content_uri); -+ - // Returns true if file exists and results are populated, else returns false. - bool ContentUriGetFileInfo(const FilePath& content_uri, - FileEnumerator::FileInfo* results); -diff --git a/base/android/java/src/org/chromium/base/ContentUriUtils.java b/base/android/java/src/org/chromium/base/ContentUriUtils.java ---- a/base/android/java/src/org/chromium/base/ContentUriUtils.java -+++ b/base/android/java/src/org/chromium/base/ContentUriUtils.java -@@ -31,6 +31,9 @@ import org.chromium.build.annotations.Nullable; - import java.io.IOException; - import java.util.List; - -+import android.system.Os; -+import android.content.ContentProviderClient; -+ - /** This class provides methods to access content URI schemes. */ - @JNINamespace("base") - @NullMarked -@@ -72,6 +75,36 @@ public abstract class ContentUriUtils { - StreamUtil.closeQuietly(parcelFileDescriptor); - } - -+ @CalledByNative -+ public static int openContentUriForWrite(String uriString) { -+ try { -+ Uri uri = Uri.parse(uriString); -+ ContentResolver resolver = ContextUtils.getApplicationContext().getContentResolver(); -+ ContentProviderClient client = resolver.acquireContentProviderClient( -+ uri.getAuthority()); -+ ParcelFileDescriptor pfd = client.openFile(uri, "wt"); -+ int fd = pfd.detachFd(); -+ client.close(); -+ return fd; -+ } catch (Exception e) { -+ Log.e(TAG, "Cannot open intermediate URI", e); -+ } -+ return -1; -+ } -+ -+ public static String getFilePathFromContentUri(Uri uri) { -+ String path = null; -+ try { -+ ContentResolver resolver = ContextUtils.getApplicationContext().getContentResolver(); -+ ParcelFileDescriptor pfd = resolver.openFileDescriptor(uri, "r"); -+ path = Os.readlink("/proc/self/fd/" + pfd.getFd()); -+ pfd.close(); -+ } catch (Exception e) { -+ Log.e(TAG, "Cannot get file path from content URI", e); -+ } -+ return path; -+ } -+ - /** - * Check whether a content URI exists. - * --- diff --git a/build/cromite_patches/Add-webGL-site-setting.patch b/build/cromite_patches/Add-webGL-site-setting.patch deleted file mode 100644 index 1972e4fc..00000000 --- a/build/cromite_patches/Add-webGL-site-setting.patch +++ /dev/null @@ -1,286 +0,0 @@ -From: uazo -Date: Tue, 3 May 2022 14:44:11 +0000 -Subject: Add webGL site setting - -Do not provide any device information when serving context creation errors. - -Requires patch: Content-settings-infrastructure.patch - -Original License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../impl/BromiteWebGLContentSetting.java | 93 +++++++++++++++++++ - .../bromite_content_settings/webgl.grdp | 27 ++++++ - .../bromite_content_settings/webgl.inc | 22 +++++ - .../common/bromite_content_settings/WEBGL.inc | 1 + - .../execution_context/execution_context.cc | 7 ++ - .../execution_context/execution_context.h | 2 + - .../webgl/webgl_rendering_context_base.cc | 32 +++---- - .../webgl/webgl_rendering_context_base.h | 2 + - 8 files changed, 167 insertions(+), 19 deletions(-) - create mode 100644 components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/impl/BromiteWebGLContentSetting.java - create mode 100644 components/browser_ui/strings/bromite_content_settings/webgl.grdp - create mode 100644 components/content_settings/core/browser/bromite_content_settings/webgl.inc - create mode 100644 components/content_settings/core/common/bromite_content_settings/WEBGL.inc - -diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/impl/BromiteWebGLContentSetting.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/impl/BromiteWebGLContentSetting.java -new file mode 100644 ---- /dev/null -+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/impl/BromiteWebGLContentSetting.java -@@ -0,0 +1,93 @@ -+/* -+ 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 . -+*/ -+ -+package org.chromium.components.browser_ui.site_settings.impl; -+ -+import org.chromium.components.browser_ui.site_settings.R; -+ -+import org.chromium.components.browser_ui.site_settings.BromiteCustomContentSetting; -+import org.chromium.components.browser_ui.site_settings.ContentSettingsResources; -+import org.chromium.components.browser_ui.site_settings.SiteSettingsCategory; -+import org.chromium.components.content_settings.ContentSetting; -+import org.chromium.components.content_settings.ContentSettingsType; -+import org.chromium.content_public.browser.BrowserContextHandle; -+ -+import androidx.annotation.Nullable; -+import androidx.preference.Preference; -+import androidx.preference.PreferenceScreen; -+ -+import java.util.ArrayList; -+ -+public class BromiteWebGLContentSetting extends BromiteCustomContentSetting { -+ public BromiteWebGLContentSetting() { -+ super(/*contentSettingsType*/ ContentSettingsType.WEBGL, -+ /*defaultEnabledValue*/ ContentSetting.ALLOW, -+ /*defaultDisabledValue*/ ContentSetting.BLOCK, -+ /*allowException*/ true, -+ /*preferenceKey*/ "webgl", -+ /*profilePrefKey*/ "webgl"); -+ } -+ -+ @Override -+ public ContentSettingsResources.ResourceItem getResourceItem() { -+ return new ContentSettingsResources.ResourceItem( -+ /*icon*/ R.drawable.web_asset, -+ /*title*/ R.string.webgl_permission_title, -+ /*defaultEnabledValue*/ getDefaultEnabledValue(), -+ /*defaultDisabledValue*/ getDefaultDisabledValue(), -+ /*enabledSummary*/ R.string.website_settings_category_webgl_enabled, -+ /*disabledSummary*/ R.string.website_settings_category_webgl_disabled, -+ /*summaryOverrideForScreenReader*/ 0); -+ } -+ -+ @Override -+ public int getCategorySummary(@Nullable @ContentSetting int value) { -+ switch (value) { -+ case ContentSetting.ALLOW: -+ return R.string.website_settings_category_webgl_enabled; -+ case ContentSetting.BLOCK: -+ return R.string.website_settings_category_webgl_disabled; -+ default: -+ return 0; -+ } -+ } -+ -+ @Override -+ public int getCategoryDescription() { -+ return R.string.settings_site_settings_webgl_description; -+ } -+ -+ @Override -+ public boolean requiresTriStateContentSetting() { -+ return false; -+ } -+ -+ @Override -+ public boolean showOnlyDescriptions() { -+ return true; -+ } -+ -+ @Override -+ public int getAddExceptionDialogMessage() { -+ return R.string.website_settings_category_webgl_enabled; -+ } -+ -+ @Override -+ public @Nullable Boolean considerException(SiteSettingsCategory category, @ContentSetting int value) { -+ return value != ContentSetting.BLOCK; -+ } -+} -diff --git a/components/browser_ui/strings/bromite_content_settings/webgl.grdp b/components/browser_ui/strings/bromite_content_settings/webgl.grdp -new file mode 100644 ---- /dev/null -+++ b/components/browser_ui/strings/bromite_content_settings/webgl.grdp -@@ -0,0 +1,27 @@ -+ -+ -+ -+ Webgl -+ -+ -+ Enable Webgl, a JavaScript API for rendering high-performance interactive 3D and 2D graphics -+ -+ -+ webgl -+ -+ -+ Webgl -+ -+ -+ Enabled -+ -+ -+ Disabled -+ -+ -+ Allowed to use webgl -+ -+ -+ Not allowed to use webgl -+ -+ -diff --git a/components/content_settings/core/browser/bromite_content_settings/webgl.inc b/components/content_settings/core/browser/bromite_content_settings/webgl.inc -new file mode 100644 ---- /dev/null -+++ b/components/content_settings/core/browser/bromite_content_settings/webgl.inc -@@ -0,0 +1,22 @@ -+ Register(ContentSettingsType::WEBGL, "webgl", CONTENT_SETTING_BLOCK, -+ WebsiteSettingsInfo::SYNCABLE, -+ /*allowlisted_schemes=*/{}, -+ /*valid_settings=*/{CONTENT_SETTING_ALLOW, -+ CONTENT_SETTING_BLOCK}, -+ WebsiteSettingsInfo::TOP_ORIGIN_ONLY_SCOPE, -+ WebsiteSettingsRegistry::ALL_PLATFORMS, -+ ContentSettingsInfo::INHERIT_IN_INCOGNITO, -+ PermissionSettingsInfo::EXCEPTIONS_ON_SECURE_AND_INSECURE_ORIGINS); -+ -+ content_settings::WebsiteSettingsRegistry::GetInstance() -+ ->GetMutable(ContentSettingsType::WEBGL) -+ ->set_show_into_info_page() -+ .set_desktop_ui() -+ .set_is_renderer_content_setting() -+ .set_title_ui(IDS_SITE_SETTINGS_TYPE_WEBGL) -+ .set_description_ui(IDS_SETTINGS_SITE_SETTINGS_WEBGL_DESCRIPTION) -+ .set_allowed_ui(IDS_WEBSITE_SETTINGS_CATEGORY_WEBGL_ENABLED) -+ .set_blocked_ui(IDS_WEBSITE_SETTINGS_CATEGORY_WEBGL_DISABLED) -+ .set_allowed_exceptions_ui(IDS_SETTINGS_SITE_SETTINGS_WEBGL_ALLOWED_EXCEPTIONS) -+ .set_blocked_exceptions_ui(IDS_SETTINGS_SITE_SETTINGS_WEBGL_BLOCKED_EXCEPTIONS) -+ .set_mid_sentence_ui(IDS_SITE_SETTINGS_TYPE_WEBGL); -diff --git a/components/content_settings/core/common/bromite_content_settings/WEBGL.inc b/components/content_settings/core/common/bromite_content_settings/WEBGL.inc -new file mode 100644 ---- /dev/null -+++ b/components/content_settings/core/common/bromite_content_settings/WEBGL.inc -@@ -0,0 +1 @@ -+ WEBGL, -diff --git a/third_party/blink/renderer/core/execution_context/execution_context.cc b/third_party/blink/renderer/core/execution_context/execution_context.cc ---- a/third_party/blink/renderer/core/execution_context/execution_context.cc -+++ b/third_party/blink/renderer/core/execution_context/execution_context.cc -@@ -86,6 +86,13 @@ blink::WebContentSettingsClient* GetContentSettingsClientFor( - return settings; - } - -+bool AllowWebgl(ExecutionContext* context) { -+ blink::WebContentSettingsClient* settings = GetContentSettingsClientFor(context); -+ if (settings) -+ return settings->AllowContentSetting(ContentSettingsType::WEBGL, false); -+ return false; -+} -+ - ExecutionContext::ExecutionContext(v8::Isolate* isolate, - Agent* agent, - bool is_window) -diff --git a/third_party/blink/renderer/core/execution_context/execution_context.h b/third_party/blink/renderer/core/execution_context/execution_context.h ---- a/third_party/blink/renderer/core/execution_context/execution_context.h -+++ b/third_party/blink/renderer/core/execution_context/execution_context.h -@@ -115,6 +115,8 @@ enum ReasonForCallingCanExecuteScripts { - - enum ReferrerPolicySource { kPolicySourceHttpHeader, kPolicySourceMetaTag }; - -+CORE_EXPORT bool AllowWebgl(ExecutionContext* context); -+ - // An environment in which script can execute. This class exposes the common - // properties of script execution environments on the web (i.e, common between - // script executing in a window and script executing in a worker), such as: -diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc ---- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc -+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc -@@ -346,6 +346,13 @@ void WebGLRenderingContextBase::InitializeWebGLContextLimits( - } - } - -+bool WebGLRenderingContextBase::AllowWebglForHost(blink::CanvasRenderingContextHost* host) { -+ if (!host) -+ return false; -+ blink::ExecutionContext* context = host->GetTopExecutionContext(); -+ return blink::AllowWebgl(context); -+} -+ - unsigned WebGLRenderingContextBase::CurrentMaxGLContexts() { - base::AutoLock locker(WebGLContextLimitLock()); - DCHECK(webgl_context_limits_initialized_); -@@ -616,25 +623,6 @@ static String ExtractWebGLContextCreationError( - const Platform::WebGLContextInfo& info) { - StringBuilder builder; - builder.Append("Could not create a WebGL context"); -- FormatWebGLStatusString( -- "VENDOR", -- info.vendor_id ? String::Format("0x%04x", info.vendor_id) : "0xffff", -- builder); -- FormatWebGLStatusString( -- "DEVICE", -- info.device_id ? String::Format("0x%04x", info.device_id) : "0xffff", -- builder); -- FormatWebGLStatusString("GL_VENDOR", info.vendor_info, builder); -- FormatWebGLStatusString("GL_RENDERER", info.renderer_info, builder); -- FormatWebGLStatusString("GL_VERSION", info.driver_version, builder); -- FormatWebGLStatusString("Sandboxed", info.sandboxed ? "yes" : "no", builder); -- FormatWebGLStatusString("Optimus", info.optimus ? "yes" : "no", builder); -- FormatWebGLStatusString("AMD switchable", info.amd_switchable ? "yes" : "no", -- builder); -- FormatWebGLStatusString( -- "Reset notification strategy", -- String::Format("0x%04x", info.reset_notification_strategy).Utf8().c_str(), -- builder); - FormatWebGLStatusString("ErrorMessage", info.error_message.Utf8().c_str(), - builder); - builder.Append('.'); -@@ -695,6 +683,12 @@ WebGLRenderingContextBase::CreateWebGraphicsContext3DProvider( - const CanvasContextCreationAttributesCore& attributes, - Platform::WebGLContextType context_type, - Platform::WebGLContextInfo* context_info) { -+ if (!AllowWebglForHost(host)) { -+ host->HostDispatchEvent(WebGLContextEvent::Create( -+ event_type_names::kWebglcontextcreationerror, -+ "disabled by site settings policy.")); -+ return nullptr; -+ } - if ((context_type == Platform::kWebGL1ContextType && - !host->IsWebGL1Enabled()) || - (context_type == Platform::kWebGL2ContextType && -diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h ---- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h -+++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h -@@ -1959,6 +1959,8 @@ class MODULES_EXPORT WebGLRenderingContextBase - DOMArrayBufferView* pixels, - int64_t offset); - -+ static bool AllowWebglForHost(blink::CanvasRenderingContextHost* host); -+ - void RecordANGLEImplementation(); - - private: --- diff --git a/build/cromite_patches/Add-webRTC-site-settings.patch b/build/cromite_patches/Add-webRTC-site-settings.patch deleted file mode 100644 index fe0202fd..00000000 --- a/build/cromite_patches/Add-webRTC-site-settings.patch +++ /dev/null @@ -1,266 +0,0 @@ -From: uazo -Date: Fri, 6 May 2022 14:27:17 +0000 -Subject: Add webRTC site settings - -Requires patch: Content-settings-infrastructure.patch - -Original License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../impl/BromiteWebRTCContentSetting.java | 94 +++++++++++++++++++ - .../bromite_content_settings/webrtc.grdp | 27 ++++++ - .../bromite_content_settings/webrtc.inc | 22 +++++ - .../bromite_content_settings/WEBRTC.inc | 1 + - .../peer_connection_dependency_factory.cc | 6 ++ - .../peerconnection/rtc_rtp_receiver.cc | 11 +++ - .../modules/peerconnection/rtc_rtp_sender.cc | 11 +++ - 7 files changed, 172 insertions(+) - create mode 100644 components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/impl/BromiteWebRTCContentSetting.java - create mode 100644 components/browser_ui/strings/bromite_content_settings/webrtc.grdp - create mode 100644 components/content_settings/core/browser/bromite_content_settings/webrtc.inc - create mode 100644 components/content_settings/core/common/bromite_content_settings/WEBRTC.inc - -diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/impl/BromiteWebRTCContentSetting.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/impl/BromiteWebRTCContentSetting.java -new file mode 100644 ---- /dev/null -+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/impl/BromiteWebRTCContentSetting.java -@@ -0,0 +1,94 @@ -+/* -+ 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 . -+*/ -+ -+package org.chromium.components.browser_ui.site_settings.impl; -+ -+import org.chromium.components.browser_ui.site_settings.R; -+ -+import org.chromium.components.browser_ui.site_settings.BromiteCustomContentSetting; -+import org.chromium.components.browser_ui.site_settings.ContentSettingsResources; -+import org.chromium.components.browser_ui.site_settings.SiteSettingsCategory; -+import org.chromium.components.content_settings.ContentSetting; -+import org.chromium.components.content_settings.ContentSettingsType; -+import org.chromium.content_public.browser.BrowserContextHandle; -+ -+import androidx.annotation.Nullable; -+import androidx.preference.Preference; -+import androidx.preference.PreferenceScreen; -+ -+import java.util.ArrayList; -+ -+public class BromiteWebRTCContentSetting extends BromiteCustomContentSetting { -+ public BromiteWebRTCContentSetting() { -+ super(/*contentSettingsType*/ ContentSettingsType.WEBRTC, -+ /*defaultEnabledValue*/ ContentSetting.ALLOW, -+ /*defaultDisabledValue*/ ContentSetting.BLOCK, -+ /*allowException*/ true, -+ /*preferenceKey*/ "webrtc", -+ /*profilePrefKey*/ "webrtc"); -+ } -+ -+ @Override -+ public ContentSettingsResources.ResourceItem getResourceItem() { -+ return new ContentSettingsResources.ResourceItem( -+ /*icon*/ R.drawable.web_asset, -+ /*title*/ R.string.webrtc_permission_title, -+ /*defaultEnabledValue*/ getDefaultEnabledValue(), -+ /*defaultDisabledValue*/ getDefaultDisabledValue(), -+ /*enabledSummary*/ R.string.website_settings_category_webrtc_enabled, -+ /*disabledSummary*/ R.string.website_settings_category_webrtc_disabled, -+ /*summaryOverrideForScreenReader*/ 0); -+ } -+ -+ @Override -+ public int getCategorySummary(@Nullable @ContentSetting int value) { -+ switch (value) { -+ case ContentSetting.ALLOW: -+ return R.string.website_settings_category_webrtc_enabled; -+ case ContentSetting.BLOCK: -+ return R.string.website_settings_category_webrtc_disabled; -+ default: -+ // this will cause a runtime exception -+ return 0; -+ } -+ } -+ -+ @Override -+ public int getCategoryDescription() { -+ return R.string.settings_site_settings_webrtc_description; -+ } -+ -+ @Override -+ public boolean requiresTriStateContentSetting() { -+ return false; -+ } -+ -+ @Override -+ public boolean showOnlyDescriptions() { -+ return true; -+ } -+ -+ @Override -+ public int getAddExceptionDialogMessage() { -+ return R.string.website_settings_category_webrtc_enabled; -+ } -+ -+ @Override -+ public @Nullable Boolean considerException(SiteSettingsCategory category, @ContentSetting int value) { -+ return value != ContentSetting.BLOCK; -+ } -+} -diff --git a/components/browser_ui/strings/bromite_content_settings/webrtc.grdp b/components/browser_ui/strings/bromite_content_settings/webrtc.grdp -new file mode 100644 ---- /dev/null -+++ b/components/browser_ui/strings/bromite_content_settings/webrtc.grdp -@@ -0,0 +1,27 @@ -+ -+ -+ -+ WebRTC -+ -+ -+ webRTC -+ -+ -+ Enable WebRTC, a JavaScript API for real-time communication and direct peer-to-peer communication -+ -+ -+ WebRTC -+ -+ -+ Enabled -+ -+ -+ Disabled -+ -+ -+ Allowed to use WebRTC -+ -+ -+ Not allowed to use WebRTC -+ -+ -diff --git a/components/content_settings/core/browser/bromite_content_settings/webrtc.inc b/components/content_settings/core/browser/bromite_content_settings/webrtc.inc -new file mode 100644 ---- /dev/null -+++ b/components/content_settings/core/browser/bromite_content_settings/webrtc.inc -@@ -0,0 +1,22 @@ -+ Register(ContentSettingsType::WEBRTC, "webrtc", CONTENT_SETTING_BLOCK, -+ WebsiteSettingsInfo::SYNCABLE, -+ /*allowlisted_schemes=*/{}, -+ /*valid_settings=*/{CONTENT_SETTING_ALLOW, -+ CONTENT_SETTING_BLOCK}, -+ WebsiteSettingsInfo::TOP_ORIGIN_ONLY_SCOPE, -+ WebsiteSettingsRegistry::ALL_PLATFORMS, -+ ContentSettingsInfo::INHERIT_IN_INCOGNITO, -+ PermissionSettingsInfo::EXCEPTIONS_ON_SECURE_AND_INSECURE_ORIGINS); -+ -+ content_settings::WebsiteSettingsRegistry::GetInstance() -+ ->GetMutable(ContentSettingsType::WEBRTC) -+ ->set_show_into_info_page() -+ .set_desktop_ui() -+ .set_is_renderer_content_setting() -+ .set_title_ui(IDS_SITE_SETTINGS_TYPE_WEBRTC) -+ .set_description_ui(IDS_SETTINGS_SITE_SETTINGS_WEBRTC_DESCRIPTION) -+ .set_allowed_ui(IDS_WEBSITE_SETTINGS_CATEGORY_WEBRTC_ENABLED) -+ .set_blocked_ui(IDS_WEBSITE_SETTINGS_CATEGORY_WEBRTC_DISABLED) -+ .set_allowed_exceptions_ui(IDS_SETTINGS_SITE_SETTINGS_WEBRTC_ALLOWED_EXCEPTIONS) -+ .set_blocked_exceptions_ui(IDS_SETTINGS_SITE_SETTINGS_WEBRTC_BLOCKED_EXCEPTIONS) -+ .set_mid_sentence_ui(IDS_SITE_SETTINGS_TYPE_WEBRTC_MID_SENTENCE); -diff --git a/components/content_settings/core/common/bromite_content_settings/WEBRTC.inc b/components/content_settings/core/common/bromite_content_settings/WEBRTC.inc -new file mode 100644 ---- /dev/null -+++ b/components/content_settings/core/common/bromite_content_settings/WEBRTC.inc -@@ -0,0 +1 @@ -+ WEBRTC, -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 -@@ -47,6 +47,7 @@ - #include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h" - #include "third_party/blink/public/platform/platform.h" - #include "third_party/blink/public/platform/task_type.h" -+#include "third_party/blink/public/platform/web_content_settings_client.h" - #include "third_party/blink/public/platform/web_url.h" - #include "third_party/blink/public/web/modules/mediastream/media_stream_video_source.h" - #include "third_party/blink/public/web/web_document.h" -@@ -989,6 +990,11 @@ PeerConnectionDependencyFactory::CreatePortAllocator( - // |request_multiple_routes|. Whether local IP addresses could be - // collected depends on if mic/camera permission is granted for this - // origin. -+ blink::WebContentSettingsClient* settings = web_frame->GetContentSettingsClient(); -+ if (settings && settings->AllowContentSetting(ContentSettingsType::WEBRTC, false)) { -+ webrtc_ip_handling_policy = mojom::blink::WebRtcIpHandlingPolicy::kDefault; -+ } -+ - switch (webrtc_ip_handling_policy) { - // TODO(guoweis): specify the flag of disabling local candidate - // collection when webrtc is updated. -diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc ---- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc -+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc -@@ -16,6 +16,9 @@ - #include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" - #include "third_party/blink/public/common/privacy_budget/identifiable_token_builder.h" - #include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h" -+#include "third_party/blink/public/platform/web_content_settings_client.h" -+#include "third_party/blink/public/web/web_local_frame.h" -+#include "third_party/blink/renderer/core/frame/local_dom_window.h" - #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" - #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_insertable_streams.h" - #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtcp_parameters.h" -@@ -279,6 +282,14 @@ RTCRtpCapabilities* RTCRtpReceiver::getCapabilities(ScriptState* state, - if (kind != "audio" && kind != "video") - return nullptr; - -+ LocalDOMWindow* window = To(ExecutionContext::From(state)); -+ auto* web_frame = -+ static_cast(WebFrame::FromCoreFrame(window->GetFrame())); -+ blink::WebContentSettingsClient* settings = web_frame->GetContentSettingsClient(); -+ if (settings && !settings->AllowContentSetting(ContentSettingsType::WEBRTC, false)) { -+ return nullptr; -+ } -+ - RTCRtpCapabilities* capabilities = RTCRtpCapabilities::Create(); - capabilities->setCodecs(HeapVector>()); - capabilities->setHeaderExtensions( -diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc ---- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc -+++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc -@@ -21,6 +21,9 @@ - #include "third_party/blink/public/common/privacy_budget/identifiable_surface.h" - #include "third_party/blink/public/common/privacy_budget/identifiable_token_builder.h" - #include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h" -+#include "third_party/blink/public/platform/web_content_settings_client.h" -+#include "third_party/blink/public/web/web_local_frame.h" -+#include "third_party/blink/renderer/core/frame/local_dom_window.h" - #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" - #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_encoding_options.h" - #include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_insertable_streams.h" -@@ -1031,6 +1034,14 @@ RTCRtpCapabilities* RTCRtpSender::getCapabilities(ScriptState* state, - if (kind != "audio" && kind != "video") - return nullptr; - -+ LocalDOMWindow* window = To(ExecutionContext::From(state)); -+ auto* web_frame = -+ static_cast(WebFrame::FromCoreFrame(window->GetFrame())); -+ blink::WebContentSettingsClient* settings = web_frame->GetContentSettingsClient(); -+ if (settings && !settings->AllowContentSetting(ContentSettingsType::WEBRTC, false)) { -+ return nullptr; -+ } -+ - RTCRtpCapabilities* capabilities = RTCRtpCapabilities::Create(); - capabilities->setCodecs(HeapVector>()); - capabilities->setHeaderExtensions( --- diff --git a/build/cromite_patches/Allow-building-without-enable_reporting.patch b/build/cromite_patches/Allow-building-without-enable_reporting.patch deleted file mode 100644 index 0dcdb80a..00000000 --- a/build/cromite_patches/Allow-building-without-enable_reporting.patch +++ /dev/null @@ -1,560 +0,0 @@ -From: Zoraver Kang -Date: Fri, 22 May 2020 22:43:27 -0400 -Subject: Allow building without enable_reporting - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - chrome/browser/net/chrome_report_sender.cc | 1 + - .../browser/devtools/protocol/network_handler.cc | 2 ++ - .../cross_origin_embedder_policy_reporter.cc | 7 +++++-- - .../browser/network/reporting_service_proxy.cc | 3 +++ - .../renderer_host/render_frame_host_impl.cc | 6 ------ - .../coop/cross_origin_opener_policy_reporter.cc | 16 +++++++--------- - .../dip/document_isolation_policy_reporter.cc | 3 +++ - .../web_package/signed_exchange_reporter.cc | 2 ++ - ...content_switch_dependent_feature_overrides.cc | 1 + - .../Allow-building-without-enable_reporting.inc | 2 ++ - net/reporting/reporting_header_parser.cc | 1 + - net/reporting/reporting_service.cc | 6 ++++++ - services/network/network_context.h | 6 +++--- - services/network/public/cpp/parsed_headers.cc | 1 + - services/network/public/mojom/BUILD.gn | 1 - - .../network/public/mojom/network_context.mojom | 3 +++ - .../core/frame/csp/content_security_policy.cc | 3 +++ - .../blink/renderer/core/frame/local_frame.cc | 3 +++ - .../blink/renderer/core/frame/local_frame.h | 3 +++ - .../renderer/core/frame/reporting_context.cc | 9 +++++++++ - .../renderer/core/frame/reporting_context.h | 7 +++++-- - .../renderer/core/frame/reporting_observer.cc | 3 +-- - 22 files changed, 64 insertions(+), 25 deletions(-) - create mode 100644 cromite_flags/services/network/public/cpp/features_cc/Allow-building-without-enable_reporting.inc - -diff --git a/chrome/browser/net/chrome_report_sender.cc b/chrome/browser/net/chrome_report_sender.cc ---- a/chrome/browser/net/chrome_report_sender.cc -+++ b/chrome/browser/net/chrome_report_sender.cc -@@ -85,6 +85,7 @@ void SendReport( - const std::string& report, - base::OnceClosure success_callback, - ErrorCallback error_callback) { -+ if ((true)) return; - auto resource_request = std::make_unique(); - resource_request->url = report_uri; - resource_request->method = "POST"; -diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc ---- a/content/browser/devtools/protocol/network_handler.cc -+++ b/content/browser/devtools/protocol/network_handler.cc -@@ -1520,6 +1520,7 @@ String BuildReportStatus(const net::ReportingReport::Status status) { - } - } - -+#if BUILDFLAG(ENABLE_REPORTING) - std::vector ComputeReportingURLs(RenderFrameHostImpl* frame_host) { - std::vector urls; - frame_host->ForEachRenderFrameHostImplWithAction( -@@ -1533,6 +1534,7 @@ std::vector ComputeReportingURLs(RenderFrameHostImpl* frame_host) { - }); - return urls; - } -+#endif // BUILDFLAG(ENABLE_REPORTING) - - } // namespace - -diff --git a/content/browser/network/cross_origin_embedder_policy_reporter.cc b/content/browser/network/cross_origin_embedder_policy_reporter.cc ---- a/content/browser/network/cross_origin_embedder_policy_reporter.cc -+++ b/content/browser/network/cross_origin_embedder_policy_reporter.cc -@@ -4,6 +4,7 @@ - - #include "content/browser/network/cross_origin_embedder_policy_reporter.h" - -+#include "net/base/features.h" - #include - - #include "base/values.h" -@@ -96,8 +97,6 @@ void CrossOriginEmbedderPolicyReporter::Clone( - void CrossOriginEmbedderPolicyReporter::QueueAndNotify( - std::initializer_list> body, - bool report_only) { -- const std::optional& endpoint = -- report_only ? report_only_endpoint_ : endpoint_; - const char* const disposition = report_only ? "reporting" : "enforce"; - if (observer_) { - std::vector list; -@@ -112,6 +111,9 @@ void CrossOriginEmbedderPolicyReporter::QueueAndNotify( - observer_->Notify(blink::mojom::Report::New( - kType, context_url_, blink::mojom::ReportBody::New(std::move(list)))); - } -+#if BUILDFLAG(ENABLE_REPORTING) -+ const std::optional& endpoint = -+ report_only ? report_only_endpoint_ : endpoint_; - if (endpoint) { - base::Value::Dict body_to_pass; - for (const auto& pair : body) { -@@ -125,6 +127,7 @@ void CrossOriginEmbedderPolicyReporter::QueueAndNotify( - network_anonymization_key_, std::move(body_to_pass)); - } - } -+#endif - } - - } // namespace content -diff --git a/content/browser/network/reporting_service_proxy.cc b/content/browser/network/reporting_service_proxy.cc ---- a/content/browser/network/reporting_service_proxy.cc -+++ b/content/browser/network/reporting_service_proxy.cc -@@ -11,6 +11,7 @@ - #include "base/memory/ref_counted.h" - #include "base/unguessable_token.h" - #include "base/values.h" -+#include "net/base/features.h" - #include "content/browser/service_worker/service_worker_host.h" - #include "content/browser/worker_host/dedicated_worker_host.h" - #include "content/browser/worker_host/shared_worker_host.h" -@@ -240,12 +241,14 @@ class ReportingServiceProxyImpl : public blink::mojom::ReportingServiceProxy { - const std::string& group, - const std::string& type, - base::Value::Dict body) { -+#if BUILDFLAG(ENABLE_REPORTING) - auto* rph = RenderProcessHost::FromID(render_process_id_); - if (!rph) - return; - rph->GetStoragePartition()->GetNetworkContext()->QueueReport( - type, group, url, reporting_source_, network_anonymization_key_, - std::move(body)); -+#endif - } - - const int render_process_id_; -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 -@@ -16264,12 +16264,6 @@ void RenderFrameHostImpl::MaybeGenerateCrashReport( - } - } - } -- -- // Send the crash report to the Reporting API. -- GetProcess()->GetStoragePartition()->GetNetworkContext()->QueueReport( -- /*type=*/"crash", crash_reporting_group_, last_committed_url_, -- GetReportingSource(), isolation_info_.network_anonymization_key(), -- std::move(body)); - } - - void RenderFrameHostImpl::UpdateOrDisableCompositorMetricRecorder() const { -diff --git a/content/browser/security/coop/cross_origin_opener_policy_reporter.cc b/content/browser/security/coop/cross_origin_opener_policy_reporter.cc ---- a/content/browser/security/coop/cross_origin_opener_policy_reporter.cc -+++ b/content/browser/security/coop/cross_origin_opener_policy_reporter.cc -@@ -18,25 +18,17 @@ - #include "services/network/public/mojom/network_context.mojom.h" - #include "services/network/public/mojom/source_location.mojom.h" - #include "url/origin.h" -+#include "build/build_config.h" - - namespace content { - - namespace { - - // Report attribute names (camelCase): --constexpr char kColumnNumber[] = "columnNumber"; - constexpr char kDisposition[] = "disposition"; --constexpr char kEffectivePolicy[] = "effectivePolicy"; --constexpr char kInitialPopupURL[] = "initialPopupURL"; --constexpr char kLineNumber[] = "lineNumber"; - constexpr char kNextURL[] = "nextResponseURL"; --constexpr char kOpeneeURL[] = "openeeURL"; --constexpr char kOpenerURL[] = "openerURL"; --constexpr char kOtherDocumentURL[] = "otherDocumentURL"; - constexpr char kPreviousURL[] = "previousResponseURL"; --constexpr char kProperty[] = "property"; - constexpr char kReferrer[] = "referrer"; --constexpr char kSourceFile[] = "sourceFile"; - constexpr char kType[] = "type"; - - // Report attribute values: -@@ -45,6 +37,7 @@ constexpr char kDispositionReporting[] = "reporting"; - constexpr char kTypeFromResponse[] = "navigation-from-response"; - constexpr char kTypeToResponse[] = "navigation-to-response"; - -+#if BUILDFLAG(ENABLE_REPORTING) - std::string ToString(network::mojom::CrossOriginOpenerPolicyValue coop_value) { - switch (coop_value) { - case network::mojom::CrossOriginOpenerPolicyValue::kUnsafeNone: -@@ -59,6 +52,7 @@ std::string ToString(network::mojom::CrossOriginOpenerPolicyValue coop_value) { - return "noopener-allow-popups"; - } - } -+#endif - - FrameTreeNode* TopLevelOpener(FrameTreeNode* frame) { - FrameTreeNode* opener = -@@ -230,6 +224,7 @@ void CrossOriginOpenerPolicyReporter::QueueAccessReport( - network::mojom::SourceLocationPtr source_location, - const std::string& reported_window_url, - const std::string& initial_popup_url) const { -+#if BUILDFLAG(ENABLE_REPORTING) - // Cross-Origin-Opener-Policy-Report-Only is not required to provide - // endpoints. - if (!coop_.report_only_reporting_endpoint) -@@ -277,12 +272,14 @@ void CrossOriginOpenerPolicyReporter::QueueAccessReport( - storage_partition_->GetNetworkContext()->QueueReport( - "coop", endpoint, context_url_, reporting_source_, - network_anonymization_key_, std::move(body)); -+#endif - } - - void CrossOriginOpenerPolicyReporter::QueueNavigationReport( - base::Value::Dict body, - const std::string& endpoint, - bool is_report_only) { -+#if BUILDFLAG(ENABLE_REPORTING) - body.Set(kDisposition, - is_report_only ? kDispositionReporting : kDispositionEnforce); - body.Set(kEffectivePolicy, -@@ -290,6 +287,7 @@ void CrossOriginOpenerPolicyReporter::QueueNavigationReport( - storage_partition_->GetNetworkContext()->QueueReport( - "coop", endpoint, context_url_, reporting_source_, - network_anonymization_key_, std::move(body)); -+#endif - } - - } // namespace content -diff --git a/content/browser/security/dip/document_isolation_policy_reporter.cc b/content/browser/security/dip/document_isolation_policy_reporter.cc ---- a/content/browser/security/dip/document_isolation_policy_reporter.cc -+++ b/content/browser/security/dip/document_isolation_policy_reporter.cc -@@ -7,6 +7,7 @@ - #include - - #include "base/values.h" -+#include "net/net_buildflags.h" - #include "content/public/browser/storage_partition.h" - #include "services/network/public/cpp/request_destination.h" - #include "services/network/public/mojom/network_context.mojom.h" -@@ -94,11 +95,13 @@ void DocumentIsolationPolicyReporter::QueueAndNotify( - } - body_to_pass.Set("disposition", disposition); - -+#if BUILDFLAG(ENABLE_REPORTING) - if (auto* storage_partition = storage_partition_.get()) { - storage_partition->GetNetworkContext()->QueueReport( - kType, *endpoint, context_url_, reporting_source_, - network_anonymization_key_, std::move(body_to_pass)); - } -+#endif - } - } - -diff --git a/content/browser/web_package/signed_exchange_reporter.cc b/content/browser/web_package/signed_exchange_reporter.cc ---- a/content/browser/web_package/signed_exchange_reporter.cc -+++ b/content/browser/web_package/signed_exchange_reporter.cc -@@ -127,6 +127,7 @@ void ReportResult( - FrameTreeNodeId frame_tree_node_id, - network::mojom::SignedExchangeReportPtr report, - const net::NetworkAnonymizationKey& network_anonymization_key) { -+#if BUILDFLAG(ENABLE_REPORTING) - FrameTreeNode* frame_tree_node = - FrameTreeNode::GloballyFindByID(frame_tree_node_id); - if (!frame_tree_node) -@@ -141,6 +142,7 @@ void ReportResult( - DCHECK(partition); - partition->GetNetworkContext()->QueueSignedExchangeReport( - std::move(report), network_anonymization_key); -+#endif - } - - } // namespace -diff --git a/content/public/common/content_switch_dependent_feature_overrides.cc b/content/public/common/content_switch_dependent_feature_overrides.cc ---- a/content/public/common/content_switch_dependent_feature_overrides.cc -+++ b/content/public/common/content_switch_dependent_feature_overrides.cc -@@ -9,6 +9,7 @@ - #include "content/public/common/content_features.h" - #include "content/public/common/content_switches.h" - #include "net/base/features.h" -+#include "net/net_buildflags.h" - #include "services/network/public/cpp/features.h" - #include "services/network/public/cpp/network_switches.h" - #include "third_party/blink/public/common/features.h" -diff --git a/cromite_flags/services/network/public/cpp/features_cc/Allow-building-without-enable_reporting.inc b/cromite_flags/services/network/public/cpp/features_cc/Allow-building-without-enable_reporting.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/services/network/public/cpp/features_cc/Allow-building-without-enable_reporting.inc -@@ -0,0 +1,2 @@ -+SET_CROMITE_FEATURE_DISABLED(kNetworkErrorLogging); -+SET_CROMITE_FEATURE_DISABLED(kReporting); -diff --git a/net/reporting/reporting_header_parser.cc b/net/reporting/reporting_header_parser.cc ---- a/net/reporting/reporting_header_parser.cc -+++ b/net/reporting/reporting_header_parser.cc -@@ -344,6 +344,7 @@ void ReportingHeaderParser::ProcessParsedReportingEndpointsHeader( - const NetworkAnonymizationKey& network_anonymization_key, - const url::Origin& origin, - base::flat_map header) { -+ CHECK(false); - DCHECK(GURL::SchemeIsCryptographic(origin.scheme())); - DCHECK(!reporting_source.is_empty()); - DCHECK(network_anonymization_key.IsEmpty() || -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 -@@ -236,6 +236,12 @@ class ReportingServiceImpl : public ReportingService { - int depth, - base::TimeTicks queued_ticks, - ReportingTargetType target_type) { -+#if BUILDFLAG(ENABLE_REPORTING) -+ if ((true)) -+ return; -+#else -+#error Attempting to build with enable_reporting -+#endif - DCHECK(initialized_); - context_->cache()->AddReport( - reporting_source, network_anonymization_key, sanitized_url, user_agent, -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 -@@ -506,14 +506,14 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext - const GURL& url, - const std::optional& reporting_source, - const net::NetworkAnonymizationKey& network_anonymization_key, -- base::Value::Dict body) override; -+ base::Value::Dict body); - void QueueEnterpriseReport(const std::string& type, - const std::string& group, - const GURL& url, -- base::Value::Dict body) override; -+ base::Value::Dict body); - void QueueSignedExchangeReport( - mojom::SignedExchangeReportPtr report, -- const net::NetworkAnonymizationKey& network_anonymization_key) override; -+ const net::NetworkAnonymizationKey& network_anonymization_key); - void AddDomainReliabilityContextForTesting( - const url::Origin& origin, - const GURL& upload_url, -diff --git a/services/network/public/cpp/parsed_headers.cc b/services/network/public/cpp/parsed_headers.cc ---- a/services/network/public/cpp/parsed_headers.cc -+++ b/services/network/public/cpp/parsed_headers.cc -@@ -133,6 +133,7 @@ mojom::ParsedHeadersPtr PopulateParsedHeaders( - } - - #if BUILDFLAG(ENABLE_REPORTING) -+#error Attempting to build with enable_reporting - if (std::optional reporting_endpoints = - headers->GetNormalizedHeader("Reporting-Endpoints")) { - parsed_headers->reporting_endpoints = -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 -@@ -1793,7 +1793,6 @@ mojom("mojom") { - export_define_blink = "BLINK_PLATFORM_IMPLEMENTATION=1" - export_header_blink = "third_party/blink/public/platform/web_common.h" - if (enable_reporting) { -- enabled_features += [ "enable_reporting" ] - } - } - -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 -@@ -1303,6 +1303,7 @@ interface NetworkContext { - // provided `network_anonymization_key`. - // - // Spec: https://w3c.github.io/reporting/#concept-reports -+ [EnableIf=enable_reporting] - QueueReport(string type, - string group, - url.mojom.Url url, -@@ -1310,6 +1311,7 @@ interface NetworkContext { - NetworkAnonymizationKey network_anonymization_key, - mojo_base.mojom.DictionaryValue body); - -+ [EnableIf=enable_reporting] - QueueEnterpriseReport(string type, - string group, - url.mojom.Url url, -@@ -1320,6 +1322,7 @@ interface NetworkContext { - // Note that this queued report will never be delivered if no reporting - // endpoint matching is registered for with the provided - // `network_anonymization_key`. -+ [EnableIf=enable_reporting] - QueueSignedExchangeReport(SignedExchangeReport report, - NetworkAnonymizationKey network_anonymization_key); - -diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc ---- a/third_party/blink/renderer/core/frame/csp/content_security_policy.cc -+++ b/third_party/blink/renderer/core/frame/csp/content_security_policy.cc -@@ -31,6 +31,7 @@ - #include - #include - -+#include "net/net_buildflags.h" - #include "base/containers/contains.h" - #include "base/debug/dump_without_crashing.h" - #include "base/feature_list.h" -@@ -1355,6 +1356,7 @@ void ContentSecurityPolicy::ReportViolation( - ShouldBypassContentSecurityPolicy(KURL(violation_data->sourceFile()))) { - return; - } -+#if BUILDFLAG(ENABLE_REPORTING) - PostViolationReport(violation_data, context_frame, report_endpoints, - use_reporting_api); - -@@ -1362,6 +1364,7 @@ void ContentSecurityPolicy::ReportViolation( - // `context_frame` (i.e. we're not processing 'frame-ancestors'). - if (delegate_ && !context_frame) - delegate_->DispatchViolationEvent(*violation_data, element); -+#endif - - AuditsIssue audits_issue = AuditsIssue::CreateContentSecurityPolicyIssue( - *violation_data, header_type == ContentSecurityPolicyType::kReport, -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 -@@ -48,6 +48,7 @@ - #include "build/build_config.h" - #include "mojo/public/cpp/bindings/self_owned_receiver.h" - #include "mojo/public/cpp/system/message_pipe.h" -+#include "net/net_buildflags.h" - #include "services/network/public/cpp/features.h" - #include "services/network/public/mojom/content_security_policy.mojom-blink.h" - #include "services/network/public/mojom/source_location.mojom-blink.h" -@@ -2851,9 +2852,11 @@ DocumentResourceCoordinator* LocalFrame::GetDocumentResourceCoordinator() { - return CHECK_DEREF(GetDocument()).GetResourceCoordinator(); - } - -+#if BUILDFLAG(ENABLE_REPORTING) - mojom::blink::ReportingServiceProxy* LocalFrame::GetReportingService() { - return mojo_handler_->ReportingService(); - } -+#endif - - mojom::blink::DevicePostureProvider* LocalFrame::GetDevicePostureProvider() { - return mojo_handler_->DevicePostureProvider(); -diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h ---- a/third_party/blink/renderer/core/frame/local_frame.h -+++ b/third_party/blink/renderer/core/frame/local_frame.h -@@ -37,6 +37,7 @@ - #include "base/time/time.h" - #include "base/unguessable_token.h" - #include "build/build_config.h" -+#include "net/net_buildflags.h" - #include "mojo/public/cpp/bindings/pending_associated_receiver.h" - #include "mojo/public/cpp/bindings/pending_receiver.h" - #include "net/storage_access_api/status.h" -@@ -668,7 +669,9 @@ class CORE_EXPORT LocalFrame final - return client_hints_preferences_; - } - -+#if BUILDFLAG(ENABLE_REPORTING) - mojom::blink::ReportingServiceProxy* GetReportingService(); -+#endif - mojom::blink::DevicePostureProvider* GetDevicePostureProvider(); - - // Returns the frame host ptr. The interface returned is backed by an -diff --git a/third_party/blink/renderer/core/frame/reporting_context.cc b/third_party/blink/renderer/core/frame/reporting_context.cc ---- a/third_party/blink/renderer/core/frame/reporting_context.cc -+++ b/third_party/blink/renderer/core/frame/reporting_context.cc -@@ -4,6 +4,7 @@ - - #include "third_party/blink/renderer/core/frame/reporting_context.h" - -+#include "net/net_buildflags.h" - #include "third_party/blink/public/platform/browser_interface_broker_proxy.h" - #include "third_party/blink/public/platform/platform.h" - #include "third_party/blink/public/platform/task_type.h" -@@ -59,7 +60,9 @@ const char ReportingContext::kSupplementName[] = "ReportingContext"; - ReportingContext::ReportingContext(ExecutionContext& context) - : Supplement(context), - execution_context_(context), -+#if BUILDFLAG(ENABLE_REPORTING) - reporting_service_(&context), -+#endif - receivers_(this, &context) {} - - // static -@@ -126,7 +129,9 @@ void ReportingContext::Trace(Visitor* visitor) const { - visitor->Trace(observers_); - visitor->Trace(report_buffer_); - visitor->Trace(execution_context_); -+#if BUILDFLAG(ENABLE_REPORTING) - visitor->Trace(reporting_service_); -+#endif - visitor->Trace(receivers_); - Supplement::Trace(visitor); - } -@@ -149,6 +154,7 @@ void ReportingContext::CountReport(Report* report) { - UseCounter::Count(execution_context_, feature); - } - -+#if BUILDFLAG(ENABLE_REPORTING) - const HeapMojoRemote& - ReportingContext::GetReportingService() const { - if (!reporting_service_.is_bound()) { -@@ -158,6 +164,7 @@ ReportingContext::GetReportingService() const { - } - return reporting_service_; - } -+#endif - - void ReportingContext::NotifyInternal(Report* report) { - if (!ShouldReportBeVisibleToObservers(report)) { -@@ -184,6 +191,7 @@ void ReportingContext::NotifyInternal(Report* report) { - - void ReportingContext::SendToReportingAPI(Report* report, - const String& endpoint) const { -+#if BUILDFLAG(ENABLE_REPORTING) - const String& type = report->type(); - if (!(type == ReportType::kCSPViolation || type == ReportType::kCSPHash || - type == ReportType::kDeprecation || -@@ -263,6 +271,7 @@ void ReportingContext::SendToReportingAPI(Report* report, - url, endpoint, body->featureId(), body->disposition(), body->message(), - body->sourceFile(), line_number, column_number); - } -+#endif - } - - } // namespace blink -diff --git a/third_party/blink/renderer/core/frame/reporting_context.h b/third_party/blink/renderer/core/frame/reporting_context.h ---- a/third_party/blink/renderer/core/frame/reporting_context.h -+++ b/third_party/blink/renderer/core/frame/reporting_context.h -@@ -5,6 +5,7 @@ - #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_REPORTING_CONTEXT_H_ - #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_REPORTING_CONTEXT_H_ - -+#include "net/net_buildflags.h" - #include "third_party/blink/public/mojom/frame/reporting_observer.mojom-blink.h" - #include "third_party/blink/public/mojom/reporting/reporting.mojom-blink.h" - #include "third_party/blink/renderer/core/core_export.h" -@@ -56,10 +57,10 @@ class CORE_EXPORT ReportingContext : public GarbageCollected, - private: - // Counts the use of a report type via UseCounter. - void CountReport(Report*); -- -+#if BUILDFLAG(ENABLE_REPORTING) - const HeapMojoRemote& - GetReportingService() const; -- -+#endif - void NotifyInternal(Report* report); - // Send |report| via the Reporting API to |endpoint|. - void SendToReportingAPI(Report* report, const String& endpoint) const; -@@ -71,8 +72,10 @@ class CORE_EXPORT ReportingContext : public GarbageCollected, - - // This is declared mutable so that the service endpoint can be cached by - // const methods. -+#if BUILDFLAG(ENABLE_REPORTING) - mutable HeapMojoRemote - reporting_service_; -+#endif - - // There might be up to two ReportingObservers stored here: one that is called - // from the CrossOriginEmbedderPolicyReporter and one that is called from the -diff --git a/third_party/blink/renderer/core/frame/reporting_observer.cc b/third_party/blink/renderer/core/frame/reporting_observer.cc ---- a/third_party/blink/renderer/core/frame/reporting_observer.cc -+++ b/third_party/blink/renderer/core/frame/reporting_observer.cc -@@ -61,8 +61,7 @@ void ReportingObserver::QueueReport(Report* report) { - } - - bool ReportingObserver::ObservedType(const String& type) { -- return !options_->hasTypesNonNull() || options_->typesNonNull().empty() || -- options_->typesNonNull().Find(type) != kNotFound; -+ return false; - } - - bool ReportingObserver::Buffered() { --- diff --git a/build/cromite_patches/Allow-building-without-supervised-users.patch b/build/cromite_patches/Allow-building-without-supervised-users.patch deleted file mode 100644 index 0e303a10..00000000 --- a/build/cromite_patches/Allow-building-without-supervised-users.patch +++ /dev/null @@ -1,247 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Mon, 21 Feb 2022 01:24:11 +0100 -Subject: Allow building without supervised users - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - chrome/android/BUILD.gn | 1 - - .../chrome/browser/feedback/ChromeFeedbackCollector.java | 1 - - chrome/browser/feedback/android/BUILD.gn | 2 -- - chrome/browser/prefs/chrome_pref_service_factory.cc | 2 +- - chrome/browser/profiles/profile_attributes_entry.cc | 2 +- - chrome/browser/profiles/profile_impl.cc | 5 +---- - chrome/browser/profiles/profile_manager.cc | 7 ------- - .../supervised_user/supervised_user_browser_utils.cc | 1 + - chrome/browser/ui/webui/managed_ui_handler.cc | 4 ---- - .../browser/ui/webui/management/management_ui_handler.cc | 4 ---- - .../core/browser/supervised_user_pref_store.cc | 1 + - .../core/browser/supervised_user_preferences.cc | 6 +++++- - .../core/browser/supervised_user_service.cc | 1 + - components/supervised_user/core/common/features.cc | 2 +- - extensions/browser/api/management/management_api.cc | 1 + - 15 files changed, 13 insertions(+), 27 deletions(-) - -diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn ---- a/chrome/android/BUILD.gn -+++ b/chrome/android/BUILD.gn -@@ -826,7 +826,6 @@ if (_is_default_toolchain) { - "//components/offline_pages/core:offline_page_model_enums_java", - "//components/sharing_message:sharing_dialog_type_generated_enum", - "//components/sharing_message:sharing_send_message_result_generated_enum", -- "//components/supervised_user/core/browser:supervised_user_utils_enum_javagen", - ] - - # From java_sources.gni. -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feedback/ChromeFeedbackCollector.java b/chrome/android/java/src/org/chromium/chrome/browser/feedback/ChromeFeedbackCollector.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/feedback/ChromeFeedbackCollector.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/feedback/ChromeFeedbackCollector.java -@@ -95,7 +95,6 @@ public class ChromeFeedbackCollector extends FeedbackCollectorSetManagedPolicies(policy_service, policy_connector); - factory->SetRecommendedPolicies(policy_service, policy_connector); -- if (supervised_user_settings) { -+ if (((false)) && supervised_user_settings) { - // supervised_user_prefs handles the case when content_filters_service is - // nullptr. It's simply not subscribing to empty service's notifications. - scoped_refptr supervised_user_prefs = -diff --git a/chrome/browser/profiles/profile_attributes_entry.cc b/chrome/browser/profiles/profile_attributes_entry.cc ---- a/chrome/browser/profiles/profile_attributes_entry.cc -+++ b/chrome/browser/profiles/profile_attributes_entry.cc -@@ -476,7 +476,7 @@ bool ProfileAttributesEntry::IsSigninRequired() const { - } - - std::string ProfileAttributesEntry::GetSupervisedUserId() const { -- return GetString(kSupervisedUserId); -+ return ""; - } - - bool ProfileAttributesEntry::IsEphemeral() const { -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 -@@ -683,10 +683,6 @@ void ProfileImpl::DoFinalInit(CreateMode create_mode) { - prefs->SetTime(prefs::kProfileCreationTime, path_creation_time_); - - pref_change_registrar_.Init(prefs); -- pref_change_registrar_.Add( -- prefs::kSupervisedUserId, -- base::BindRepeating(&ProfileImpl::UpdateSupervisedUserIdInStorage, -- base::Unretained(this))); - - // Changes in the profile avatar. - pref_change_registrar_.Add( -@@ -1632,6 +1628,7 @@ GURL ProfileImpl::GetHomePage() { - } - - void ProfileImpl::UpdateSupervisedUserIdInStorage() { -+ if ((true)) return; - ProfileManager* profile_manager = g_browser_process->profile_manager(); - ProfileAttributesEntry* entry = profile_manager->GetProfileAttributesStorage() - .GetProfileAttributesWithPath(GetPath()); -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 -@@ -1191,10 +1191,6 @@ void ProfileManager::InitProfileUserPrefs(Profile* profile) { - profile->GetPrefs()->SetString(prefs::kProfileName, profile_name); - } - -- if (!profile->GetPrefs()->HasPrefPath(prefs::kSupervisedUserId)) { -- profile->GetPrefs()->SetString(prefs::kSupervisedUserId, -- supervised_user_id); -- } - } - - void ProfileManager::RegisterTestingProfile(std::unique_ptr profile, -@@ -1956,9 +1952,6 @@ void ProfileManager::AddProfileToStorage(Profile* profile) { - init_params.icon_index = - profile->GetPrefs()->GetInteger(prefs::kProfileAvatarIndex); - -- init_params.supervised_user_id = -- profile->GetPrefs()->GetString(prefs::kSupervisedUserId); -- - #if BUILDFLAG(IS_CHROMEOS) - user_manager::User* user = - ash::ProfileHelper::Get()->GetUserByProfile(profile); -diff --git a/chrome/browser/supervised_user/supervised_user_browser_utils.cc b/chrome/browser/supervised_user/supervised_user_browser_utils.cc ---- a/chrome/browser/supervised_user/supervised_user_browser_utils.cc -+++ b/chrome/browser/supervised_user/supervised_user_browser_utils.cc -@@ -99,6 +99,7 @@ bool SupervisedUserCanSkipExtensionParentApprovals(const Profile* profile) { - } - - bool AreExtensionsPermissionsEnabled(Profile* profile) { -+ if ((true)) return false; - #if BUILDFLAG(ENABLE_EXTENSIONS_CORE) - return profile->IsChild(); - #else -diff --git a/chrome/browser/ui/webui/managed_ui_handler.cc b/chrome/browser/ui/webui/managed_ui_handler.cc ---- a/chrome/browser/ui/webui/managed_ui_handler.cc -+++ b/chrome/browser/ui/webui/managed_ui_handler.cc -@@ -89,10 +89,6 @@ void ManagedUIHandler::AddObservers() { - auto domain = static_cast(i); - policy_service->AddObserver(domain, this); - } -- -- pref_registrar_.Add(prefs::kSupervisedUserId, -- base::BindRepeating(&ManagedUIHandler::NotifyIfChanged, -- base::Unretained(this))); - } - - void ManagedUIHandler::RemoveObservers() { -diff --git a/chrome/browser/ui/webui/management/management_ui_handler.cc b/chrome/browser/ui/webui/management/management_ui_handler.cc ---- a/chrome/browser/ui/webui/management/management_ui_handler.cc -+++ b/chrome/browser/ui/webui/management/management_ui_handler.cc -@@ -623,10 +623,6 @@ bool ManagementUIHandler::managed() const { - - void ManagementUIHandler::RegisterPrefChange( - PrefChangeRegistrar& pref_registrar) { -- pref_registrar_.Add( -- prefs::kSupervisedUserId, -- base::BindRepeating(&ManagementUIHandler::UpdateManagedState, -- base::Unretained(this))); - } - - void ManagementUIHandler::UpdateManagedState() { -diff --git a/components/supervised_user/core/browser/supervised_user_pref_store.cc b/components/supervised_user/core/browser/supervised_user_pref_store.cc ---- a/components/supervised_user/core/browser/supervised_user_pref_store.cc -+++ b/components/supervised_user/core/browser/supervised_user_pref_store.cc -@@ -172,6 +172,7 @@ void SupervisedUserPrefStore::OnNewContentFiltersStateAvailable( - - void SupervisedUserPrefStore::OnNewSettingsAvailable( - const base::Value::Dict& settings) { -+ if ((true)) return; - std::unique_ptr old_prefs = std::move(prefs_); - prefs_ = std::make_unique(); - if (!settings.empty()) { -diff --git a/components/supervised_user/core/browser/supervised_user_preferences.cc b/components/supervised_user/core/browser/supervised_user_preferences.cc ---- a/components/supervised_user/core/browser/supervised_user_preferences.cc -+++ b/components/supervised_user/core/browser/supervised_user_preferences.cc -@@ -160,6 +160,10 @@ void RegisterProfilePrefs(PrefRegistrySimple* registry) { - } - - void EnableParentalControls(PrefService& pref_service) { -+ if ((true)) { -+ DisableParentalControls(pref_service); -+ return; -+ } - pref_service.SetString(prefs::kSupervisedUserId, - supervised_user::kChildAccountSUID); - #if BUILDFLAG(IS_CHROMEOS) -@@ -187,7 +191,7 @@ bool IsSafeSitesEnabled(const PrefService& pref_service) { - } - - bool IsSubjectToParentalControls(const PrefService& pref_service) { -- return pref_service.GetString(prefs::kSupervisedUserId) == kChildAccountSUID; -+ return false; - } - - bool IsGoogleSafeSearchEnforced(const PrefService& pref_service) { -diff --git a/components/supervised_user/core/browser/supervised_user_service.cc b/components/supervised_user/core/browser/supervised_user_service.cc ---- a/components/supervised_user/core/browser/supervised_user_service.cc -+++ b/components/supervised_user/core/browser/supervised_user_service.cc -@@ -248,6 +248,7 @@ SupervisedUserService::SupervisedUserService( - } - - void SupervisedUserService::SetSettingsServiceActive(bool active) { -+ active = false; - settings_service_->SetActive(active); - - // Trigger a sync reconfig to enable/disable the right SU data types. -diff --git a/components/supervised_user/core/common/features.cc b/components/supervised_user/core/common/features.cc ---- a/components/supervised_user/core/common/features.cc -+++ b/components/supervised_user/core/common/features.cc -@@ -30,7 +30,6 @@ BASE_FEATURE(kAllowSubframeLocalWebApprovals, - #else - base::FEATURE_DISABLED_BY_DEFAULT); - #endif -- - #if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ - BUILDFLAG(IS_WIN) - const int kLocalWebApprovalBottomSheetLoadTimeoutDefaultValueMs = 5000; -@@ -151,4 +150,5 @@ bool ClassifyUrlWithoutCredentialsForLocalSupervision() { - - #endif - -+SET_CROMITE_FEATURE_DISABLED(kLocalWebApprovals); - } // namespace supervised_user -diff --git a/extensions/browser/api/management/management_api.cc b/extensions/browser/api/management/management_api.cc ---- a/extensions/browser/api/management/management_api.cc -+++ b/extensions/browser/api/management/management_api.cc -@@ -324,6 +324,7 @@ void AddExtensionInfo(const Extension* source_extension, - } - - bool PlatformSupportsApprovalFlowForExtensions() { -+ if ((true)) return false; - #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_LINUX) || \ - BUILDFLAG(IS_WIN) - return true; --- diff --git a/build/cromite_patches/Allow-playing-audio-in-background.patch b/build/cromite_patches/Allow-playing-audio-in-background.patch deleted file mode 100644 index 1967106e..00000000 --- a/build/cromite_patches/Allow-playing-audio-in-background.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: AlexeyBarabash -Date: Thu, 2 Nov 2017 18:21:16 +0200 -Subject: Allow playing audio in background - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../renderer/platform/media/web_media_player_impl.cc | 11 ++++++++++- - .../renderer/platform/media/web_media_player_impl.h | 3 +++ - 2 files changed, 13 insertions(+), 1 deletion(-) - -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 -@@ -1309,6 +1309,12 @@ bool WebMediaPlayerImpl::HasAudio() const { - return pipeline_metadata_.has_audio; - } - -+bool WebMediaPlayerImpl::HasVideoNonEmptySize() const { -+ DCHECK(main_task_runner_->BelongsToCurrentThread()); -+ -+ return pipeline_metadata_.has_video && pipeline_metadata_.natural_size.width() != 0 && pipeline_metadata_.natural_size.height() != 0; -+} -+ - void WebMediaPlayerImpl::EnabledAudioTracksChanged( - std::optional enabled_track_id) { - DCHECK(main_task_runner_->BelongsToCurrentThread()); -@@ -3645,7 +3651,10 @@ bool WebMediaPlayerImpl::ShouldPausePlaybackWhenHidden() const { - - const bool preserve_audio = HasUnmutedAudio() || audio_source_provider_->IsAudioBeingCaptured(); - // Audio only stream is allowed to play when in background. -- if (!HasVideo() && preserve_audio) -+ //pipeline_metadata_.has_video is true for MediaPlayerRenderer, -+ //see media/base/pipeline_metadata.h. This is a workaround to allow audio -+ //streams be played in background. -+ if (!HasVideoNonEmptySize() && preserve_audio) - return false; - - // Video PiP is the only exception when background video playback is disabled. -diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.h b/third_party/blink/renderer/platform/media/web_media_player_impl.h ---- a/third_party/blink/renderer/platform/media/web_media_player_impl.h -+++ b/third_party/blink/renderer/platform/media/web_media_player_impl.h -@@ -212,6 +212,9 @@ class PLATFORM_EXPORT WebMediaPlayerImpl - bool HasVideo() const override; - bool HasAudio() const override; - -+ // True is has video and it's frame size is not zero -+ bool HasVideoNonEmptySize() const; -+ - void EnabledAudioTracksChanged( - std::optional enabled_track_id) override; - void SelectedVideoTrackChanged( --- diff --git a/build/cromite_patches/Always-use-new-tab-page-for-default-home-page.patch b/build/cromite_patches/Always-use-new-tab-page-for-default-home-page.patch deleted file mode 100644 index 336a8f39..00000000 --- a/build/cromite_patches/Always-use-new-tab-page-for-default-home-page.patch +++ /dev/null @@ -1,96 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Wed, 27 Jun 2018 11:02:38 +0200 -Subject: Always use new tab page for default home page - -Ignore any partner-provided home page. - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../org/chromium/chrome/browser/homepage/HomepageManager.java | 4 ---- - .../chrome/browser/new_tab_url/DseNewTabUrlManager.java | 2 +- - .../partnerbookmarks/PartnerBookmarksProviderIterator.java | 1 + - .../partnercustomizations/PartnerBrowserCustomizations.java | 2 +- - .../org/chromium/components/search_engines/TemplateUrl.java | 1 + - .../search_engines/android/template_url_service_android.cc | 1 + - .../always-use-new-tab-page-for-default-home-page.inc | 1 + - 7 files changed, 6 insertions(+), 6 deletions(-) - create mode 100755 cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/always-use-new-tab-page-for-default-home-page.inc - -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 -@@ -159,10 +159,6 @@ public class HomepageManager - * tab page if the homepage button is force enabled via flag. - */ - public GURL getDefaultHomepageGurl() { -- if (PartnerBrowserCustomizations.getInstance().isHomepageProviderAvailableAndEnabled()) { -- return assumeNonNull(PartnerBrowserCustomizations.getInstance().getHomePageUrl()); -- } -- - String homepagePartnerDefaultGurlSerialized = - ChromeSharedPreferences.getInstance() - .readString( -diff --git a/chrome/android/java/src/org/chromium/chrome/browser/new_tab_url/DseNewTabUrlManager.java b/chrome/android/java/src/org/chromium/chrome/browser/new_tab_url/DseNewTabUrlManager.java ---- a/chrome/android/java/src/org/chromium/chrome/browser/new_tab_url/DseNewTabUrlManager.java -+++ b/chrome/android/java/src/org/chromium/chrome/browser/new_tab_url/DseNewTabUrlManager.java -@@ -59,7 +59,7 @@ public class DseNewTabUrlManager { - - /** Returns whether the feature NewTabSearchEngineUrlAndroid is enabled. */ - public static boolean isNewTabSearchEngineUrlAndroidEnabled() { -- return true; -+ return false; - } - - /** -diff --git a/chrome/browser/partnerbookmarks/android/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksProviderIterator.java b/chrome/browser/partnerbookmarks/android/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksProviderIterator.java ---- a/chrome/browser/partnerbookmarks/android/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksProviderIterator.java -+++ b/chrome/browser/partnerbookmarks/android/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksProviderIterator.java -@@ -70,6 +70,7 @@ public class PartnerBookmarksProviderIterator implements PartnerBookmark.Bookmar - new AsyncTask<@Nullable Cursor>() { - @Override - protected @Nullable Cursor doInBackground() { -+ if ((true)) return null; - try { - return ContextUtils.getApplicationContext() - .getContentResolver() -diff --git a/chrome/browser/partnercustomizations/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java b/chrome/browser/partnercustomizations/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java ---- a/chrome/browser/partnercustomizations/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java -+++ b/chrome/browser/partnercustomizations/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java -@@ -213,7 +213,7 @@ public class PartnerBrowserCustomizations { - & ApplicationInfo.FLAG_SYSTEM) - == 1 - || !VersionInfo.isStableBuild(); -- if (!systemOrPreStable) { -+ if ((true)) { - // Only allow partner customization if this browser is a system - // package, or is in pre-stable channels. - return null; -diff --git a/components/search_engines/android/java/src/org/chromium/components/search_engines/TemplateUrl.java b/components/search_engines/android/java/src/org/chromium/components/search_engines/TemplateUrl.java ---- a/components/search_engines/android/java/src/org/chromium/components/search_engines/TemplateUrl.java -+++ b/components/search_engines/android/java/src/org/chromium/components/search_engines/TemplateUrl.java -@@ -88,6 +88,7 @@ public class TemplateUrl { - * prepopulated_engines.json. - */ - public String getNewTabURL() { -+ if ((true)) return null; - return TemplateUrlJni.get().getNewTabURL(mTemplateUrlPtr); - } - -diff --git a/components/search_engines/android/template_url_service_android.cc b/components/search_engines/android/template_url_service_android.cc ---- a/components/search_engines/android/template_url_service_android.cc -+++ b/components/search_engines/android/template_url_service_android.cc -@@ -400,6 +400,7 @@ jboolean TemplateUrlServiceAndroid::SetPlayAPISearchEngine( - jimage_translate_source_language_param_key, - const base::android::JavaParamRef& - jimage_translate_target_language_param_key) { -+ if ((true)) return false; - // The function is scheduled to run only when the service is loaded, see - // `TemplateUrlService#runWhenLoaded()`. - CHECK(template_url_service_->loaded()); -diff --git a/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/always-use-new-tab-page-for-default-home-page.inc b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/always-use-new-tab-page-for-default-home-page.inc -new file mode 100755 ---- /dev/null -+++ b/cromite_flags/chrome/browser/flags/android/chrome_feature_list_cc/always-use-new-tab-page-for-default-home-page.inc -@@ -0,0 +1 @@ -+SET_CROMITE_FEATURE_DISABLED(kPartnerCustomizationsUma); --- diff --git a/build/cromite_patches/AudioBuffer-AnalyserNode-fp-mitigations.patch b/build/cromite_patches/AudioBuffer-AnalyserNode-fp-mitigations.patch deleted file mode 100644 index 5b7a36ba..00000000 --- a/build/cromite_patches/AudioBuffer-AnalyserNode-fp-mitigations.patch +++ /dev/null @@ -1,233 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Sun, 25 Mar 2018 21:49:37 +0200 -Subject: AudioBuffer, AnalyserNode: fp mitigations - -Truncate base latency precision to two digits - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../AudioBuffer-AnalyserNode-fp-mitigations.inc | 8 ++++++++ - .../AudioBuffer-AnalyserNode-fp-mitigations.inc | 3 +++ - .../AudioBuffer-AnalyserNode-fp-mitigations.inc | 1 + - .../renderer/modules/webaudio/audio_buffer.cc | 14 ++++++++++++++ - .../blink/renderer/modules/webaudio/audio_buffer.h | 2 ++ - .../renderer/modules/webaudio/audio_context.cc | 5 ++++- - .../modules/webaudio/base_audio_context.cc | 12 ++++++++++++ - .../renderer/modules/webaudio/base_audio_context.h | 2 ++ - .../modules/webaudio/offline_audio_context.cc | 1 + - .../renderer/modules/webaudio/realtime_analyser.cc | 13 ++++++++++--- - .../platform/runtime_enabled_features.json5 | 5 ++--- - 11 files changed, 59 insertions(+), 7 deletions(-) - create mode 100644 cromite_flags/chrome/browser/about_flags_cc/AudioBuffer-AnalyserNode-fp-mitigations.inc - create mode 100644 cromite_flags/third_party/blink/common/features_cc/AudioBuffer-AnalyserNode-fp-mitigations.inc - create mode 100644 cromite_flags/third_party/blink/common/features_h/AudioBuffer-AnalyserNode-fp-mitigations.inc - -diff --git a/cromite_flags/chrome/browser/about_flags_cc/AudioBuffer-AnalyserNode-fp-mitigations.inc b/cromite_flags/chrome/browser/about_flags_cc/AudioBuffer-AnalyserNode-fp-mitigations.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/chrome/browser/about_flags_cc/AudioBuffer-AnalyserNode-fp-mitigations.inc -@@ -0,0 +1,8 @@ -+#ifdef FLAG_SECTION -+ -+ {"fingerprinting-audio-context-data-noise", -+ "Enable Audio Context fingerprint deception", -+ "Scale the output values of rendered data with a randomly selected factor.", kOsAll, -+ FEATURE_VALUE_TYPE(blink::features::kAudioContextShuffleEnabled)}, -+ -+#endif -diff --git a/cromite_flags/third_party/blink/common/features_cc/AudioBuffer-AnalyserNode-fp-mitigations.inc b/cromite_flags/third_party/blink/common/features_cc/AudioBuffer-AnalyserNode-fp-mitigations.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/third_party/blink/common/features_cc/AudioBuffer-AnalyserNode-fp-mitigations.inc -@@ -0,0 +1,3 @@ -+CROMITE_FEATURE(kAudioContextShuffleEnabled, -+ "AudioContextShuffleEnabled", -+ base::FEATURE_ENABLED_BY_DEFAULT); -diff --git a/cromite_flags/third_party/blink/common/features_h/AudioBuffer-AnalyserNode-fp-mitigations.inc b/cromite_flags/third_party/blink/common/features_h/AudioBuffer-AnalyserNode-fp-mitigations.inc -new file mode 100644 ---- /dev/null -+++ b/cromite_flags/third_party/blink/common/features_h/AudioBuffer-AnalyserNode-fp-mitigations.inc -@@ -0,0 +1 @@ -+BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kAudioContextShuffleEnabled); -diff --git a/third_party/blink/renderer/modules/webaudio/audio_buffer.cc b/third_party/blink/renderer/modules/webaudio/audio_buffer.cc ---- a/third_party/blink/renderer/modules/webaudio/audio_buffer.cc -+++ b/third_party/blink/renderer/modules/webaudio/audio_buffer.cc -@@ -200,6 +200,20 @@ AudioBuffer::AudioBuffer(AudioBus* bus) - } - } - -+void AudioBuffer::ShuffleAudioData() { -+ for (unsigned i = 0; i < channels_.size(); ++i) { -+ if (NotShared array = getChannelData(i)) { -+ size_t len = array->length(); -+ if (len > 0) { -+ base::span destination = array->AsSpan(); -+ for (unsigned j = 0; j < len; ++j) { -+ destination[j] = BaseAudioContext::ShuffleAudioData(destination[j], j); -+ } -+ } -+ } -+ } -+} -+ - NotShared AudioBuffer::getChannelData( - unsigned channel_index, - ExceptionState& exception_state) { -diff --git a/third_party/blink/renderer/modules/webaudio/audio_buffer.h b/third_party/blink/renderer/modules/webaudio/audio_buffer.h ---- a/third_party/blink/renderer/modules/webaudio/audio_buffer.h -+++ b/third_party/blink/renderer/modules/webaudio/audio_buffer.h -@@ -116,6 +116,8 @@ class MODULES_EXPORT AudioBuffer final : public ScriptWrappable { - - std::unique_ptr CreateSharedAudioBuffer(); - -+ void ShuffleAudioData(); -+ - private: - static DOMFloat32Array* CreateFloat32ArrayOrNull( - uint32_t length, -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 -@@ -17,6 +17,7 @@ - #include "third_party/blink/public/common/features.h" - #include "third_party/blink/public/common/mediastream/media_devices.h" - #include "third_party/blink/public/platform/browser_interface_broker_proxy.h" -+#include "third_party/blink/public/common/features.h" - #include "third_party/blink/public/platform/modules/webrtc/webrtc_logging.h" - #include "third_party/blink/public/platform/web_audio_latency_hint.h" - #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" -@@ -850,7 +851,9 @@ double AudioContext::baseLatency() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(main_thread_sequence_checker_); - DCHECK(destination()); - -- return base_latency_; -+ // remove precision past two decimal digits -+ int l = base_latency_ * 100; -+ return double(l)/100; - } - - double AudioContext::outputLatency() const { -diff --git a/third_party/blink/renderer/modules/webaudio/base_audio_context.cc b/third_party/blink/renderer/modules/webaudio/base_audio_context.cc ---- a/third_party/blink/renderer/modules/webaudio/base_audio_context.cc -+++ b/third_party/blink/renderer/modules/webaudio/base_audio_context.cc -@@ -29,6 +29,7 @@ - - #include "base/metrics/histogram_functions.h" - #include "build/build_config.h" -+#include "third_party/blink/public/common/features.h" - #include "third_party/blink/public/mojom/devtools/console_message.mojom-blink.h" - #include "third_party/blink/public/mojom/frame/lifecycle.mojom-shared.h" - #include "third_party/blink/public/platform/platform.h" -@@ -774,6 +775,17 @@ LocalDOMWindow* BaseAudioContext::GetWindow() const { - return To(GetExecutionContext()); - } - -+/*static*/ -+float BaseAudioContext::ShuffleAudioData(float data, unsigned index) { -+ if (base::FeatureList::IsEnabled(features::kAudioContextShuffleEnabled)) { -+ float rnd = 1.0f + -+ (base::RandDouble() / 10000.0) * -+ (base::RandInt(0,10) > 5 ? 1.f : -1.f); -+ return data * rnd; -+ } -+ return data; -+} -+ - void BaseAudioContext::NotifySourceNodeStartedProcessing(AudioNode* node) { - DCHECK(IsMainThread()); - DeferredTaskHandler::GraphAutoLocker locker(this); -diff --git a/third_party/blink/renderer/modules/webaudio/base_audio_context.h b/third_party/blink/renderer/modules/webaudio/base_audio_context.h ---- a/third_party/blink/renderer/modules/webaudio/base_audio_context.h -+++ b/third_party/blink/renderer/modules/webaudio/base_audio_context.h -@@ -327,6 +327,8 @@ class MODULES_EXPORT BaseAudioContext - // if the execution context does not exist. - bool CheckExecutionContextAndThrowIfNecessary(ExceptionState&); - -+ static float ShuffleAudioData(float data, unsigned index); -+ - protected: - enum class ContextType { kRealtimeContext, kOfflineContext }; - -diff --git a/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc b/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc ---- a/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc -+++ b/third_party/blink/renderer/modules/webaudio/offline_audio_context.cc -@@ -374,6 +374,7 @@ void OfflineAudioContext::FireCompletionEvent() { - if (!rendered_buffer) { - return; - } -+ rendered_buffer->ShuffleAudioData(); - - // Call the offline rendering completion event listener and resolve the - // promise too. -diff --git a/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc b/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc ---- a/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc -+++ b/third_party/blink/renderer/modules/webaudio/realtime_analyser.cc -@@ -32,6 +32,7 @@ - #include - - #include "base/compiler_specific.h" -+#include "third_party/blink/renderer/modules/webaudio/base_audio_context.h" - #include "third_party/blink/renderer/platform/audio/audio_bus.h" - #include "third_party/blink/renderer/platform/audio/audio_utilities.h" - #include "third_party/blink/renderer/platform/audio/vector_math.h" -@@ -117,7 +118,8 @@ void RealtimeAnalyser::GetFloatFrequencyData(DOMFloat32Array* destination_array, - for (unsigned i = 0; i < len; ++i) { - const float linear_value = UNSAFE_TODO(source[i]); - const double db_mag = audio_utilities::LinearToDecibels(linear_value); -- UNSAFE_TODO(destination[i]) = static_cast(db_mag); -+ auto v = static_cast(db_mag); -+ UNSAFE_TODO(destination[i]) = BaseAudioContext::ShuffleAudioData(v, i); - } - } - } -@@ -155,9 +157,11 @@ void RealtimeAnalyser::GetByteFrequencyData(DOMUint8Array* destination_array, - - // The range m_minDecibels to m_maxDecibels will be scaled to byte values - // from 0 to UCHAR_MAX. -- const double scaled_value = -+ double scaled_value = - UCHAR_MAX * (db_mag - min_decibels) * range_scale_factor; - -+ scaled_value = BaseAudioContext::ShuffleAudioData(scaled_value, i); -+ - // Clip to valid range. - UNSAFE_TODO(destination[i]) = - static_cast(ClampTo(scaled_value, 0, UCHAR_MAX)); -@@ -188,6 +192,7 @@ void RealtimeAnalyser::GetFloatTimeDomainData( - input_buffer[(i + write_index - fft_size + kInputBufferSize) % - kInputBufferSize]); - -+ value = BaseAudioContext::ShuffleAudioData(value, i); - UNSAFE_TODO(destination[i]) = value; - } - } -@@ -211,10 +216,12 @@ void RealtimeAnalyser::GetByteTimeDomainData(DOMUint8Array* destination_array) { - - for (unsigned i = 0; i < len; ++i) { - // Buffer access is protected due to modulo operation. -- const float value = UNSAFE_TODO( -+ float value = UNSAFE_TODO( - input_buffer[(i + write_index - fft_size + kInputBufferSize) % - kInputBufferSize]); - -+ value = BaseAudioContext::ShuffleAudioData(value, i); -+ - // Scale from nominal -1 -> +1 to unsigned byte. - const double scaled_value = 128 * (value + 1); - -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 -@@ -608,9 +608,8 @@ - { - // AudioContext.playoutStats interface. - // https://chromestatus.com/feature/5172818344148992 -- name: "AudioContextPlayoutStats", -- origin_trial_feature_name: "AudioContextPlayoutStats", -- status: "experimental", -+ name: "AudioContextPlayoutStats", // keep AudioContextPlayoutStats -+ status: "experimental", // experimental - }, - { - name: "AudioContextSetSinkId", --- diff --git a/build/cromite_patches/Battery-API-return-nothing.patch b/build/cromite_patches/Battery-API-return-nothing.patch deleted file mode 100644 index 9e074294..00000000 --- a/build/cromite_patches/Battery-API-return-nothing.patch +++ /dev/null @@ -1,66 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Thu, 22 Mar 2018 22:11:57 +0100 -Subject: Battery API: return nothing - -Include @thestinger's fix for correct charging/unknown values - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../modules/battery/battery_manager.cc | 26 +++---------------- - 1 file changed, 4 insertions(+), 22 deletions(-) - -diff --git a/third_party/blink/renderer/modules/battery/battery_manager.cc b/third_party/blink/renderer/modules/battery/battery_manager.cc ---- a/third_party/blink/renderer/modules/battery/battery_manager.cc -+++ b/third_party/blink/renderer/modules/battery/battery_manager.cc -@@ -80,46 +80,28 @@ ScriptPromise BatteryManager::StartRequest( - } - - bool BatteryManager::charging() { -- return battery_status_.Charging(); -+ return true; - } - - double BatteryManager::chargingTime() { -- return battery_status_.charging_time().InSecondsF(); -+ return 0.0; - } - - double BatteryManager::dischargingTime() { -- return battery_status_.discharging_time().InSecondsF(); -+ return std::numeric_limits::infinity(); - } - - double BatteryManager::level() { -- return battery_status_.Level(); -+ return 1.0; - } - - void BatteryManager::DidUpdateData() { - DCHECK(battery_property_); - -- BatteryStatus old_status = battery_status_; -- battery_status_ = *battery_dispatcher_->LatestData(); -- - if (battery_property_->GetState() == BatteryProperty::kPending) { - battery_property_->Resolve(this); - return; - } -- -- DCHECK(GetExecutionContext()); -- if (GetExecutionContext()->IsContextPaused() || -- GetExecutionContext()->IsContextDestroyed()) { -- return; -- } -- -- if (battery_status_.Charging() != old_status.Charging()) -- DispatchEvent(*Event::Create(event_type_names::kChargingchange)); -- if (battery_status_.charging_time() != old_status.charging_time()) -- DispatchEvent(*Event::Create(event_type_names::kChargingtimechange)); -- if (battery_status_.discharging_time() != old_status.discharging_time()) -- DispatchEvent(*Event::Create(event_type_names::kDischargingtimechange)); -- if (battery_status_.Level() != old_status.Level()) -- DispatchEvent(*Event::Create(event_type_names::kLevelchange)); - } - - void BatteryManager::RegisterWithDispatcher() { --- diff --git a/build/cromite_patches/Block-qjz9zk-or-trk-requests.patch b/build/cromite_patches/Block-qjz9zk-or-trk-requests.patch deleted file mode 100644 index c7d34b52..00000000 --- a/build/cromite_patches/Block-qjz9zk-or-trk-requests.patch +++ /dev/null @@ -1,277 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Wed, 30 Oct 2019 11:50:13 +0100 -Subject: Block 'qjz9zk' or 'trk:' requests - -An info bar is displayed unless the --disable-trkbar command-line flag or the chrome://flag option is used. -This patch is based on Iridium's 'net: add "trk:" scheme and help identify URLs being retrieved' - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../chrome_autocomplete_scheme_classifier.cc | 1 + - chrome/browser/history/history_utils.cc | 1 + - chrome/browser/ui/singleton_tabs.cc | 5 ++++ - .../omnibox/browser/autocomplete_input.cc | 8 ++++- - components/url_formatter/url_fixer.cc | 4 +++ - .../child_process_security_policy_impl.cc | 1 + - net/BUILD.gn | 2 ++ - net/url_request/trk_protocol_handler.cc | 25 ++++++++++++++++ - net/url_request/trk_protocol_handler.h | 30 +++++++++++++++++++ - net/url_request/url_request.cc | 8 +++++ - .../url_request_context_builder.cc | 3 ++ - url/url_constants.h | 1 + - url/url_util.cc | 2 ++ - 13 files changed, 90 insertions(+), 1 deletion(-) - create mode 100644 net/url_request/trk_protocol_handler.cc - create mode 100644 net/url_request/trk_protocol_handler.h - -diff --git a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc ---- a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -+++ b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc -@@ -72,6 +72,7 @@ ChromeAutocompleteSchemeClassifier::GetInputTypeForScheme( - if (base::IsStringASCII(scheme) && - (ProfileIOData::IsHandledProtocol(scheme) || - base::EqualsCaseInsensitiveASCII(scheme, content::kViewSourceScheme) || -+ base::EqualsCaseInsensitiveASCII(scheme, url::kTraceScheme) || - base::EqualsCaseInsensitiveASCII(scheme, url::kJavaScriptScheme) || - base::EqualsCaseInsensitiveASCII(scheme, url::kDataScheme))) { - return metrics::OmniboxInputType::URL; -diff --git a/chrome/browser/history/history_utils.cc b/chrome/browser/history/history_utils.cc ---- a/chrome/browser/history/history_utils.cc -+++ b/chrome/browser/history/history_utils.cc -@@ -22,6 +22,7 @@ bool CanAddURLToHistory(const GURL& url) { - url.SchemeIs(content::kChromeUIScheme) || - url.SchemeIs(content::kChromeUIUntrustedScheme) || - url.SchemeIs(content::kViewSourceScheme) || -+ url.SchemeIs(url::kTraceScheme) || - url.SchemeIs(chrome::kChromeNativeScheme) || - url.SchemeIs(chrome::kChromeSearchScheme) || - url.SchemeIs(dom_distiller::kDomDistillerScheme)) -diff --git a/chrome/browser/ui/singleton_tabs.cc b/chrome/browser/ui/singleton_tabs.cc ---- a/chrome/browser/ui/singleton_tabs.cc -+++ b/chrome/browser/ui/singleton_tabs.cc -@@ -141,6 +141,11 @@ int GetIndexOfExistingTab(BrowserWindowInterface* browser, - continue; - } - -+ // trk: URLs must not be rewritten -+ if (tab_url.SchemeIs(url::kTraceScheme)) { -+ continue; -+ } -+ - GURL rewritten_tab_url = tab_url; - content::BrowserURLHandler::GetInstance()->RewriteURLIfNecessary( - &rewritten_tab_url, browser->GetProfile()); -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 -@@ -92,10 +92,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; -+ -+ if (url::FindAndCompareScheme(utf8_input, url::kTraceScheme, &view_source_scheme)) { -+ return false; -+ } - if (url::FindAndCompareScheme(utf8_input, kViewSourceScheme, - &view_source_scheme)) { - utf8_input.erase(0, view_source_scheme.end() + 1); - } -+ - return url::FindAndCompareScheme(utf8_input, scheme, nullptr); - } - -@@ -578,7 +583,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::EqualsCaseInsensitiveASCII(scheme_str, kViewSourceScheme) || -- base::EqualsCaseInsensitiveASCII(scheme_str, url::kBlobScheme)) && -+ base::EqualsCaseInsensitiveASCII(scheme_str, url::kBlobScheme) || -+ base::EqualsCaseInsensitiveASCII(scheme_str, url::kTraceScheme)) && - (static_cast(text.length()) > after_scheme_and_colon)) { - // Obtain the URL prefixed by view-source or blob and parse it. - std::u16string real_url(text.substr(after_scheme_and_colon)); -diff --git a/components/url_formatter/url_fixer.cc b/components/url_formatter/url_fixer.cc ---- a/components/url_formatter/url_fixer.cc -+++ b/components/url_formatter/url_fixer.cc -@@ -598,6 +598,10 @@ GURL FixupURLInternal(const std::string& text, - } - } - -+ if (scheme == url::kTraceScheme) { -+ return GURL(); -+ } -+ - // We handle the file scheme separately. - if (scheme == url::kFileScheme) { - return GURL(parts.scheme.is_valid() ? text : FixupPath(text)); -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 -@@ -969,6 +969,7 @@ ChildProcessSecurityPolicyImpl::ChildProcessSecurityPolicyImpl() - RegisterPseudoScheme(url::kJavaScriptScheme); - RegisterPseudoScheme(kViewSourceScheme); - RegisterPseudoScheme(kGoogleChromeScheme); -+ RegisterWebSafeScheme(url::kTraceScheme); - } - - ChildProcessSecurityPolicyImpl::~ChildProcessSecurityPolicyImpl() = default; -diff --git a/net/BUILD.gn b/net/BUILD.gn ---- a/net/BUILD.gn -+++ b/net/BUILD.gn -@@ -1142,6 +1142,8 @@ component("net") { - "url_request/url_request_http_job.cc", - "url_request/url_request_http_job.h", - "url_request/url_request_interceptor.cc", -+ "url_request/trk_protocol_handler.cc", -+ "url_request/trk_protocol_handler.h", - "url_request/url_request_interceptor.h", - "url_request/url_request_job.cc", - "url_request/url_request_job.h", -diff --git a/net/url_request/trk_protocol_handler.cc b/net/url_request/trk_protocol_handler.cc -new file mode 100644 ---- /dev/null -+++ b/net/url_request/trk_protocol_handler.cc -@@ -0,0 +1,25 @@ -+// Copyright (c) 2018 The ungoogled-chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#include "net/url_request/trk_protocol_handler.h" -+ -+#include "base/logging.h" -+#include "net/base/net_errors.h" -+#include "net/url_request/url_request_error_job.h" -+ -+namespace net { -+ -+TrkProtocolHandler::TrkProtocolHandler() = default; -+ -+std::unique_ptr TrkProtocolHandler::CreateJob( -+ URLRequest* request) const { -+ LOG(ERROR) << "Blocked URL in TrkProtocolHandler: " << request->original_url(); -+ return std::make_unique(request, ERR_BLOCKED_BY_CLIENT); -+} -+ -+bool TrkProtocolHandler::IsSafeRedirectTarget(const GURL& location) const { -+ return true; -+} -+ -+} // namespace net -diff --git a/net/url_request/trk_protocol_handler.h b/net/url_request/trk_protocol_handler.h -new file mode 100644 ---- /dev/null -+++ b/net/url_request/trk_protocol_handler.h -@@ -0,0 +1,30 @@ -+// Copyright (c) 2018 The ungoogled-chromium Authors. All rights reserved. -+// Use of this source code is governed by a BSD-style license that can be -+// found in the LICENSE file. -+ -+#ifndef NET_URL_REQUEST_TRK_PROTOCOL_HANDLER_H_ -+#define NET_URL_REQUEST_TRK_PROTOCOL_HANDLER_H_ -+ -+#include "base/compiler_specific.h" -+#include "net/base/net_export.h" -+#include "net/url_request/url_request_job_factory.h" -+ -+namespace net { -+ -+class URLRequestJob; -+ -+// Implements a ProtocolHandler for Trk jobs. -+class NET_EXPORT TrkProtocolHandler -+ : public URLRequestJobFactory::ProtocolHandler { -+ public: -+ TrkProtocolHandler(const TrkProtocolHandler&) = delete; -+ TrkProtocolHandler& operator=(const TrkProtocolHandler&) = delete; -+ -+ TrkProtocolHandler(); -+ std::unique_ptr CreateJob(URLRequest* request) const override; -+ bool IsSafeRedirectTarget(const GURL& location) const override; -+}; -+ -+} // namespace net -+ -+#endif // NET_URL_REQUEST_TRK_PROTOCOL_HANDLER_H_ -diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc ---- a/net/url_request/url_request.cc -+++ b/net/url_request/url_request.cc -@@ -15,6 +15,7 @@ - #include "base/notreached.h" - #include "base/rand_util.h" - #include "base/strings/utf_string_conversions.h" -+#include "base/strings/string_util.h" - #include "base/synchronization/lock.h" - #include "base/task/single_thread_task_runner.h" - #include "base/types/optional_util.h" -@@ -55,6 +56,7 @@ - #include "net/url_request/url_request_redirect_job.h" - #include "url/gurl.h" - #include "url/origin.h" -+#include "url/url_constants.h" - - namespace net { - -@@ -650,6 +652,12 @@ URLRequest::URLRequest(base::PassKey pass_key, - // Sanity check out environment. - DCHECK(base::SingleThreadTaskRunner::HasCurrentDefault()); - -+ if (!url.SchemeIs(url::kTraceScheme) && -+ base::EndsWith(url.host(), "qjz9zk", base::CompareCase::INSENSITIVE_ASCII)) { -+ LOG(ERROR) << "Block URL in URLRequest: " << url; -+ url_chain_[0] = GURL(url::kTraceScheme + (":" + url.possibly_invalid_spec())); -+ } -+ - context->url_requests()->insert(this); - net_log_.BeginEvent(NetLogEventType::REQUEST_ALIVE, - [&](NetLogCaptureMode capture_mode) { -diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc ---- a/net/url_request/url_request_context_builder.cc -+++ b/net/url_request/url_request_context_builder.cc -@@ -55,6 +55,7 @@ - #include "net/socket/network_binding_client_socket_factory.h" - #include "net/ssl/ssl_config_service_defaults.h" - #include "net/url_request/static_http_user_agent_settings.h" -+#include "net/url_request/trk_protocol_handler.h" - #include "net/url_request/url_request_context.h" - #include "net/url_request/url_request_job_factory.h" - #include "url/url_constants.h" -@@ -619,6 +620,8 @@ std::unique_ptr URLRequestContextBuilder::Build() { - job_factory->SetProtocolHandler(scheme_handler.first, - std::move(scheme_handler.second)); - } -+ job_factory->SetProtocolHandler(url::kTraceScheme, -+ std::make_unique()); - protocol_handlers_.clear(); - - context->set_job_factory(std::move(job_factory)); -diff --git a/url/url_constants.h b/url/url_constants.h ---- a/url/url_constants.h -+++ b/url/url_constants.h -@@ -34,6 +34,7 @@ inline constexpr char16_t kDataScheme16[] = u"data"; - inline constexpr char kDrivefsScheme[] = "drivefs"; - inline constexpr char kFileScheme[] = "file"; - inline constexpr char16_t kFileScheme16[] = u"file"; -+inline constexpr char kTraceScheme[] = "trk"; - inline constexpr char kFileSystemScheme[] = "filesystem"; - inline constexpr char16_t kFileSystemScheme16[] = u"filesystem"; - inline constexpr char kFtpScheme[] = "ftp"; -diff --git a/url/url_util.cc b/url/url_util.cc ---- a/url/url_util.cc -+++ b/url/url_util.cc -@@ -54,6 +54,7 @@ struct SchemeRegistry { - std::vector standard_schemes = { - {kHttpsScheme, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, - {kHttpScheme, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, -+ {kTraceScheme, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, - // Yes, file URLs can have a hostname, so file URLs should be handled as - // "standard". File URLs never have a port as specified by the SchemeType - // field. Unlike other SCHEME_WITH_HOST schemes, the 'host' in a file -@@ -99,6 +100,7 @@ struct SchemeRegistry { - kAboutScheme, - kJavaScriptScheme, - kDataScheme, -+ kTraceScheme, - }; - - // Schemes that can be sent CORS requests. --- diff --git a/build/cromite_patches/Bookmarks-select-all-menu-entry.patch b/build/cromite_patches/Bookmarks-select-all-menu-entry.patch deleted file mode 100644 index f3c564d3..00000000 --- a/build/cromite_patches/Bookmarks-select-all-menu-entry.patch +++ /dev/null @@ -1,93 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Sat, 9 Apr 2022 23:01:55 +0200 -Subject: Bookmarks select all menu entry - -Requires: Restore-BookmarkToolbar-setCurrentFolder.patch - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - .../menu/bookmark_toolbar_menu_improved.xml | 7 +++++++ - .../browser/bookmarks/BookmarkToolbar.java | 18 ++++++++++++++++++ - .../android/strings/android_chrome_strings.grd | 3 +++ - 3 files changed, 28 insertions(+) - -diff --git a/chrome/android/java/res/menu/bookmark_toolbar_menu_improved.xml b/chrome/android/java/res/menu/bookmark_toolbar_menu_improved.xml ---- a/chrome/android/java/res/menu/bookmark_toolbar_menu_improved.xml -+++ b/chrome/android/java/res/menu/bookmark_toolbar_menu_improved.xml -@@ -51,6 +51,13 @@ found in the LICENSE file. - android:title="@string/create_new_folder" - app:showAsAction="ifRoom" - app:iconTint="@color/default_icon_color_secondary_tint_list" /> -+ - - void setCurrentFolder(BookmarkId folder) { - mCurrentFolder = mBookmarkModel.getBookmarkById(folder); - enableImportExportMenu(); -+ enableSelectAllMenu(); -+ } -+ -+ void enableSelectAllMenu() { -+ getMenu().findItem(R.id.select_all_menu_id).setVisible(true); - } - - void enableImportExportMenu() { -@@ -226,6 +232,17 @@ public class BookmarkToolbar extends SelectableListToolbar - mExportBookmarkRunnable.run(); - return true; - } -+ if (menuItem.getItemId() == R.id.select_all_menu_id) { -+ if (mBookmarkModel.isBookmarkModelLoaded()) { -+ List childs = mBookmarkModel.getChildIds(mCurrentFolder.getId()); -+ HashSet ids = new HashSet<>(childs.size()); -+ for (BookmarkId item : childs) { -+ ids.add(item); -+ } -+ mSelectionDelegate.setSelectedItems(ids); -+ } -+ return true; -+ } - return assumeNonNull(mMenuIdClickedFunction).apply(menuItem.getItemId()); - } - -@@ -248,6 +265,7 @@ public class BookmarkToolbar extends SelectableListToolbar - - getMenu().findItem(R.id.import_menu_id).setVisible(mCurrentFolder != null); - getMenu().findItem(R.id.export_menu_id).setVisible(mCurrentFolder != null); -+ getMenu().findItem(R.id.select_all_menu_id).setVisible(mCurrentFolder != null); - - // SelectableListToolbar will show/hide the entire group. - setEditButtonVisible(mEditButtonVisible); -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 -@@ -252,6 +252,9 @@ CHAR_LIMIT guidelines: - - Sites - -+ -+ Select all -+ - - Import - --- diff --git a/build/cromite_patches/Bromite-package-name.patch b/build/cromite_patches/Bromite-package-name.patch deleted file mode 100644 index 3b5387ab..00000000 --- a/build/cromite_patches/Bromite-package-name.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Sat, 8 Jan 2022 19:42:34 +0100 -Subject: Bromite package name - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - chrome/android/chrome_public_apk_tmpl.gni | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/chrome/android/chrome_public_apk_tmpl.gni b/chrome/android/chrome_public_apk_tmpl.gni ---- a/chrome/android/chrome_public_apk_tmpl.gni -+++ b/chrome/android/chrome_public_apk_tmpl.gni -@@ -27,7 +27,7 @@ declare_args() { - # WebView providers which declare one of a handful of package names. See - # https://chromium.googlesource.com/chromium/src/+/HEAD/android_webview/docs/build-instructions.md#Changing-package-name - # for details. -- chrome_public_manifest_package = "org.chromium.chrome" -+ chrome_public_manifest_package = "org.bromite.bromite" - if (use_stable_package_name_for_trichrome) { - chrome_public_manifest_package += ".stable" - } else if (android_channel != "default" && android_channel != "stable") { --- diff --git a/build/cromite_patches/Bromite-subresource-adblocker.patch b/build/cromite_patches/Bromite-subresource-adblocker.patch deleted file mode 100644 index f8e1538e..00000000 --- a/build/cromite_patches/Bromite-subresource-adblocker.patch +++ /dev/null @@ -1,2038 +0,0 @@ -From: csagan5 <32685696+csagan5@users.noreply.github.com> -Date: Sat, 14 Sep 2019 10:20:08 +0200 -Subject: Bromite subresource adblocker - -Add option to configure the ad blocker filters URL -Disable look-alike, metrics, ablation and navigation throttles -Do not use experiments to enable/disable presets -Always enable ad filtering -Download filters by checking Last-Modified header first -Fix RestoreForeignSessionTab by recreating the tab (issue #681) -Enable AutomaticLazyFrameLoadingToAds and AutomaticLazyFrameLoadingToEmbeds features - -License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html ---- - chrome/android/BUILD.gn | 1 + - chrome/android/chrome_java_resources.gni | 2 + - chrome/android/chrome_java_sources.gni | 2 + - .../java/res/layout/adblock_editor.xml | 67 +++++ - chrome/android/java/res/values/styles.xml | 18 ++ - chrome/android/java/res/values/values.xml | 4 + - .../java/res/xml/adblock_preferences.xml | 25 ++ - .../android/java/res/xml/main_preferences.xml | 5 + - .../browser/settings/AdBlockEditor.java | 91 ++++++ - .../browser/settings/AdBlockPreferences.java | 74 +++++ - .../browser/settings/SettingsActivity.java | 3 + - chrome/app/generated_resources.grd | 10 + - chrome/browser/after_startup_task_utils.cc | 4 + - chrome/browser/browser_process.h | 6 + - chrome/browser/browser_process_impl.cc | 28 ++ - chrome/browser/browser_process_impl.h | 2 + - chrome/browser/chrome_browser_main.cc | 3 + - chrome/browser/flags/BUILD.gn | 3 + - .../flags/android/adblock_native_gateway.cc | 31 ++ - .../browser/flags/AdBlockNativeGateway.java | 30 ++ - .../net/system_network_context_manager.cc | 4 + - .../sessions/session_restore_android.cc | 7 +- - .../strings/android_chrome_strings.grd | 14 + - chrome/common/pref_names.h | 5 + - .../strings/android/site_settings.grdp | 3 + - components/component_updater/BUILD.gn | 8 + - .../adblock_updater_service.cc | 281 ++++++++++++++++++ - .../adblock_updater_service.h | 103 +++++++ - .../download_filters_task.cc | 250 ++++++++++++++++ - .../component_updater/download_filters_task.h | 129 ++++++++ - ...ent_subresource_filter_throttle_manager.cc | 15 + - ...tent_subresource_filter_throttle_manager.h | 2 + - .../content/shared/browser/ruleset_service.cc | 44 ++- - .../content/shared/browser/ruleset_service.h | 8 +- - .../unindexed_ruleset_stream_generator.cc | 3 + - .../core/browser/ruleset_version.h | 4 + - .../browser/subresource_filter_features.cc | 118 +------- - .../core/browser/verified_ruleset_dealer.cc | 4 + - .../core/common/indexed_ruleset.cc | 5 +- - 39 files changed, 1287 insertions(+), 129 deletions(-) - create mode 100644 chrome/android/java/res/layout/adblock_editor.xml - create mode 100644 chrome/android/java/res/xml/adblock_preferences.xml - create mode 100644 chrome/android/java/src/org/chromium/chrome/browser/settings/AdBlockEditor.java - create mode 100644 chrome/android/java/src/org/chromium/chrome/browser/settings/AdBlockPreferences.java - create mode 100755 chrome/browser/flags/android/adblock_native_gateway.cc - create mode 100755 chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/AdBlockNativeGateway.java - create mode 100644 components/component_updater/adblock_updater_service.cc - create mode 100644 components/component_updater/adblock_updater_service.h - create mode 100644 components/component_updater/download_filters_task.cc - create mode 100644 components/component_updater/download_filters_task.h - -diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn ---- a/chrome/android/BUILD.gn -+++ b/chrome/android/BUILD.gn -@@ -324,6 +324,7 @@ if (_is_default_toolchain) { - "//chrome/android/features/tab_ui/public:ui_java_resources", - "//chrome/android/modules/stack_unwinder/provider:java", - "//chrome/android/webapk/libs/client:client_java", -+ "//chrome/browser/endpoint_fetcher:java", - "//chrome/android/webapk/libs/common:common_java", - "//chrome/android/webapk/libs/common:splash_java", - "//chrome/android/webapk/libs/runtime_library:webapk_service_aidl_java", -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 -@@ -432,6 +432,7 @@ chrome_java_resources = [ - "java/res/layout/account_divider_preference.xml", - "java/res/layout/account_management_account_row.xml", - "java/res/layout/app_history_filter.xml", -+ "java/res/layout/adblock_editor.xml", - "java/res/layout/auto_sign_in_first_run_dialog.xml", - "java/res/layout/autofill_billing_address_dropdown.xml", - "java/res/layout/autofill_card_name_and_number.xml", -@@ -627,6 +628,7 @@ chrome_java_resources = [ - "java/res/xml/account_management_preferences.xml", - "java/res/xml/ad_services_config.xml", - "java/res/xml/appearance_preferences.xml", -+ "java/res/xml/adblock_preferences.xml", - "java/res/xml/bookmark_widget_info.xml", - "java/res/xml/clear_browsing_data_preferences.xml", - "java/res/xml/contextual_search_preferences.xml", -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 -@@ -918,6 +918,8 @@ chrome_java_sources = [ - "java/src/org/chromium/chrome/browser/permissions/PermissionBlockedDialog.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", - "java/src/org/chromium/chrome/browser/policy/PolicyAuditor.java", - "java/src/org/chromium/chrome/browser/policy/PolicyAuditorBridge.java", - "java/src/org/chromium/chrome/browser/privacy/settings/DoNotTrackSettings.java", -diff --git a/chrome/android/java/res/layout/adblock_editor.xml b/chrome/android/java/res/layout/adblock_editor.xml -new file mode 100644 ---- /dev/null -+++ b/chrome/android/java/res/layout/adblock_editor.xml -@@ -0,0 +1,67 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -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 -@@ -312,6 +312,24 @@ found in the LICENSE file. - - - -+ -+ -+ -+ - - -+ -+ -+ -+ -+ -+
-+ -+
-+
-+
Enable anti-circumvention and snippets
-+
-+ Snippets are pieces of JavaScript code, injected by the Adblock Plus, that execute within the context of a website and combat advanced ads that circumvent ordinary blocking. -+ The functionality is ONLY allowed for the list -+ abp-filters-anti-cv.txt -+ which is activated by this setting. -+
Open ABP anti-circumvention filter list repo -+
Open ABP Snippets Overview -+
-+
-+
-+ -+ -+
-+ -+
-+
-+
-+ -+ Check for updates now -+ -+
-+ -+
-+ -+
-+
Built in Subscriptions ([[countEnabled]] selected)
-+
-+ Add the languages in which you regularly browse websites in -+
-+
-+
-+ -+
-+ -+
-+
-+
-+
-+ -+
-+ Allowed Domains ([[allowedDomainsCount]] added) -+
-+
-+ Support your favorite websites by adding them to this list. You might see ads on them. -+
-+
-+ -+
-+ -+
-+
-+ -+ -+ Add -+ -+ -+
-+
-+
-+
-+
-+
-+ -+
-+ Custom Subscriptions ([[customSubscriptions.length]] added) -+
-+
-+ Add custom filter urls -+
-+
-+ -+
-+ -+
-+
-+ -+ -+ Add -+ -+ -+
-+
-+
-+
-+
-+
-+ -+
-+ Custom Filters ([[customFilters.length]] added) -+
-+
-+ Add custom filter commands -+
-+
-+ -+
-+ -+
-+
-+ -+ -+ Add -+ -+ -+
-+
-+
-+
-+
-+ -+
-+ -+
-diff --git a/chrome/browser/resources/settings/adblock_page/adblock_page.ts b/chrome/browser/resources/settings/adblock_page/adblock_page.ts -new file mode 100644 ---- /dev/null -+++ b/chrome/browser/resources/settings/adblock_page/adblock_page.ts -@@ -0,0 +1,311 @@ -+/* -+ 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 . -+*/ -+import 'chrome://resources/cr_elements/cr_button/cr_button.js'; -+import 'chrome://resources/cr_elements/cr_shared_style.css.js'; -+import 'chrome://resources/polymer/v3_0/iron-collapse/iron-collapse.js'; -+import 'chrome://resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js'; -+import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; -+import '../settings_shared.css.js'; -+ -+import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; -+import {BaseMixin} from '../base_mixin.js'; -+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -+import {SettingsToggleButtonElement} from '../controls/settings_toggle_button.js'; -+import {PrefsMixin} from '/shared/settings/prefs/prefs_mixin.js'; -+import {CrCheckboxElement} from 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.js'; -+import {getTemplate} from './adblock_page.html.js'; -+import {getToastManager} from 'chrome://resources/cr_elements/cr_toast/cr_toast_manager.js'; -+import {getSearchManager} from '../search_settings.js'; -+import type {SettingsPlugin} from '../settings_main/settings_plugin.js'; -+ -+const SettingsAdblockPageElementBase = -+ I18nMixin(PrefsMixin(BaseMixin((PolymerElement)))); -+ -+interface Subscription { -+ url: string; -+ title: string; -+ enabled: boolean; -+ current_version: string; -+ download_error_count: number; -+ download_success_count: number; -+ installation_state: string; -+ last_installation_time: string; -+} -+ -+export class SettingsAdblockPageElement extends SettingsAdblockPageElementBase -+ implements SettingsPlugin { -+ static get is() { -+ return 'settings-adblock-page'; -+ } -+ -+ static get template() { -+ return getTemplate(); -+ } -+ -+ static get properties() { -+ return { -+ customSubscriptionInput: String, -+ customFilterInput: String, -+ allowedDomainInput: String, -+ additionalMessage: String, -+ additionalMessageIcon: String, -+ countEnabled: Number, -+ allowedDomainsCount: Number, -+ isEnablePrivilegedFiltersToggle_: Boolean, -+ customSubscriptions: Array, -+ customFilters: Array, -+ allowedDomains: Array, -+ subscriptions: Array, -+ } -+ } -+ -+ // input fields updated by html -+ declare private customSubscriptionInput: string; -+ declare private customFilterInput: string; -+ declare private allowedDomainInput: string; -+ declare private additionalMessage: string; -+ declare private additionalMessageIcon: string; -+ declare private countEnabled: number; -+ declare private allowedDomainsCount: number; -+ declare private isEnablePrivilegedFiltersToggle_: boolean; -+ -+ // models that will fill templates lists in html -+ declare private customSubscriptions: Subscription[]; -+ declare private customFilters: Array; -+ declare private allowedDomains: Array; -+ declare private subscriptions: Subscription[]; -+ -+ private syncSubscriptions() { -+ this.subscriptions = [] -+ this.customSubscriptions = []; -+ -+ chrome.adblockPrivate?.getBuiltInSubscriptions(list => { -+ chrome.adblockPrivate.getInstalledSubscriptions(activelist => { -+ let new_subscriptions: Subscription[] = []; -+ let custom_subscriptions: Subscription[] = []; -+ -+ list.forEach(obj => { -+ new_subscriptions.push({ -+ title: obj.title, -+ enabled: false, -+ url: obj.url, -+ current_version: '', -+ download_error_count: 0, -+ download_success_count: 0, -+ installation_state: '', -+ last_installation_time: '' -+ }) -+ }) -+ -+ activelist.forEach(obj => { -+ var found = new_subscriptions.find(element => element.url == obj.url); -+ if (found === undefined) { -+ found = { -+ title: obj.title, -+ enabled: false, -+ url: obj.url, -+ current_version: '', -+ download_error_count: 0, -+ download_success_count: 0, -+ installation_state: '', -+ last_installation_time: '' -+ } -+ custom_subscriptions.push(found) -+ } -+ found.enabled = true; -+ found.current_version = obj.current_version; -+ found.download_error_count = obj.download_error_count; -+ found.download_success_count = obj.download_success_count; -+ found.installation_state = obj.installation_state; -+ found.last_installation_time = obj.last_installation_time; -+ }) -+ -+ this.subscriptions = new_subscriptions; -+ this.customSubscriptions = custom_subscriptions; -+ this.updateUI(); -+ }) -+ }); -+ } -+ -+ private updateUI() { -+ this.additionalMessage = ""; -+ this.additionalMessageIcon = ""; -+ this.countEnabled = 0; -+ -+ chrome.adblockPrivate?.isEnabled(enabled => { -+ if (!enabled) return; -+ -+ let c = 0; -+ this.subscriptions.forEach(obj => { -+ if (obj.enabled) c++; -+ }); -+ this.countEnabled = c; -+ if (this.countEnabled == 0 && -+ this.customSubscriptions.length == 0 && -+ this.customFilters.length == 0) { -+ this.additionalMessage = "No subscriptions selected. Adblock is not active."; -+ this.additionalMessageIcon = "cr:warning"; -+ } -+ }); -+ -+ chrome.adblockPrivate?.isPrivilegedFiltersEnabled(enabled => { -+ this.isEnablePrivilegedFiltersToggle_ = enabled; -+ }); -+ } -+ -+ private syncCustomFilters() { -+ chrome.adblockPrivate?.getCustomFilters(domain => { -+ this.customFilters = []; -+ domain.forEach(value => { -+ this.customFilters.push(value); -+ }) -+ this.updateUI(); -+ }); -+ } -+ -+ private syncAllowedDomains() { -+ this.allowedDomainsCount = 0; -+ chrome.adblockPrivate?.getAllowedDomains(domain => { -+ this.allowedDomains = []; -+ domain.forEach(value => { -+ this.allowedDomains.push(value); -+ }) -+ this.allowedDomainsCount = this.allowedDomains.length; -+ this.updateUI(); -+ }); -+ } -+ -+ public override ready() { -+ super.ready(); -+ -+ this.syncSubscriptions(); -+ this.syncCustomFilters(); -+ this.syncAllowedDomains(); -+ } -+ -+ private onAdblockEnabled_(event: Event) { -+ if ((event.target as SettingsToggleButtonElement).checked) { -+ chrome.adblockPrivate.setEnabled(true); -+ } else { -+ chrome.adblockPrivate.setEnabled(false); -+ } -+ this.updateUI(); -+ } -+ -+ private onEnablePrivilegedFiltersToggle_(_evt: any, enabled: boolean) { -+ chrome.adblockPrivate.setPrivilegedFiltersEnabled(enabled); -+ this.syncSubscriptions(); -+ } -+ -+ private cleanUrl(url: string) : string { -+ let cleanedUrl : string = ""; -+ try { -+ cleanedUrl = new URL(url).host; -+ } catch (err) { -+ try { -+ // one last try by adding schema -+ cleanedUrl = new URL("https://" + url).host; -+ } -+ catch (err) { -+ console.log("malformed url " + url); -+ return ""; -+ } -+ } -+ return cleanedUrl; -+ } -+ -+ private selectRecommendedSubscription(e: Event) { -+ const url = ((e.target as CrCheckboxElement).id); -+ const enabled = ((e.target as CrCheckboxElement).checked); -+ if (enabled) { -+ chrome.adblockPrivate.installSubscription(url); -+ } else { -+ chrome.adblockPrivate.uninstallSubscription(url); -+ } -+ this.updateUI(); -+ } -+ -+ private removeCustomFilter(e: Event) { -+ const filter = ((e.target as HTMLElement).id); -+ chrome.adblockPrivate.removeCustomFilter(filter); -+ const i = this.customFilters.indexOf(filter); -+ this.splice('customFilters', i, 1); -+ this.updateUI(); -+ } -+ -+ private addCustomFilter() { -+ if (this.customFilterInput == undefined || this.customFilterInput == "") return; -+ chrome.adblockPrivate.addCustomFilter(this.customFilterInput); -+ this.customFilterInput = ""; -+ this.syncCustomFilters(); -+ } -+ -+ private removeAllowedDomain(e: Event) { -+ const allowedDomain = ((e.target as HTMLElement).id); -+ chrome.adblockPrivate.removeAllowedDomain(allowedDomain); -+ const i = this.allowedDomains.indexOf(allowedDomain); -+ this.splice('allowedDomains', i, 1); -+ this.allowedDomainsCount = this.allowedDomains.length; -+ this.updateUI(); -+ } -+ -+ private addAllowedDomain() { -+ if (this.allowedDomainInput == undefined || this.allowedDomainInput == "") return; -+ const cleanedUrl = this.cleanUrl(this.allowedDomainInput); -+ if (cleanedUrl == "") return; -+ chrome.adblockPrivate.addAllowedDomain(cleanedUrl); -+ this.allowedDomainInput = ""; -+ this.syncAllowedDomains(); -+ } -+ -+ private removeCustomSubscription(e: Event) { -+ const url = ((e.target as HTMLElement).id); -+ const subscription = this.customSubscriptions.find( x => x.url = url); -+ chrome.adblockPrivate.uninstallSubscription(subscription!.url); -+ this.splice('customSubscriptions', this.customSubscriptions.indexOf(subscription!), 1); -+ this.updateUI(); -+ } -+ -+ private addCustomSubscription() { -+ if (this.customSubscriptionInput == undefined || this.customSubscriptionInput == "") return; -+ chrome.adblockPrivate.installSubscription(this.customSubscriptionInput); -+ this.customSubscriptionInput = ""; -+ this.syncSubscriptions(); -+ } -+ -+ private startUpdateCycle() { -+ const toastManager = getToastManager(); -+ chrome.adblockPrivate.startUpdate(); -+ toastManager.duration = 5000; -+ toastManager.show("Starting update..."); -+ } -+ -+ // SettingsPlugin implementation -+ async searchContents(query: string) { -+ const searchRequest = await getSearchManager().search(query, this); -+ return searchRequest.getSearchResult(); -+ } -+} -+ -+declare global { -+ interface HTMLElementTagNameMap { -+ 'settings-adblock-page': SettingsAdblockPageElement; -+ } -+} -+ -+customElements.define( -+ SettingsAdblockPageElement.is, SettingsAdblockPageElement); -diff --git a/chrome/browser/resources/settings/page_visibility.ts b/chrome/browser/resources/settings/page_visibility.ts ---- a/chrome/browser/resources/settings/page_visibility.ts -+++ b/chrome/browser/resources/settings/page_visibility.ts -@@ -9,6 +9,7 @@ import {loadTimeData} from './i18n_setup.js'; - */ - export interface PageVisibility { - a11y?: boolean; -+ adblock?: boolean; - ai?: boolean; - appearance?: boolean|AppearancePageVisibility; - autofill?: boolean; -diff --git a/chrome/browser/resources/settings/route.ts b/chrome/browser/resources/settings/route.ts ---- a/chrome/browser/resources/settings/route.ts -+++ b/chrome/browser/resources/settings/route.ts -@@ -226,6 +226,10 @@ function createRoutes(): SettingsRoutes { - r.FONTS = r.APPEARANCE.createChild('/fonts'); - } - -+ if (visibility.adblock !== false) { -+ r.ADBLOCK = r.BASIC.createSection('/adblock', 'adblock'); -+ } -+ - if (visibility.autofill !== false) { - r.AUTOFILL = r.BASIC.createSection( - '/autofill', 'autofill', loadTimeData.getString('autofillPageTitle')); -diff --git a/chrome/browser/resources/settings/router.ts b/chrome/browser/resources/settings/router.ts ---- a/chrome/browser/resources/settings/router.ts -+++ b/chrome/browser/resources/settings/router.ts -@@ -13,6 +13,7 @@ import {loadTimeData} from './i18n_setup.js'; - */ - export interface SettingsRoutes { - ABOUT: Route; -+ ADBLOCK: Route; - ACCESSIBILITY: Route; - ADDRESSES: Route; - ADVANCED: Route; -diff --git a/chrome/browser/resources/settings/settings.ts b/chrome/browser/resources/settings/settings.ts ---- a/chrome/browser/resources/settings/settings.ts -+++ b/chrome/browser/resources/settings/settings.ts -@@ -55,6 +55,7 @@ export {SettingsAppearancePageIndexElement} from './appearance_page/appearance_p - export {HomeUrlInputElement} from './appearance_page/home_url_input.js'; - export {SettingsAutofillPageElement} from './autofill_page/autofill_page.js'; - export {SettingsAutofillPageIndexElement} from './autofill_page/autofill_page_index.js'; -+export {SettingsAdblockPageElement} from './adblock_page/adblock_page.js'; - export {PasswordCheckReferrer, PasswordManagerImpl, PasswordManagerPage, PasswordManagerProxy} from './autofill_page/password_manager_proxy.js'; - export {BaseMixin} from './base_mixin.js'; - export {SettingsCheckboxListEntryElement} from './controls/settings_checkbox_list_entry.js'; -diff --git a/chrome/browser/resources/settings/settings_main/settings_main.html b/chrome/browser/resources/settings/settings_main/settings_main.html ---- a/chrome/browser/resources/settings/settings_main/settings_main.html -+++ b/chrome/browser/resources/settings/settings_main/settings_main.html -@@ -200,6 +200,13 @@ -

- - -+
-+ -+
-+ - -