M114 stage 6

This commit is contained in:
Alexander Frick 2023-06-20 22:43:27 -05:00
parent fac4028b19
commit 598233646b
24 changed files with 924 additions and 470 deletions

View file

@ -34,6 +34,10 @@
#include "media/base/android/media_codec_util.h" // nogncheck #include "media/base/android/media_codec_util.h" // nogncheck
#endif #endif
#if BUILDFLAG(IS_WIN)
#include "base/win/windows_version.h"
#endif
namespace media { namespace media {
namespace { namespace {
@ -273,6 +277,8 @@ bool IsAACSupported(const AudioType& type) {
if (__builtin_available(macOS 10.15, *)) if (__builtin_available(macOS 10.15, *))
return true; return true;
return false; return false;
#elif BUILDFLAG(IS_WIN)
return base::win::GetVersion() >= base::win::Version::WIN11_22H2;
#else #else
return false; return false;
#endif #endif

View file

@ -49,7 +49,7 @@ VideoDecoderConfig::AlphaMode GetAlphaMode(const AVStream* stream) {
VideoColorSpace GetGuessedColorSpace(const VideoColorSpace& color_space) { VideoColorSpace GetGuessedColorSpace(const VideoColorSpace& color_space) {
return VideoColorSpace::FromGfxColorSpace( return VideoColorSpace::FromGfxColorSpace(
// convert to gfx color space and make a guess. // convert to gfx color space and make a guess.
color_space.ToGfxColorSpace()); color_space.GuessGfxColorSpace());
} }
} // namespace } // namespace

View file

@ -32,8 +32,9 @@ is_cast_media_device = is_castos || is_cast_android
# allow_oop_video_decoder where appropriate. Also, finish replacing usages of # allow_oop_video_decoder where appropriate. Also, finish replacing usages of
# (is_linux || is_chromeos_ash) with allow_hosting_oop_video_decoder where # (is_linux || is_chromeos_ash) with allow_hosting_oop_video_decoder where
# appropriate. # appropriate.
allow_oop_video_decoder = is_linux || is_chromeos allow_hosting_oop_video_decoder =
allow_hosting_oop_video_decoder = is_linux || is_chromeos_ash (is_chromeos_ash || is_linux) && (use_vaapi || use_v4l2_codec)
allow_oop_video_decoder = is_chromeos_lacros || allow_hosting_oop_video_decoder
declare_args() { declare_args() {
# Allows distributions to link pulseaudio directly (DT_NEEDED) instead of # Allows distributions to link pulseaudio directly (DT_NEEDED) instead of
@ -66,9 +67,8 @@ declare_args() {
# Override to dynamically link the cras (ChromeOS audio) library. # Override to dynamically link the cras (ChromeOS audio) library.
use_cras = is_chromeos_device use_cras = is_chromeos_device
# Enables AC3/EAC3 audio demuxing. This is enabled only on Chromecast, since # Enables AC3/EAC3 audio handling in chromium. This includes demuxing,
# it only provides demuxing, and is only useful for AC3/EAC3 audio # on-device decoding and bitstream passthrough as supported by device.
# pass-through to HDMI sink on Chromecast.
enable_platform_ac3_eac3_audio = proprietary_codecs && is_cast_media_device enable_platform_ac3_eac3_audio = proprietary_codecs && is_cast_media_device
enable_platform_mpeg_h_audio = proprietary_codecs && is_cast_media_device enable_platform_mpeg_h_audio = proprietary_codecs && is_cast_media_device
@ -77,9 +77,6 @@ declare_args() {
# on-device decoding and bitstream passthrough as supported by device. # on-device decoding and bitstream passthrough as supported by device.
enable_platform_dts_audio = false enable_platform_dts_audio = false
enable_mse_mpeg2ts_stream_parser =
proprietary_codecs && (enable_cast_receiver || use_fuzzing_engine)
# Enable Dolby Vision demuxing. Enabled by default for Chromecast and Windows. # Enable Dolby Vision demuxing. Enabled by default for Chromecast and Windows.
# Actual decoding must be provided by the platform. Since most Dolby Vision # Actual decoding must be provided by the platform. Since most Dolby Vision
# profiles use HEVC, `enable_platform_hevc` is required to enable this. # profiles use HEVC, `enable_platform_hevc` is required to enable this.
@ -96,10 +93,6 @@ declare_args() {
# kAllowClearDolbyVisionInMseWhenPlatformEncryptedDvEnabled. # kAllowClearDolbyVisionInMseWhenPlatformEncryptedDvEnabled.
enable_platform_encrypted_dolby_vision = proprietary_codecs && is_win enable_platform_encrypted_dolby_vision = proprietary_codecs && is_win
# Enable HLS with SAMPLE-AES decryption.
enable_hls_sample_aes =
proprietary_codecs && (enable_cast_receiver || use_fuzzing_engine)
# Enable logging override, e.g. enable DVLOGs through level 2 at build time. # Enable logging override, e.g. enable DVLOGs through level 2 at build time.
# On Cast devices, these are logged as INFO. # On Cast devices, these are logged as INFO.
# When enabled on Fuchsia, these are logged as VLOGs. # When enabled on Fuchsia, these are logged as VLOGs.
@ -116,11 +109,10 @@ declare_args() {
# Enable inclusion of the HEVC/H265 parser and also enable HEVC/H265 decoding # Enable inclusion of the HEVC/H265 parser and also enable HEVC/H265 decoding
# with hardware acceleration assist. Enabled by default for fuzzer builds, # with hardware acceleration assist. Enabled by default for fuzzer builds,
# ChromeOS builds with protected content support, Windows, Mac, and Android. # Windows, Mac, and Android.
enable_hevc_parser_and_hw_decoder = enable_hevc_parser_and_hw_decoder =
proprietary_codecs && proprietary_codecs &&
(use_fuzzing_engine || use_chromeos_protected_media || is_win || is_mac || (use_fuzzing_engine || is_win || is_mac || is_android || is_linux)
is_android || is_linux)
} }
# Use another declare_args() to allow dependence on args defined above. # Use another declare_args() to allow dependence on args defined above.
@ -130,13 +122,16 @@ declare_args() {
enable_av1_decoder = enable_dav1d_decoder enable_av1_decoder = enable_dav1d_decoder
# Enable HEVC/H265 demuxing. Actual decoding must be provided by the # Enable HEVC/H265 demuxing. Actual decoding must be provided by the
# platform. # platform. Always enable this for Lacros, it determines support at runtime.
# TODO(b/194429120): Enable this for Lacros builds.
# TODO(crbug.com/1336055): Revisit the default value for this setting as it # TODO(crbug.com/1336055): Revisit the default value for this setting as it
# applies to video-capable devices. # applies to video-capable devices.
enable_platform_hevc = enable_platform_hevc =
proprietary_codecs && (enable_hevc_parser_and_hw_decoder ||
is_cast_media_device || is_chromeos_lacros)
enable_mse_mpeg2ts_stream_parser =
proprietary_codecs && proprietary_codecs &&
(enable_hevc_parser_and_hw_decoder || is_cast_media_device) (enable_hls_demuxer || enable_cast_receiver || use_fuzzing_engine)
} }
declare_args() { declare_args() {
@ -156,20 +151,10 @@ assert(!enable_platform_dolby_vision || proprietary_codecs,
assert( assert(
!enable_platform_encrypted_dolby_vision || enable_platform_dolby_vision, !enable_platform_encrypted_dolby_vision || enable_platform_dolby_vision,
"enable_platform_dolby_vision required for enable_platform_encrypted_dolby_vision") "enable_platform_dolby_vision required for enable_platform_encrypted_dolby_vision")
assert(!enable_hls_sample_aes || proprietary_codecs,
"proprietary_codecs required for enable_hls_sample_aes")
assert(!enable_platform_dts_audio || proprietary_codecs, assert(!enable_platform_dts_audio || proprietary_codecs,
"proprietary_codecs required for enable_platform_dts_audio") "proprietary_codecs required for enable_platform_dts_audio")
assert(!enable_hls_sample_aes || enable_mse_mpeg2ts_stream_parser,
"enable_mse_mpeg2ts_stream_parser required for enable_hls_sample_aes")
assert(!enable_hls_demuxer || enable_mse_mpeg2ts_stream_parser,
"enable_mse_mpeg2ts_stream_parser required for enable_hls_demuxer")
assert(!enable_platform_hevc || proprietary_codecs, assert(!enable_platform_hevc || proprietary_codecs,
"proprietary_codecs required for enable_platform_hevc") "proprietary_codecs required for enable_platform_hevc")
assert(!enable_hevc_parser_and_hw_decoder || enable_platform_hevc, assert(!enable_hevc_parser_and_hw_decoder || enable_platform_hevc,
"enable_platform_hevc required for enable_hevc_parser_and_hw_decoder") "enable_platform_hevc required for enable_hevc_parser_and_hw_decoder")
@ -268,7 +253,7 @@ if (is_cast_media_device) {
"video_decoder", "video_decoder",
] ]
_default_mojo_media_host = "gpu" _default_mojo_media_host = "gpu"
} else if (is_mac || (is_win && enable_platform_dts_audio)) { } else if (is_mac || is_win) {
_default_mojo_media_services = [ _default_mojo_media_services = [
"audio_decoder", "audio_decoder",
"audio_encoder", "audio_encoder",
@ -371,3 +356,7 @@ if (media_use_ffmpeg) {
if (enable_library_cdms || is_win) { if (enable_library_cdms || is_win) {
media_subcomponent_deps += [ "//media/cdm:cdm_type_conversion" ] media_subcomponent_deps += [ "//media/cdm:cdm_type_conversion" ]
} }
if (is_win) {
media_subcomponent_deps += [ "//media/base/win:media_foundation_util" ]
}

View file

@ -34,6 +34,10 @@
#include "media/base/android/media_codec_util.h" // nogncheck #include "media/base/android/media_codec_util.h" // nogncheck
#endif #endif
#if BUILDFLAG(IS_WIN)
#include "base/win/windows_version.h"
#endif
namespace media { namespace media {
namespace { namespace {
@ -273,6 +277,8 @@ bool IsAACSupported(const AudioType& type) {
if (__builtin_available(macOS 10.15, *)) if (__builtin_available(macOS 10.15, *))
return true; return true;
return false; return false;
#elif BUILDFLAG(IS_WIN)
return base::win::GetVersion() >= base::win::Version::WIN11_22H2;
#else #else
return false; return false;
#endif #endif

View file

@ -49,7 +49,7 @@ VideoDecoderConfig::AlphaMode GetAlphaMode(const AVStream* stream) {
VideoColorSpace GetGuessedColorSpace(const VideoColorSpace& color_space) { VideoColorSpace GetGuessedColorSpace(const VideoColorSpace& color_space) {
return VideoColorSpace::FromGfxColorSpace( return VideoColorSpace::FromGfxColorSpace(
// convert to gfx color space and make a guess. // convert to gfx color space and make a guess.
color_space.ToGfxColorSpace()); color_space.GuessGfxColorSpace());
} }
} // namespace } // namespace

View file

@ -46,14 +46,17 @@ config("compiler") {
# Reduce the page size from 65536 in order to reduce binary size slightly # Reduce the page size from 65536 in order to reduce binary size slightly
# by shrinking the alignment gap between segments. This also causes all # by shrinking the alignment gap between segments. This also causes all
# segments to be mapped adjacently, which breakpad relies on. # segments to be mapped adjacently, which breakpad relies on.
cflags += [ "-march=armv8-a", "-mtune=generic-armv8-a", ]
ldflags += [ "-Wl,-z,max-page-size=4096" ] ldflags += [ "-Wl,-z,max-page-size=4096" ]
} }
if (current_cpu == "arm64") { if (current_cpu == "arm64") {
if (arm_control_flow_integrity == "standard") { if (arm_control_flow_integrity == "standard") {
cflags += [ "-mbranch-protection=standard", "-mfloat-abi=hard", "-march=armv8-a+simd", "-mfpu=neon", ] cflags += [ "-mbranch-protection=standard" ]
rustflags = [ "-Zbranch-protection=bti" ]
} else if (arm_control_flow_integrity == "pac") { } else if (arm_control_flow_integrity == "pac") {
cflags += [ "-mbranch-protection=pac-ret", "-mfloat-abi=hard", "-march=armv8-a+simd", "-mfpu=neon", ] cflags += [ "-mbranch-protection=pac-ret" ]
rustflags = [ "-Zbranch-protection=pac-ret" ]
} }
} }

View file

@ -551,12 +551,6 @@ CHAR_LIMIT guidelines:
<message name="IDS_AUTOFILL_VIRTUAL_CARD_ENROLLMENT_DIALOG_CARD_CONTAINER_TITLE" desc="Text describing how the virtual card will be shown to the user in autofill suggestions."> <message name="IDS_AUTOFILL_VIRTUAL_CARD_ENROLLMENT_DIALOG_CARD_CONTAINER_TITLE" desc="Text describing how the virtual card will be shown to the user in autofill suggestions.">
Virtual card Virtual card
</message> </message>
<message name="IDS_AUTOFILL_VIRTUAL_CARD_ENROLLMENT_DIALOG_CARD_LABEL" desc="Notifies the user that their virtual card card is linked with a card on their account.">
Linked with <ph name="CARD_DETAIL">%1$s<ex>Visa ....1234</ex></ph>
</message>
<message name="IDS_AUTOFILL_VIRTUAL_CARD_ENROLLMENT_INFOBAR_CARD_PREFIX" desc="Notifies the user that their virtual card card is linked with a card on their account.">
linked with
</message>
<message name="IDS_AUTOFILL_CARD_EDITOR_VIRTUAL_CARD_TURN_ON_BUTTON_LABEL" desc="Label shown on the button that the user clicks on to enroll into virtual cards."> <message name="IDS_AUTOFILL_CARD_EDITOR_VIRTUAL_CARD_TURN_ON_BUTTON_LABEL" desc="Label shown on the button that the user clicks on to enroll into virtual cards.">
Turn on Turn on
</message> </message>
@ -1078,9 +1072,12 @@ Private state tokens improve privacy on the web and cant be used to find out
<message name="IDS_PRIVACY_SANDBOX_M1_NOTICE_EEA_BULLET_2" desc="* This is 2 of 2 bullets that site beneath the sentence: 'Were launching new ways to limit what sites can learn about you when they show you personalized ads, for example:' * 'ad measurement' is the name of a new setting we're launching and that appears on the Ad privacy page of Thorium settings. * 'limited types of data': This setting helps an advertiser associate a user's actions on one site with their actions on another. For example, a user sees an ad on one site and then later buys that product from the company that sells the product. The ad measurement setting allows Thorium to help a company make the association between the two sites so that the first site can be fairly compensated for showing an ad. Compared with third-party cookies, very little info is shared between sites to support this functionality. **** CONTEXT PRIVACY SANDBOX **** Thoriums Privacy Sandbox initiative 1) deprecates third-party cookies in Thorium, 2) supports free and open content on the web (by finding better ways to support ads online), 3) while providing stronger privacy protections for users. You can see a high-level description of this public project at www.privacysanbox.com. **** CONTEXT EEA NOTICE **** 1) This screen provides notice to Thorium users in the European Economic Area (EEA). It follows guidelines established by the GDPR. 2) This screen is the second of 2 screens. This second screen describes 2 settings: “Site-suggested ads” and “Ad measurement”. The first screen describes the “Ad topics” setting. " formatter_data="android_java"> <message name="IDS_PRIVACY_SANDBOX_M1_NOTICE_EEA_BULLET_2" desc="* This is 2 of 2 bullets that site beneath the sentence: 'Were launching new ways to limit what sites can learn about you when they show you personalized ads, for example:' * 'ad measurement' is the name of a new setting we're launching and that appears on the Ad privacy page of Thorium settings. * 'limited types of data': This setting helps an advertiser associate a user's actions on one site with their actions on another. For example, a user sees an ad on one site and then later buys that product from the company that sells the product. The ad measurement setting allows Thorium to help a company make the association between the two sites so that the first site can be fairly compensated for showing an ad. Compared with third-party cookies, very little info is shared between sites to support this functionality. **** CONTEXT PRIVACY SANDBOX **** Thoriums Privacy Sandbox initiative 1) deprecates third-party cookies in Thorium, 2) supports free and open content on the web (by finding better ways to support ads online), 3) while providing stronger privacy protections for users. You can see a high-level description of this public project at www.privacysanbox.com. **** CONTEXT EEA NOTICE **** 1) This screen provides notice to Thorium users in the European Economic Area (EEA). It follows guidelines established by the GDPR. 2) This screen is the second of 2 screens. This second screen describes 2 settings: “Site-suggested ads” and “Ad measurement”. The first screen describes the “Ad topics” setting. " formatter_data="android_java">
With ad measurement, limited types of data can be shared among sites and apps to measure the performance of their ads, such as the time of day an ad was shown to you. With ad measurement, limited types of data can be shared among sites and apps to measure the performance of their ads, such as the time of day an ad was shown to you.
</message> </message>
<message name="IDS_PRIVACY_SANDBOX_M1_NOTICE_ROW_DESCRIPTION_3" desc="A paragraph on the 'Enhanced ad privacy in Thorium' page that provides notice to Thorium users outside of the EEA. **** CONTEXT PRIVACY SANDBOX **** Thoriums Privacy Sandbox initiative 1) deprecates third-party cookies in Thorium, 2) supports free and open content on the web (by finding better ways to support ads online), 3) while providing stronger privacy protections for users. You can see a high-level description of this public project at www.privacysanbox.com. **** CONTEXT ROW NOTICE **** 1) This screen provides notice to Thorium users outside of the European Economic Area (EEA) (we typically refer to this screen as “Rest of World” or “ROW”). It follows guidelines established by the GDPR. 2) Were using similar but distinct content for EEA / ROW because legal requirements differ. For ROW, we can provide notice for all 3 settings, and so all 3 settings can appear on a single screen. " formatter_data="android_java"> <message name="IDS_PRIVACY_SANDBOX_M1_NOTICE_ROW_DESCRIPTION_3" desc="A paragraph on the 'Enhanced ad privacy in Thorium' page that provides notice to Thorium users outside of the EEA. **** CONTEXT PRIVACY SANDBOX **** Thoriums Privacy Sandbox initiative 1) deprecates third-party cookies in Thorium, 2) supports free and open content on the web (by finding better ways to support ads online), 3) while providing stronger privacy protections for users. You can see a high-level description of this public project at www.privacysanbox.com. **** CONTEXT ROW NOTICE **** 1) This screen provides notice to Thorium users outside of the European Economic Area (EEA) (we typically refer to this screen as “Rest of World” or “ROW”). It follows guidelines established by the GDPR. 2) Were using similar but distinct content for EEA / ROW because legal requirements differ. For ROW, we can provide notice for all 3 settings, and so all 3 settings can appear on a single screen. ">
To measure the performance of an ad, limited types of data can be shared among sites, such as the time of day an ad was shown to you. To measure the performance of an ad, limited types of data can be shared among sites, such as the time of day an ad was shown to you.
</message> </message>
<message name="IDS_PRIVACY_SANDBOX_M1_NOTICE_RESTRICTED_DESCRIPTION_3" translateable="false" formatter_data="android_java">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</message>
<message name="IDS_PRIVACY_SANDBOX_M1_NOTICE_EEA_LEARN_MORE_DESCRIPTION_ANDROID" desc="As part of Privacy Sandbox (see details below), both Thorium and Android devices will have a new setting called 'Ad measurement'. Some details are different, but these settings essentially do the same thing. The Thorium setting allows sites you visit to ask Thorium for information that helps them measure the performance of their ads, linking 1) an ad for site B the user sees on site A, with 2) a purchase or other action the user might take on site B. On Android, it's essentially the same story only it's between apps and not sites. The challenge is that on Android, Thorium is a browser but it's also an App. This paragraph helps the user understand that, if both settings are on, information about the user's actions on a site might be connected with actions the user takes in an app. **** CONTEXT PRIVACY SANDBOX **** Thoriums Privacy Sandbox initiative 1) deprecates third-party cookies in Thorium, 2) supports free and open content on the web (by finding better ways to support ads online), 3) while providing stronger privacy protections for users. You can see a high-level description of this public project at www.privacysanbox.com."> <message name="IDS_PRIVACY_SANDBOX_M1_NOTICE_EEA_LEARN_MORE_DESCRIPTION_ANDROID" desc="As part of Privacy Sandbox (see details below), both Thorium and Android devices will have a new setting called 'Ad measurement'. Some details are different, but these settings essentially do the same thing. The Thorium setting allows sites you visit to ask Thorium for information that helps them measure the performance of their ads, linking 1) an ad for site B the user sees on site A, with 2) a purchase or other action the user might take on site B. On Android, it's essentially the same story only it's between apps and not sites. The challenge is that on Android, Thorium is a browser but it's also an App. This paragraph helps the user understand that, if both settings are on, information about the user's actions on a site might be connected with actions the user takes in an app. **** CONTEXT PRIVACY SANDBOX **** Thoriums Privacy Sandbox initiative 1) deprecates third-party cookies in Thorium, 2) supports free and open content on the web (by finding better ways to support ads online), 3) while providing stronger privacy protections for users. You can see a high-level description of this public project at www.privacysanbox.com.">
Your Android device may include a similar setting. If Ad measurement is turned on in Thorium and on your Android device, a company may be able to measure the effectiveness of an ad across web sites you visit and apps you use. Your Android device may include a similar setting. If Ad measurement is turned on in Thorium and on your Android device, a company may be able to measure the effectiveness of an ad across web sites you visit and apps you use.
</message> </message>
@ -1152,7 +1149,7 @@ Private state tokens improve privacy on the web and cant be used to find out
Sites Sites
</message> </message>
<message name="IDS_SETTINGS_FLEDGE_PAGE_CURRENT_SITES_DESCRIPTION" desc="A paragraph beneath the 'Sites' label. It explains how users can control the sites that appear in the list. * 'block sites': When a user blocks a site, that site may no longer save info with Thorium about the user's visit. As the user continues to browse, they will not see ads suggested by the blocked site. * 'auto-deletes': We included the 'auto' to reinforce that this is part of a system and the deletion is done regularly. "> <message name="IDS_SETTINGS_FLEDGE_PAGE_CURRENT_SITES_DESCRIPTION" desc="A paragraph beneath the 'Sites' label. It explains how users can control the sites that appear in the list. * 'block sites': When a user blocks a site, that site may no longer save info with Thorium about the user's visit. As the user continues to browse, they will not see ads suggested by the blocked site. * 'auto-deletes': We included the 'auto' to reinforce that this is part of a system and the deletion is done regularly. ">
You can block sites you dont want. Thorium also auto-deletes sites from the list that are older than 4 weeks. <ph name="BEGIN_LINK">&lt;link&gt;</ph>Learn more<ph name="END_LINK">&lt;/link&gt;</ph> You can block sites you dont want. Thorium also auto-deletes sites from the list that are older than 30 days. <ph name="BEGIN_LINK">&lt;link&gt;</ph>Learn more<ph name="END_LINK">&lt;/link&gt;</ph>
</message> </message>
<message name="IDS_SETTINGS_FLEDGE_PAGE_CURRENT_SITES_DESCRIPTION_DISABLED" desc="1 of 3 possible descriptions that appear beneath the 'Sites' title. If this setting is off, no sites appear. The link opens a dialog box that provides more information about Site-suggested ads."> <message name="IDS_SETTINGS_FLEDGE_PAGE_CURRENT_SITES_DESCRIPTION_DISABLED" desc="1 of 3 possible descriptions that appear beneath the 'Sites' title. If this setting is off, no sites appear. The link opens a dialog box that provides more information about Site-suggested ads.">
When on, a list of sites you visit that guess your interests appears here. When on, a list of sites you visit that guess your interests appears here.
@ -1191,7 +1188,7 @@ Private state tokens improve privacy on the web and cant be used to find out
For example, if you visit a site that sells long-distance running shoes, the site might decide that youre interested in running marathons. Later, if you visit a different site, that site can show you an ad for running shoes suggested by the first site. For example, if you visit a site that sells long-distance running shoes, the site might decide that youre interested in running marathons. Later, if you visit a different site, that site can show you an ad for running shoes suggested by the first site.
</message> </message>
<message name="IDS_SETTINGS_FLEDGE_PAGE_LEARN_MORE_BULLET_3" desc="3 of 3 paragraphs on the Learn more page for Site-suggested ads. * 'Auto-deletes': This could just read 'Thorium deletes...' but we include the 'auto' to suggest that the deletion happens regularly and as part of the system. * 'A site you visit again...': We want to reassure the user. We just told them sites are automatically deleted. And yet, a user might see the same site in the list month after month if they visit that site regularly."> <message name="IDS_SETTINGS_FLEDGE_PAGE_LEARN_MORE_BULLET_3" desc="3 of 3 paragraphs on the Learn more page for Site-suggested ads. * 'Auto-deletes': This could just read 'Thorium deletes...' but we include the 'auto' to suggest that the deletion happens regularly and as part of the system. * 'A site you visit again...': We want to reassure the user. We just told them sites are automatically deleted. And yet, a user might see the same site in the list month after month if they visit that site regularly.">
Thorium auto-deletes sites that are older than 4 weeks. A site you visit again might reappear on the list. Or you can block a site from suggesting ads for you. Thorium auto-deletes sites that are older than 30 days. A site you visit again might reappear on the list. Or you can block a site from suggesting ads for you.
</message> </message>
<message name="IDS_SETTINGS_FLEDGE_PAGE_BLOCK_SITE_A11Y_LABEL" desc="A button label read by screen readers that indicates which site will get blocked. The list is of sites the user has recently visited and that use the Site-suggested ads API to suggest ads to other sites as the user continues browsing."> <message name="IDS_SETTINGS_FLEDGE_PAGE_BLOCK_SITE_A11Y_LABEL" desc="A button label read by screen readers that indicates which site will get blocked. The list is of sites the user has recently visited and that use the Site-suggested ads API to suggest ads to other sites as the user continues browsing.">
Block <ph name="DOMAIN">%1$s<ex>example.com</ex></ph> Block <ph name="DOMAIN">%1$s<ex>example.com</ex></ph>
@ -1400,12 +1397,15 @@ Your Google account may have other forms of browsing history like searches and a
</message> </message>
<!-- Privacy Guide --> <!-- Privacy Guide -->
<message name="IDS_PREFS_PRIVACY_GUIDE_TITLE" desc="The title of the privacy guide menu item."> <message name="IDS_PRIVACY_GUIDE_PREF_TITLE" desc="The title of the privacy guide menu item. The text between the BEGIN_NEW and END_NEW tokens is a chip shown on the menu item, informing users that this is a new feature.">
Privacy guide Privacy Guide <ph name="BEGIN_NEW">&lt;new&gt;</ph>New<ph name="END_NEW">&lt;/new&gt;</ph>
</message> </message>
<message name="IDS_PREFS_PRIVACY_GUIDE_SUMMARY" desc="The summary of the privacy menu item."> <message name="IDS_PRIVACY_GUIDE_PREF_SUMMARY" desc="The summary of the privacy menu item.">
Review key privacy and security controls Review key privacy and security controls
</message> </message>
<message name="IDS_PRIVACY_GUIDE_FRAGMENT_TITLE" desc="The title of all privacy guide fragments.">
Privacy Guide
</message>
<message name="IDS_PRIVACY_GUIDE_WELCOME_TITLE" desc="Title on the welcome page of the privacy guide."> <message name="IDS_PRIVACY_GUIDE_WELCOME_TITLE" desc="Title on the welcome page of the privacy guide.">
A guide of your privacy choices A guide of your privacy choices
</message> </message>
@ -2629,10 +2629,13 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
<message name="IDS_NOTIFICATION_WEBAPK_INSTALL_FAILED_CONTENTS_GENERAL" desc="Message content indicates that the WebAPK install was unsuccessful for a general reason."> <message name="IDS_NOTIFICATION_WEBAPK_INSTALL_FAILED_CONTENTS_GENERAL" desc="Message content indicates that the WebAPK install was unsuccessful for a general reason.">
Something went wrong. Something went wrong.
</message> </message>
<message name="IDS_NOTIFICATION_WEBAPK_INSTALL_FAILED_SPACE" desc="Message content indicates that the WebAPK install was unsuccessful because out of space.">
Not enough space on device.
</message>
<message name="IDS_WEBAPK_INSTALL_FAILED_ACTION_OPEN" desc="The label of the button which upon click would open the site user was trying to install as PWA. "> <message name="IDS_WEBAPK_INSTALL_FAILED_ACTION_OPEN" desc="The label of the button which upon click would open the site user was trying to install as PWA. ">
Go back to site Go back to site
</message> </message>
<message name="IDS_WEBAPK_INSTALL_FAILED_ACTION_RETRY" desc="The label of the button which upon click would retry installing the PWA" translateable="false"> <message name="IDS_WEBAPK_INSTALL_FAILED_ACTION_RETRY" desc="The label of the button which upon click would retry installing the PWA">
Try again Try again
</message> </message>
<message name="IDS_IPH_PWA_INSTALL_AVAILABLE_TEXT" desc="The in-product-help message for PWAs that can be installed to the device."> <message name="IDS_IPH_PWA_INSTALL_AVAILABLE_TEXT" desc="The in-product-help message for PWAs that can be installed to the device.">
@ -2677,6 +2680,11 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
If youre seeing this frequently, try these <ph name="BEGIN_LINK">&lt;link&gt;</ph>suggestions<ph name="END_LINK">&lt;/link&gt;</ph>. If youre seeing this frequently, try these <ph name="BEGIN_LINK">&lt;link&gt;</ph>suggestions<ph name="END_LINK">&lt;/link&gt;</ph>.
</message> </message>
<!-- Can't launch dialog. -->
<message name="IDS_UPDATE_NEEDED" desc="The help message is displayed on launch if an update is required to function.">
Your device couldnt open Thorium. To fix the issue, download the latest Thorium update from your app store.
</message>
<!-- Web Notifications API --> <!-- Web Notifications API -->
<message name="IDS_NOTIFICATION_HIDDEN_TEXT" desc="Text shown in place of notification contents when the notification's contents have been hidden on a secure lockscreen [CHAR_LIMIT=32]"> <message name="IDS_NOTIFICATION_HIDDEN_TEXT" desc="Text shown in place of notification contents when the notification's contents have been hidden on a secure lockscreen [CHAR_LIMIT=32]">
Contents hidden Contents hidden
@ -2982,8 +2990,8 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
<message name="IDS_FRE_BROWSER_MANAGED_BY_ORGANIZATION" desc="Text that indicates the browser is managed by policy"> <message name="IDS_FRE_BROWSER_MANAGED_BY_ORGANIZATION" desc="Text that indicates the browser is managed by policy">
Your browser is managed by your organization Your browser is managed by your organization
</message> </message>
<message name="IDS_FRE_BROWSER_MANAGED_BY_PARENTS" desc="Text that indicates the browser is managed by parents"> <message name="IDS_FRE_BROWSER_MANAGED_BY_PARENT" desc="Text that indicates the browser is managed by parent">
Your browser is managed by your parents Your browser is managed by your parent
</message> </message>
<!-- Signin First Run strings --> <!-- Signin First Run strings -->
@ -3041,6 +3049,24 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
Add account to device Add account to device
</message> </message>
<!-- Strings for the Device Lock. -->
<!-- TODO(crbug.com/1431577): Finalize strings and set to translateable -->
<message name="IDS_DEVICE_LOCK_TITLE" translateable="false" desc="">
Keep your data secure with profile lock
</message>
<message name="IDS_DEVICE_LOCK_DESCRIPTION" translateable="false" desc="">
For your data security in the car, profile lock is required to sync and save your passwords, payments, and more.
</message>
<message name="IDS_DEVICE_LOCK_HIGHLIGHTED_NOTICE" translateable="false" desc="">
Your saved data will be erased if profile lock is removed later
</message>
<message name="IDS_DEVICE_LOCK_CREATE_LOCK_BUTTON" translateable="false" desc="">
Set up a profile lock
</message>
<message name="IDS_DEVICE_LOCK_USER_UNDERSTANDS_BUTTON" translateable="false" desc="">
I understand
</message>
<!-- Strings for Streamlined Signin and Unified Consent. --> <!-- Strings for Streamlined Signin and Unified Consent. -->
<message name="IDS_SIGNIN_TITLE" desc="Title for the screen that asks users to sign-in and turn on Sync. [CHAR_LIMIT=27]"> <message name="IDS_SIGNIN_TITLE" desc="Title for the screen that asks users to sign-in and turn on Sync. [CHAR_LIMIT=27]">
Turn on sync? Turn on sync?
@ -3517,6 +3543,15 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
<message name="IDS_CUSTOM_TAB_AMP_PUBLISHER_URL" desc="Text shown in a Custom Tab toolbar for a web page that is hosted by the Google content delivery network but was originally published by someone else."> <message name="IDS_CUSTOM_TAB_AMP_PUBLISHER_URL" desc="Text shown in a Custom Tab toolbar for a web page that is hosted by the Google content delivery network but was originally published by someone else.">
From <ph name="PUBLISHER_ORIGIN">&lt;pub&gt;%1$s&lt;/pub&gt;<ex>example.com</ex></ph> <ph name="BEGIN_DEEMPHASIZED">&lt;bg&gt;</ph>delivered by Google<ph name="END_DEEMPHASIZED">&lt;/bg&gt;</ph> From <ph name="PUBLISHER_ORIGIN">&lt;pub&gt;%1$s&lt;/pub&gt;<ex>example.com</ex></ph> <ph name="BEGIN_DEEMPHASIZED">&lt;bg&gt;</ph>delivered by Google<ph name="END_DEEMPHASIZED">&lt;/bg&gt;</ph>
</message> </message>
<message name="IDS_ACCESSIBILITY_CUSTOM_TAB_DRAG_HANDLE" desc="The accesibility text for drag handle in the toolbar of the partial custom tab.">
Drag handle
</message>
<message name="IDS_ACCESSIBILITY_CUSTOM_TAB_EXPANDED" desc="The accesibility text informing the custom tab is expanded.">
Tab is expanded
</message>
<message name="IDS_ACCESSIBILITY_CUSTOM_TAB_COLLAPSED" desc="The accesibility text informing the custom tab is collapsed back to initial height.">
Tab is back to initial height
</message>
<message name="IDS_CUSTOM_TAB_SIDE_SHEET_MAXIMIZE" desc="The accesibility text for maximize button in side-sheet custom tab."> <message name="IDS_CUSTOM_TAB_SIDE_SHEET_MAXIMIZE" desc="The accesibility text for maximize button in side-sheet custom tab.">
Expand to full screen Expand to full screen
</message> </message>
@ -3690,9 +3725,6 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
<message name="IDS_MENU_CLOSE_ALL_INCOGNITO_TABS" desc="Menu item for closing all open Incognito tabs. [CHAR_LIMIT=27]"> <message name="IDS_MENU_CLOSE_ALL_INCOGNITO_TABS" desc="Menu item for closing all open Incognito tabs. [CHAR_LIMIT=27]">
Close Incognito tabs Close Incognito tabs
</message> </message>
<message name="IDS_MENU_GROUP_TABS" desc="Menu item for grouping tabs. [CHAR_LIMIT=27]">
Group tabs
</message>
<message name="IDS_MENU_SELECT_TABS" desc="Menu item for bulk editing tabs. [CHAR_LIMIT=27]"> <message name="IDS_MENU_SELECT_TABS" desc="Menu item for bulk editing tabs. [CHAR_LIMIT=27]">
Select tabs Select tabs
</message> </message>
@ -3864,6 +3896,30 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
<message name="IDS_IPH_SHOPPING_LIST_SAVE_FLOW_ACCESSIBILITY" is_accessibility_with_no_ui="true" desc="In-product help accessibility text that notifies a user that they can organize their saved products from a folder in bookmarks."> <message name="IDS_IPH_SHOPPING_LIST_SAVE_FLOW_ACCESSIBILITY" is_accessibility_with_no_ui="true" desc="In-product help accessibility text that notifies a user that they can organize their saved products from a folder in bookmarks.">
Organize your tracked products in Bookmarks from the folder icon Organize your tracked products in Bookmarks from the folder icon
</message> </message>
<message name="IDS_SORT_SUBMENU" desc="Sub-menu in the bookmarks manager for sort/view options. [CHAR_LIMIT=24]">
Sort and view options
</message>
<message name="IDS_SORT_BY_NEWEST" desc="Option in the bookmarks manager to sort by newest. [CHAR_LIMIT=24]">
Sort by newest
</message>
<message name="IDS_SORT_BY_OLDEST" desc="Option in the bookmarks manager to sort by newest. [CHAR_LIMIT=24]">
Sort by oldest
</message>
<message name="IDS_SORT_BY_ALPHA" desc="Option in the bookmarks manager to sort alphabetically. A and Z should be substituted with the first/last letter in the localized language. [CHAR_LIMIT=24]">
Sort by A to Z
</message>
<message name="IDS_SORT_BY_REVERSE_ALPHA" desc="Option in the bookmarks manager to sort alphabetically. A and Z should be substituted with the first/last letter in the localized language. [CHAR_LIMIT=24]">
Sort by Z to A
</message>
<message name="IDS_VISUAL_VIEW" desc="Option in the bookmarks manager to show the visual view with expanded rows and images. [CHAR_LIMIT=24]">
Visual view
</message>
<message name="IDS_COMPACT_VIEW" desc="Option in the bookmarks manager to show the compact view with smaller rows and favicons. [CHAR_LIMIT=24]">
Compact view
</message>
<message name="IDS_CREATE_NEW_FOLDER" desc="Option in the bookmarks manager to show the create a new folder in the current context. [CHAR_LIMIT=24]">
Create new folder
</message>
<!-- Read later strings --> <!-- Read later strings -->
<message name="IDS_READING_LIST_READ" desc="The header for the read section in the reading list UI."> <message name="IDS_READING_LIST_READ" desc="The header for the read section in the reading list UI.">
@ -4869,7 +4925,7 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
</message> </message>
<!-- Sharing content types --> <!-- Sharing content types -->
<message name="IDS_BROWSER_SHARING_CONTENT_TYPE_TEXT" desc="The label used to describe that the content type being shared is a text."> <message name="IDS_BROWSER_SHARING_CONTENT_TYPE_TEXT" desc="This will be used as a placeholder in the message 'Can't share [content type].' so it should be lower-case unless this is a language where nouns are upper case." meaning="text as placeholder">
text text
</message> </message>
@ -5259,6 +5315,14 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
Save to device Save to device
</message> </message>
<message name="IDS_SHARING_INCLUDE_LINK" desc="Label for the button in android share sheet to include a link to share along with highlighted text.">
Include link
</message>
<message name="IDS_SHARING_EXCLUDE_LINK" desc="Label for the button in android share sheet to share the highlighted text without a link.">
Exclude link
</message>
<message name="IDS_TEXT_COPIED" desc="Text shown in the toast notification when Copy Text is selected in the sharing hub."> <message name="IDS_TEXT_COPIED" desc="Text shown in the toast notification when Copy Text is selected in the sharing hub.">
Text Copied Text Copied
</message> </message>
@ -5521,9 +5585,18 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
</message> </message>
<!-- WebID Account Selection strings --> <!-- WebID Account Selection strings -->
<message name="IDS_ACCOUNT_SELECTION_SHEET_TITLE_EXPLICIT" desc="Header for sign in sheet. Sheet is shown to prompt user for sign in consent."> <message name="IDS_ACCOUNT_SELECTION_SHEET_TITLE_EXPLICIT_SIGNIN" desc="Header for sign in sheet. Sheet is shown to prompt user to sign in to a website using an account from an identity provider.">
Sign in to <ph name="SITE_ETLD_PLUS_ONE">%1$s<ex>rp.example</ex></ph> with <ph name="IDENTITY_PROVIDER_ETLD_PLUS_ONE">%2$s<ex>idp.com</ex></ph> Sign in to <ph name="SITE_ETLD_PLUS_ONE">%1$s<ex>rp.example</ex></ph> with <ph name="IDENTITY_PROVIDER_ETLD_PLUS_ONE">%2$s<ex>idp.com</ex></ph>
</message> </message>
<message name="IDS_ACCOUNT_SELECTION_SHEET_TITLE_EXPLICIT_SIGNUP" desc="Header for sign up sheet. Sheet is shown to prompt user to sign up to a website using an account from an identity provider.">
Sign up to <ph name="SITE_ETLD_PLUS_ONE">%1$s<ex>rp.example</ex></ph> with <ph name="IDENTITY_PROVIDER_ETLD_PLUS_ONE">%2$s<ex>idp.com</ex></ph>
</message>
<message name="IDS_ACCOUNT_SELECTION_SHEET_TITLE_EXPLICIT_USE" desc="Header for use sheet. Sheet is shown to prompt user to use a website using an account from an identity provider.">
Use <ph name="SITE_ETLD_PLUS_ONE">%1$s<ex>rp.example</ex></ph> with <ph name="IDENTITY_PROVIDER_ETLD_PLUS_ONE">%2$s<ex>idp.com</ex></ph>
</message>
<message name="IDS_ACCOUNT_SELECTION_SHEET_TITLE_EXPLICIT_CONTINUE" desc="Header for continue sheet. Sheet is shown to prompt user to continue to a website using an account from an identity provider.">
Continue to <ph name="SITE_ETLD_PLUS_ONE">%1$s<ex>rp.example</ex></ph> with <ph name="IDENTITY_PROVIDER_ETLD_PLUS_ONE">%2$s<ex>idp.com</ex></ph>
</message>
<message name="IDS_ACCOUNT_SELECTION_SHEET_SUBTITLE_EXPLICIT" desc="Message shown when the user is shown the federated identity login prompt. This message is the subtitle for the sign in sheet, which contains the top-level domain of the page the user is visiting when the user is receiving a prompt from an iframe embedded on such page."> <message name="IDS_ACCOUNT_SELECTION_SHEET_SUBTITLE_EXPLICIT" desc="Message shown when the user is shown the federated identity login prompt. This message is the subtitle for the sign in sheet, which contains the top-level domain of the page the user is visiting when the user is receiving a prompt from an iframe embedded on such page.">
on <ph name="MAIN_FRAME_ETLD_PLUS_ONE">%1$s<ex>main-frame.example</ex></ph> on <ph name="MAIN_FRAME_ETLD_PLUS_ONE">%1$s<ex>main-frame.example</ex></ph>
</message> </message>
@ -5695,10 +5768,13 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
Delete last 15 minutes? Delete last 15 minutes?
</message> </message>
<message name="IDS_QUICK_DELETE_DIALOG_DESCRIPTION" desc="Description of the dialog when asking users to confirm deleting the last 15 minutes of browsing data."> <message name="IDS_QUICK_DELETE_DIALOG_DESCRIPTION" desc="Description of the dialog when asking users to confirm deleting the last 15 minutes of browsing data.">
Following data from the last 15 minutes will be deleted Following data from the last 15 minutes will be deleted:
</message>
<message name="IDS_QUICK_DELETE_DIALOG_SEARCH_HISTORY_DISAMBIGUATION_TEXT" desc="Text for signed in users only in the Quick Delete dialog, that is shown when the user clicks on 'Delete last 15 minutes' option in the three dots menu, informing signed in users that search history and other forms of Activity saved in their Google account will not be deleted.">
<ph name="BEGIN_LINK1">&lt;link1&gt;</ph>Search history<ph name="END_LINK1">&lt;/link1&gt;</ph> and <ph name="BEGIN_LINK2">&lt;link2&gt;</ph>other forms of activity<ph name="END_LINK2">&lt;/link2&gt;</ph> may be saved in your Google Account
</message> </message>
<message name="IDS_QUICK_DELETE_SNACKBAR_MESSAGE" desc="Text inside the snackbar which is shown once the user confirms deletion via the 'Delete last 15 minutes' option present inside the three dots menu."> <message name="IDS_QUICK_DELETE_SNACKBAR_MESSAGE" desc="Text inside the snackbar which is shown once the user confirms deletion via the 'Delete last 15 minutes' option present inside the three dots menu.">
Deleted history, cookies, and other data Deleted
</message> </message>
</messages> </messages>
</release> </release>

View file

@ -130,6 +130,7 @@
#include "chrome/browser/ui/tab_dialogs.h" #include "chrome/browser/ui/tab_dialogs.h"
#include "chrome/browser/ui/tab_helpers.h" #include "chrome/browser/ui/tab_helpers.h"
#include "chrome/browser/ui/tab_modal_confirm_dialog.h" #include "chrome/browser/ui/tab_modal_confirm_dialog.h"
#include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_service_factory.h"
#include "chrome/browser/ui/tabs/tab_enums.h" #include "chrome/browser/ui/tabs/tab_enums.h"
#include "chrome/browser/ui/tabs/tab_group.h" #include "chrome/browser/ui/tabs/tab_group.h"
#include "chrome/browser/ui/tabs/tab_group_model.h" #include "chrome/browser/ui/tabs/tab_group_model.h"
@ -807,14 +808,21 @@ std::u16string Browser::GetWindowTitleFromWebContents(
return app_controller_ ? app_controller_->GetAppShortName() return app_controller_ ? app_controller_->GetAppShortName()
: base::UTF8ToUTF16(app_name()); : base::UTF8ToUTF16(app_name());
} }
// Include the app name in window titles for tabbed browser windows when // Include the app name in window titles for tabbed browser windows when
// requested with |include_app_name|. // requested with |include_app_name|. Exception: On Lacros, when the OS is
// collecting window titles to render for desk overview mode, this function
// would get called with include_app_name=true. In this case,
// include_app_name=true would be ignored and no app name would be included
// in the title string that is to be returned. So always set
// `include_app_name` to false.
#if BUILDFLAG(IS_CHROMEOS_LACROS)
include_app_name = false;
#endif // BUILDFLAG(IS_CHROMEOS_LACROS)
return ((is_type_normal() || is_type_popup()) && include_app_name) return ((is_type_normal() || is_type_popup()) && include_app_name)
? l10n_util::GetStringFUTF16(IDS_BROWSER_WINDOW_TITLE_FORMAT, ? l10n_util::GetStringFUTF16(IDS_BROWSER_WINDOW_TITLE_FORMAT,
title) title)
: title; : title;
#endif #endif // BUILDFLAG(IS_MAC)
} }
// static // static
@ -1241,8 +1249,22 @@ void Browser::OnTabGroupChanged(const TabGroupChange& change) {
tab_strip_model_->group_model() tab_strip_model_->group_model()
->GetTabGroup(change.group) ->GetTabGroup(change.group)
->visual_data(); ->visual_data();
const SavedTabGroupKeyedService* const saved_tab_group_keyed_service =
base::FeatureList::IsEnabled(features::kTabGroupsSave)
? SavedTabGroupServiceFactory::GetForProfile(profile_)
: nullptr;
absl::optional<std::string> saved_guid;
if (saved_tab_group_keyed_service) {
const SavedTabGroup* const saved_group =
saved_tab_group_keyed_service->model()->Get(change.group);
if (saved_group) {
saved_guid = saved_group->saved_guid().AsLowercaseString();
}
}
session_service->SetTabGroupMetadata(session_id(), change.group, session_service->SetTabGroupMetadata(session_id(), change.group,
visual_data); visual_data, std::move(saved_guid));
} }
} else if (change.type == TabGroupChange::kClosed) { } else if (change.type == TabGroupChange::kClosed) {
sessions::TabRestoreService* tab_restore_service = sessions::TabRestoreService* tab_restore_service =
@ -1891,7 +1913,7 @@ void Browser::PortalWebContentsCreated(WebContents* portal_web_contents) {
TabHelpers::AttachTabHelpers(portal_web_contents); TabHelpers::AttachTabHelpers(portal_web_contents);
// Make the portal show up in the task manager. // Make the portal show up in the task manager.
task_manager::WebContentsTags::CreateForPortal(portal_web_contents); WebContentsBecamePortal(portal_web_contents);
} }
void Browser::WebContentsBecamePortal(WebContents* portal_web_contents) { void Browser::WebContentsBecamePortal(WebContents* portal_web_contents) {
@ -2048,27 +2070,15 @@ blink::ProtocolHandlerSecurityLevel Browser::GetProtocolHandlerSecurityLevel(
content::BrowserContext* context = requesting_frame->GetBrowserContext(); content::BrowserContext* context = requesting_frame->GetBrowserContext();
extensions::ProcessMap* process_map = extensions::ProcessMap::Get(context); extensions::ProcessMap* process_map = extensions::ProcessMap::Get(context);
const GURL& owner_site_url =
requesting_frame->GetSiteInstance()->GetSiteURL();
const Extension* owner_extension = const Extension* owner_extension =
extensions::ProcessManager::Get(context)->GetExtensionForRenderFrameHost( extensions::ProcessManager::Get(context)->GetExtensionForRenderFrameHost(
requesting_frame); requesting_frame);
switch (process_map->GetMostLikelyContextType( if (owner_extension &&
owner_extension, requesting_frame->GetProcess()->GetID(), process_map->IsPrivilegedExtensionProcess(
&owner_site_url)) { *owner_extension, requesting_frame->GetProcess()->GetID())) {
case extensions::Feature::BLESSED_WEB_PAGE_CONTEXT:
case extensions::Feature::CONTENT_SCRIPT_CONTEXT:
case extensions::Feature::LOCK_SCREEN_EXTENSION_CONTEXT:
case extensions::Feature::OFFSCREEN_EXTENSION_CONTEXT:
case extensions::Feature::UNBLESSED_EXTENSION_CONTEXT:
case extensions::Feature::UNSPECIFIED_CONTEXT:
case extensions::Feature::WEBUI_CONTEXT:
case extensions::Feature::WEBUI_UNTRUSTED_CONTEXT:
case extensions::Feature::WEB_PAGE_CONTEXT:
return blink::ProtocolHandlerSecurityLevel::kStrict;
case extensions::Feature::BLESSED_EXTENSION_CONTEXT:
return blink::ProtocolHandlerSecurityLevel::kExtensionFeatures; return blink::ProtocolHandlerSecurityLevel::kExtensionFeatures;
} }
return blink::ProtocolHandlerSecurityLevel::kStrict;
} }
void Browser::RegisterProtocolHandler( void Browser::RegisterProtocolHandler(

View file

@ -445,7 +445,7 @@ class Browser : public TabStripModelObserver,
chrome::BrowserCommandController* command_controller() { chrome::BrowserCommandController* command_controller() {
return command_controller_.get(); return command_controller_.get();
} }
const SessionID& session_id() const { return session_id_; } SessionID session_id() const { return session_id_; }
bool omit_from_session_restore() const { return omit_from_session_restore_; } bool omit_from_session_restore() const { return omit_from_session_restore_; }
bool should_trigger_session_restore() const { bool should_trigger_session_restore() const {
return should_trigger_session_restore_; return should_trigger_session_restore_;
@ -591,8 +591,8 @@ class Browser : public TabStripModelObserver,
// Invoked at the end of a fullscreen transition. // Invoked at the end of a fullscreen transition.
void WindowFullscreenStateChanged(); void WindowFullscreenStateChanged();
// Only used on Mac. Called when the top ui style has been changed since this // Only used on Mac and Lacros. Called when the top ui style has been changed
// may trigger bookmark bar state change. // since this may trigger bookmark bar state change.
void FullscreenTopUIStateChanged(); void FullscreenTopUIStateChanged();
void OnFindBarVisibilityChanged(); void OnFindBarVisibilityChanged();
@ -1112,32 +1112,40 @@ class Browser : public TabStripModelObserver,
// Shared code between Reload() and ReloadBypassingCache(). // Shared code between Reload() and ReloadBypassingCache().
void ReloadInternal(WindowOpenDisposition disposition, bool bypass_cache); void ReloadInternal(WindowOpenDisposition disposition, bool bypass_cache);
// See comment on SupportsWindowFeatureImpl for info on `check_can_support`.
bool NormalBrowserSupportsWindowFeature(WindowFeature feature, bool NormalBrowserSupportsWindowFeature(WindowFeature feature,
bool check_can_support) const; bool check_can_support) const;
// See comment on SupportsWindowFeatureImpl for info on `check_can_support`.
bool PopupBrowserSupportsWindowFeature(WindowFeature feature, bool PopupBrowserSupportsWindowFeature(WindowFeature feature,
bool check_can_support) const; bool check_can_support) const;
// See comment on SupportsWindowFeatureImpl for info on `check_can_support`.
bool AppPopupBrowserSupportsWindowFeature(WindowFeature feature, bool AppPopupBrowserSupportsWindowFeature(WindowFeature feature,
bool check_can_support) const; bool check_can_support) const;
// See comment on SupportsWindowFeatureImpl for info on `check_can_support`.
bool AppBrowserSupportsWindowFeature(WindowFeature feature, bool AppBrowserSupportsWindowFeature(WindowFeature feature,
bool check_can_support) const; bool check_can_support) const;
#if BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(IS_CHROMEOS_ASH)
// See comment on SupportsWindowFeatureImpl for info on `check_can_support`.
bool CustomTabBrowserSupportsWindowFeature(WindowFeature feature) const; bool CustomTabBrowserSupportsWindowFeature(WindowFeature feature) const;
#endif #endif
// See comment on SupportsWindowFeatureImpl for info on `check_can_support`.
bool PictureInPictureBrowserSupportsWindowFeature( bool PictureInPictureBrowserSupportsWindowFeature(
WindowFeature feature, WindowFeature feature,
bool check_can_support) const; bool check_can_support) const;
// Implementation of SupportsWindowFeature and CanSupportWindowFeature. If // Implementation of SupportsWindowFeature and CanSupportWindowFeature. If
// |check_fullscreen| is true, the set of features reflect the actual state of // `check_can_support` is true, this method returns true if this type of
// the browser, otherwise the set of features reflect the possible state of // browser can ever support `feature`, under any conditions; if
// the browser. // `check_can_support` is false, it returns true if the browser *in its
// current state* (e.g. whether or not it is currently fullscreen) supports
// `feature`.
bool SupportsWindowFeatureImpl(WindowFeature feature, bool SupportsWindowFeatureImpl(WindowFeature feature,
bool check_fullscreen) const; bool check_can_support) const;
// Resets |bookmark_bar_state_| based on the active tab. Notifies the // Resets |bookmark_bar_state_| based on the active tab. Notifies the
// BrowserWindow if necessary. // BrowserWindow if necessary.

View file

@ -43,6 +43,7 @@
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
#include "ui/base/resource/scoped_startup_resource_bundle.h" #include "ui/base/resource/scoped_startup_resource_bundle.h"
#include "ui/views/views_switches.h"
#if BUILDFLAG(IS_ANDROID) #if BUILDFLAG(IS_ANDROID)
#include "chrome/browser/android/flags/bad_flags_snackbar_manager.h" #include "chrome/browser/android/flags/bad_flags_snackbar_manager.h"
@ -131,7 +132,7 @@ static const char* kBadFlags[] = {
// updating components won't be performed until shutdown. // updating components won't be performed until shutdown.
switches::kDisableBestEffortTasks, switches::kDisableBestEffortTasks,
// GPU sanboxing isn't implemented for the Web GPU API yet meaning it would // GPU sandboxing isn't implemented for the Web GPU API yet meaning it would
// be possible to read GPU data for other Chromium processes. // be possible to read GPU data for other Chromium processes.
// switches::kEnableUnsafeWebGPU, (Disabled by Alex313031) // switches::kEnableUnsafeWebGPU, (Disabled by Alex313031)
@ -158,6 +159,10 @@ static const char* kBadFlags[] = {
// learning model output used by the History Clusters service and should // learning model output used by the History Clusters service and should
// only be used for testing purposes. // only be used for testing purposes.
history_clusters::switches::kClustersOverrideFile, history_clusters::switches::kClustersOverrideFile,
// This flag disables protection against potentially unintentional user
// interaction with certain UI elements.
views::switches::kDisableInputEventActivationProtectionForTesting,
}; };
#endif // !BUILDFLAG(IS_ANDROID) #endif // !BUILDFLAG(IS_ANDROID)

View file

@ -17,12 +17,6 @@
#include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
namespace gfx {
class Canvas;
}
class SkPath;
// Holds the basic logic for rendering tabs, including preferred sizes, paths, // Holds the basic logic for rendering tabs, including preferred sizes, paths,
// etc. // etc.
class TabStyle { class TabStyle {
@ -108,94 +102,56 @@ class TabStyle {
TabStyle& operator=(const TabStyle&) = delete; TabStyle& operator=(const TabStyle&) = delete;
virtual ~TabStyle(); virtual ~TabStyle();
// Gets the specific |path_type| associated with the specific |tab|.
// If |force_active| is true, applies an active appearance on the tab (usually
// involving painting an optional stroke) even if the tab is not the active
// tab.
virtual SkPath GetPath(
PathType path_type,
float scale,
bool force_active = false,
RenderUnits render_units = RenderUnits::kPixels) const = 0;
// Returns the insets to use for laying out tab contents.
virtual gfx::Insets GetContentsInsets() const = 0;
// Returns the z-value of the tab, which should be used to paint them in
// ascending order. Return values are in the range (0,
// TabStyle::GetMaximumZValue()).
virtual float GetZValue() const = 0;
// Returns the current opacity of the "active" portion of the tab's state.
virtual float GetActiveOpacity() const = 0;
// Returns whichever of (active, inactive) the tab appears more like given the
// active opacity.
virtual TabActive GetApparentActiveState() const = 0;
// Derives and returns colors for the tab. See TabColors, above.
virtual TabColors CalculateColors() const = 0;
// Returns the appropriate fonts for the current theme and active state. // Returns the appropriate fonts for the current theme and active state.
virtual const gfx::FontList& GetFontList() const = 0; virtual const gfx::FontList& GetFontList() const = 0;
// Paints the tab.
virtual void PaintTab(gfx::Canvas* canvas) const = 0;
// Sets the center of the radial highlight in the hover animation.
virtual void SetHoverLocation(const gfx::Point& location) = 0;
// Shows the hover animation.
virtual void ShowHover(ShowHoverStyle style) = 0;
// Hides the hover animation.
virtual void HideHover(HideHoverStyle style) = 0;
// Opacity of the active tab background painted over inactive selected tabs.
static constexpr float kSelectedTabOpacity = 0.75f;
// Returns the preferred width of a single Tab, assuming space is // Returns the preferred width of a single Tab, assuming space is
// available. // available.
static int GetStandardWidth(); virtual int GetStandardWidth() const = 0;
// Returns the width for pinned tabs. Pinned tabs always have this width. // Returns the width for pinned tabs. Pinned tabs always have this width.
static int GetPinnedWidth(); virtual int GetPinnedWidth() const = 0;
// Returns the overlap between adjacent tabs. // Returns the overlap between adjacent tabs.
static int GetTabOverlap(); virtual int GetTabOverlap() const = 0;
// Get the space only partially occupied by a tab that we should
// consider to be padding rather than part of the body of the tab for
// interaction purposes.
static gfx::Insets GetTabInternalPadding();
// Gets the size of the separator drawn between tabs, if any. // Gets the size of the separator drawn between tabs, if any.
static gfx::Size GetSeparatorSize(); virtual gfx::Size GetSeparatorSize() const = 0;
// Returns, for a tab of height |height|, how far the window top drag handle // Returns, for a tab of height |height|, how far the window top drag handle
// can extend down into inactive tabs or the new tab button. This behavior // can extend down into inactive tabs or the new tab button. This behavior
// is not used in all cases. // is not used in all cases.
static int GetDragHandleExtension(int height); virtual int GetDragHandleExtension(int height) const = 0;
// Gets the preferred size for tab previews, which could be screencaps, hero // Gets the preferred size for tab previews, which could be screencaps, hero
// or og:image images, etc. // or og:image images, etc.
static gfx::Size GetPreviewImageSize(); virtual gfx::Size GetPreviewImageSize() const = 0;
// Returns the radius of the outer corners of the tab shape. // Returns the radius of the outer corners of the tab shape.
static int GetCornerRadius(); virtual int GetTopCornerRadius() const = 0;
// Returns the radius of the outer corners of the tab shape.
virtual int GetBottomCornerRadius() const = 0;
// Opacity of the active tab background painted over inactive selected tabs.
virtual float GetSelectedTabOpacity() const = 0;
// The largest valid value of TabStyle::GetZValue(). Currently, // The largest valid value of TabStyle::GetZValue(). Currently,
// GM2TabStyle::GetZValue is the only implementation, and it can't return // GM2TabStyle::GetZValue is the only implementation, and it can't return
// values larger than 7. // values larger than 7.
static constexpr float kMaximumZValue = 7.0f; static constexpr float kMaximumZValue = 7.0f;
protected: static constexpr float kDefaultSelectedTabOpacity = 0.75f;
// Avoid implicitly-deleted constructor.
TabStyle() = default; static const TabStyle* Get();
// Returns how far from the leading and trailing edges of a tab the contents // Returns how far from the leading and trailing edges of a tab the contents
// should actually be laid out. // should actually be laid out.
static int GetContentsHorizontalInsetSize(); int GetContentsHorizontalInsetSize() const;
protected:
// Avoid implicitly-deleted constructor.
TabStyle() = default;
}; };
#endif // CHROME_BROWSER_UI_TABS_TAB_STYLE_H_ #endif // CHROME_BROWSER_UI_TABS_TAB_STYLE_H_

View file

@ -20,6 +20,7 @@
#include "components/google/core/common/google_util.h" #include "components/google/core/common/google_util.h"
#include "components/offline_pages/buildflags/buildflags.h" #include "components/offline_pages/buildflags/buildflags.h"
#include "components/omnibox/browser/autocomplete_input.h" #include "components/omnibox/browser/autocomplete_input.h"
#include "components/omnibox/browser/omnibox_field_trial.h"
#include "components/omnibox/browser/omnibox_prefs.h" #include "components/omnibox/browser/omnibox_prefs.h"
#include "components/omnibox/common/omnibox_features.h" #include "components/omnibox/common/omnibox_features.h"
#include "components/pref_registry/pref_registry_syncable.h" #include "components/pref_registry/pref_registry_syncable.h"
@ -37,6 +38,7 @@
#if !BUILDFLAG(IS_ANDROID) #if !BUILDFLAG(IS_ANDROID)
#include "components/omnibox/browser/vector_icons.h" // nogncheck #include "components/omnibox/browser/vector_icons.h" // nogncheck
#include "components/vector_icons/vector_icons.h" // nogncheck
#endif #endif
#if BUILDFLAG(ENABLE_OFFLINE_PAGES) #if BUILDFLAG(ENABLE_OFFLINE_PAGES)
@ -183,11 +185,17 @@ const gfx::VectorIcon* ChromeLocationBarModelDelegate::GetVectorIconOverride()
GURL url; GURL url;
GetURL(&url); GetURL(&url);
if (url.SchemeIs(content::kChromeUIScheme)) if (url.SchemeIs(content::kChromeUIScheme)) {
return &omnibox::kProductIcon; return (OmniboxFieldTrial::IsChromeRefreshIconsEnabled())
? &omnibox::kProductChromeRefreshIcon
: &omnibox::kProductIcon;
}
if (url.SchemeIs(extensions::kExtensionScheme)) if (url.SchemeIs(extensions::kExtensionScheme)) {
return &omnibox::kExtensionAppIcon; return (OmniboxFieldTrial::IsChromeRefreshIconsEnabled())
? &vector_icons::kExtensionChromeRefreshIcon
: &omnibox::kExtensionAppIcon;
}
#endif #endif
return nullptr; return nullptr;

View file

@ -370,7 +370,7 @@ void BrowserRootView::PaintChildren(const views::PaintInfo& paint_info) {
// view. // view.
if (browser_view_->immersive_mode_controller()->IsRevealed()) { if (browser_view_->immersive_mode_controller()->IsRevealed()) {
tabstrip_root = tabstrip_root =
base::FeatureList::IsEnabled(features::kImmersiveFullscreenTabs) browser_view_->UsesImmersiveFullscreenTabbedMode()
? browser_view_->tab_overlay_widget()->GetRootView() ? browser_view_->tab_overlay_widget()->GetRootView()
: browser_view_->overlay_widget()->GetRootView(); : browser_view_->overlay_widget()->GetRootView();
} }

View file

@ -13,9 +13,9 @@
#include "base/debug/alias.h" #include "base/debug/alias.h"
#include "base/functional/bind.h" #include "base/functional/bind.h"
#include "base/command_line.h"
#include "base/i18n/rtl.h" #include "base/i18n/rtl.h"
#include "base/memory/raw_ptr.h" #include "base/memory/raw_ptr.h"
#include "base/command_line.h"
#include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics.h"
#include "base/numerics/safe_conversions.h" #include "base/numerics/safe_conversions.h"
#include "base/scoped_observation.h" #include "base/scoped_observation.h"
@ -124,8 +124,8 @@ int Center(int size, int item_size) {
class TabStyleHighlightPathGenerator : public views::HighlightPathGenerator { class TabStyleHighlightPathGenerator : public views::HighlightPathGenerator {
public: public:
explicit TabStyleHighlightPathGenerator(TabStyle* tab_style) explicit TabStyleHighlightPathGenerator(TabStyleViews* tab_style_views)
: tab_style_(tab_style) {} : tab_style_views_(tab_style_views) {}
TabStyleHighlightPathGenerator(const TabStyleHighlightPathGenerator&) = TabStyleHighlightPathGenerator(const TabStyleHighlightPathGenerator&) =
delete; delete;
TabStyleHighlightPathGenerator& operator=( TabStyleHighlightPathGenerator& operator=(
@ -133,11 +133,11 @@ class TabStyleHighlightPathGenerator : public views::HighlightPathGenerator {
// views::HighlightPathGenerator: // views::HighlightPathGenerator:
SkPath GetHighlightPath(const views::View* view) override { SkPath GetHighlightPath(const views::View* view) override {
return tab_style_->GetPath(TabStyle::PathType::kHighlight, 1.0); return tab_style_views_->GetPath(TabStyle::PathType::kHighlight, 1.0);
} }
private: private:
const raw_ptr<TabStyle, DanglingUntriaged> tab_style_; const raw_ptr<TabStyleViews, DanglingUntriaged> tab_style_views_;
}; };
} // namespace } // namespace
@ -195,7 +195,7 @@ Tab::Tab(TabSlotController* controller)
title_animation_(this) { title_animation_(this) {
DCHECK(controller); DCHECK(controller);
tab_style_ = TabStyleViews::CreateForTab(this); tab_style_views_ = TabStyleViews::Create()->CreateForTab(this);
// So we get don't get enter/exit on children and don't prematurely stop the // So we get don't get enter/exit on children and don't prematurely stop the
// hover. // hover.
@ -205,7 +205,7 @@ Tab::Tab(TabSlotController* controller)
// This will cause calls to GetContentsBounds to return only the rectangle // This will cause calls to GetContentsBounds to return only the rectangle
// inside the tab shape, rather than to its extents. // inside the tab shape, rather than to its extents.
SetBorder(views::CreateEmptyBorder(tab_style()->GetContentsInsets())); SetBorder(views::CreateEmptyBorder(tab_style_views()->GetContentsInsets()));
title_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD); title_->SetHorizontalAlignment(gfx::ALIGN_TO_HEAD);
title_->SetElideBehavior(gfx::FADE_TAIL); title_->SetElideBehavior(gfx::FADE_TAIL);
@ -246,7 +246,8 @@ Tab::Tab(TabSlotController* controller)
SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY);
views::FocusRing::Install(this); views::FocusRing::Install(this);
views::HighlightPathGenerator::Install( views::HighlightPathGenerator::Install(
this, std::make_unique<TabStyleHighlightPathGenerator>(tab_style_.get())); this,
std::make_unique<TabStyleHighlightPathGenerator>(tab_style_views()));
SetProperty(views::kElementIdentifierKey, kTabElementId); SetProperty(views::kElementIdentifierKey, kTabElementId);
} }
@ -276,7 +277,7 @@ bool Tab::GetHitTestMask(SkPath* mask) const {
// When the window is maximized we don't want to shave off the edges or top // When the window is maximized we don't want to shave off the edges or top
// shadow of the tab, such that the user can click anywhere along the top // shadow of the tab, such that the user can click anywhere along the top
// edge of the screen to select a tab. Ditto for immersive fullscreen. // edge of the screen to select a tab. Ditto for immersive fullscreen.
*mask = tab_style()->GetPath( *mask = tab_style_views()->GetPath(
TabStyle::PathType::kHitTest, TabStyle::PathType::kHitTest,
GetWidget()->GetCompositor()->device_scale_factor(), GetWidget()->GetCompositor()->device_scale_factor(),
/* force_active */ false, TabStyle::RenderUnits::kDips); /* force_active */ false, TabStyle::RenderUnits::kDips);
@ -579,7 +580,7 @@ void Tab::OnMouseCaptureLost() {
} }
void Tab::OnMouseMoved(const ui::MouseEvent& event) { void Tab::OnMouseMoved(const ui::MouseEvent& event) {
tab_style_->SetHoverLocation(event.location()); tab_style_views()->SetHoverLocation(event.location());
controller_->OnMouseEventInTab(this, event); controller_->OnMouseEventInTab(this, event);
// Linux enter/leave events are sometimes flaky, so we don't want to "miss" // Linux enter/leave events are sometimes flaky, so we don't want to "miss"
@ -613,7 +614,7 @@ void Tab::MaybeUpdateHoverStatus(const ui::MouseEvent& event) {
#endif #endif
mouse_hovered_ = true; mouse_hovered_ = true;
tab_style_->ShowHover(TabStyle::ShowHoverStyle::kSubtle); tab_style_views()->ShowHover(TabStyle::ShowHoverStyle::kSubtle);
UpdateForegroundColors(); UpdateForegroundColors();
Layout(); Layout();
if (g_show_hover_card_on_mouse_hover) if (g_show_hover_card_on_mouse_hover)
@ -625,7 +626,7 @@ void Tab::OnMouseExited(const ui::MouseEvent& event) {
if (!mouse_hovered_) if (!mouse_hovered_)
return; return;
mouse_hovered_ = false; mouse_hovered_ = false;
tab_style_->HideHover(TabStyle::HideHoverStyle::kGradual); tab_style_views()->HideHover(TabStyle::HideHoverStyle::kGradual);
UpdateForegroundColors(); UpdateForegroundColors();
Layout(); Layout();
} }
@ -683,7 +684,8 @@ void Tab::GetAccessibleNodeData(ui::AXNodeData* node_data) {
} }
gfx::Size Tab::CalculatePreferredSize() const { gfx::Size Tab::CalculatePreferredSize() const {
return gfx::Size(TabStyle::GetStandardWidth(), GetLayoutConstant(TAB_HEIGHT)); return gfx::Size(tab_style()->GetStandardWidth(),
GetLayoutConstant(TAB_HEIGHT));
} }
void Tab::PaintChildren(const views::PaintInfo& info) { void Tab::PaintChildren(const views::PaintInfo& info) {
@ -694,7 +696,7 @@ void Tab::PaintChildren(const views::PaintInfo& info) {
// The paint recording scale for tabs is consistent along the x and y axis. // The paint recording scale for tabs is consistent along the x and y axis.
const float paint_recording_scale = info.paint_recording_scale_x(); const float paint_recording_scale = info.paint_recording_scale_x();
const SkPath clip_path = tab_style()->GetPath( const SkPath clip_path = tab_style_views()->GetPath(
TabStyle::PathType::kInteriorClip, paint_recording_scale); TabStyle::PathType::kInteriorClip, paint_recording_scale);
clip_recorder.ClipPathWithAntiAliasing(clip_path); clip_recorder.ClipPathWithAntiAliasing(clip_path);
@ -702,7 +704,7 @@ void Tab::PaintChildren(const views::PaintInfo& info) {
} }
void Tab::OnPaint(gfx::Canvas* canvas) { void Tab::OnPaint(gfx::Canvas* canvas) {
tab_style()->PaintTab(canvas); tab_style_views()->PaintTab(canvas);
} }
void Tab::AddedToWidget() { void Tab::AddedToWidget() {
@ -739,9 +741,10 @@ TabSlotView::ViewType Tab::GetTabSlotViewType() const {
} }
TabSizeInfo Tab::GetTabSizeInfo() const { TabSizeInfo Tab::GetTabSizeInfo() const {
return {TabStyle::GetPinnedWidth(), TabStyleViews::GetMinimumActiveWidth(), return {tab_style()->GetPinnedWidth(),
TabStyleViews::GetMinimumInactiveWidth(), tab_style_views()->GetMinimumActiveWidth(),
TabStyle::GetStandardWidth()}; tab_style_views()->GetMinimumInactiveWidth(),
tab_style()->GetStandardWidth()};
} }
void Tab::SetClosing(bool closing) { void Tab::SetClosing(bool closing) {
@ -805,8 +808,8 @@ SkColor Tab::GetAlertIndicatorColor(TabAlertState state) const {
{kColorTabAlertAudioPlayingActiveFrameInactive, {kColorTabAlertAudioPlayingActiveFrameInactive,
kColorTabAlertAudioPlayingActiveFrameActive}}}; kColorTabAlertAudioPlayingActiveFrameActive}}};
return color_provider->GetColor( return color_provider->GetColor(
color_ids[group] color_ids[group][tab_style_views()->GetApparentActiveState() ==
[tab_style_->GetApparentActiveState() == TabActive::kActive] TabActive::kActive]
[controller_->ShouldPaintAsActiveFrame()]); [controller_->ShouldPaintAsActiveFrame()]);
} }
@ -936,7 +939,7 @@ void Tab::MaybeAdjustLeftForPinnedTab(gfx::Rect* bounds,
int visual_width) const { int visual_width) const {
if (ShouldRenderAsNormalTab()) if (ShouldRenderAsNormalTab())
return; return;
const int pinned_width = TabStyle::GetPinnedWidth(); const int pinned_width = tab_style()->GetPinnedWidth();
const int ideal_delta = width() - pinned_width; const int ideal_delta = width() - pinned_width;
const int ideal_x = (pinned_width - visual_width) / 2; const int ideal_x = (pinned_width - visual_width) / 2;
// TODO(crbug.com/533570): This code is broken when the current width is less // TODO(crbug.com/533570): This code is broken when the current width is less
@ -1063,7 +1066,7 @@ void Tab::UpdateIconVisibility() {
} }
bool Tab::ShouldRenderAsNormalTab() const { bool Tab::ShouldRenderAsNormalTab() const {
return !data().pinned || (width() >= (TabStyle::GetPinnedWidth() + return !data().pinned || (width() >= (tab_style()->GetPinnedWidth() +
kPinnedTabExtraWidthToRenderAsNormal)); kPinnedTabExtraWidthToRenderAsNormal));
} }
@ -1092,13 +1095,15 @@ int Tab::GetWidthOfLargestSelectableRegion() const {
} }
void Tab::UpdateForegroundColors() { void Tab::UpdateForegroundColors() {
TabStyle::TabColors colors = tab_style_->CalculateColors(); TabStyle::TabColors colors = tab_style_views()->CalculateColors();
title_->SetEnabledColor(colors.foreground_color); title_->SetEnabledColor(colors.foreground_color);
close_button_->SetColors(colors); close_button_->SetColors(colors);
alert_indicator_button_->OnParentTabButtonColorChanged(); alert_indicator_button_->OnParentTabButtonColorChanged();
// There may be no focus ring when the tab is closing. // There may be no focus ring when the tab is closing.
if (auto* focus_ring = views::FocusRing::Get(this); focus_ring) if (auto* focus_ring = views::FocusRing::Get(this); focus_ring) {
focus_ring->SetColorId(colors.focus_ring_color); focus_ring->SetColorId(colors.focus_ring_color);
focus_ring->SetOutsetFocusRingDisabled(true);
}
SchedulePaint(); SchedulePaint();
} }

View file

@ -18,13 +18,12 @@
#include "base/containers/adapters.h" #include "base/containers/adapters.h"
#include "base/containers/contains.h" #include "base/containers/contains.h"
#include "base/containers/flat_map.h" #include "base/containers/flat_map.h"
#include "base/cxx17_backports.h"
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/functional/bind.h" #include "base/functional/bind.h"
#include "base/functional/callback.h" #include "base/functional/callback.h"
#include "base/command_line.h"
#include "base/i18n/rtl.h" #include "base/i18n/rtl.h"
#include "base/memory/raw_ptr.h" #include "base/memory/raw_ptr.h"
#include "base/command_line.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/metrics/histogram.h" #include "base/metrics/histogram.h"
#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_functions.h"
@ -68,7 +67,6 @@
#include "chrome/browser/ui/views/tabs/tab_strip_layout_types.h" #include "chrome/browser/ui/views/tabs/tab_strip_layout_types.h"
#include "chrome/browser/ui/views/tabs/tab_strip_observer.h" #include "chrome/browser/ui/views/tabs/tab_strip_observer.h"
#include "chrome/browser/ui/views/tabs/tab_strip_types.h" #include "chrome/browser/ui/views/tabs/tab_strip_types.h"
#include "chrome/browser/ui/views/tabs/tab_style_views.h"
#include "chrome/browser/ui/views/tabs/z_orderable_tab_container_element.h" #include "chrome/browser/ui/views/tabs/z_orderable_tab_container_element.h"
#include "chrome/browser/ui/views/touch_uma/touch_uma.h" #include "chrome/browser/ui/views/touch_uma/touch_uma.h"
#include "chrome/browser/ui/web_applications/app_browser_controller.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h"
@ -88,6 +86,7 @@
#include "ui/base/models/list_selection_model.h" #include "ui/base/models/list_selection_model.h"
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
#include "ui/base/theme_provider.h" #include "ui/base/theme_provider.h"
#include "ui/base/ui_base_features.h"
#include "ui/color/color_provider.h" #include "ui/color/color_provider.h"
#include "ui/display/display.h" #include "ui/display/display.h"
#include "ui/gfx/animation/throb_animation.h" #include "ui/gfx/animation/throb_animation.h"
@ -131,8 +130,7 @@ std::unique_ptr<TabContainer> MakeTabContainer(
TabDragContext* drag_context) { TabDragContext* drag_context) {
if (base::FeatureList::IsEnabled(features::kSplitTabStrip)) { if (base::FeatureList::IsEnabled(features::kSplitTabStrip)) {
return std::make_unique<CompoundTabContainer>( return std::make_unique<CompoundTabContainer>(
raw_ref<TabContainerController>::from_ptr(tab_strip), *tab_strip, hover_card_controller, drag_context, *tab_strip, tab_strip);
hover_card_controller, drag_context, *tab_strip, tab_strip);
} }
return std::make_unique<TabContainerImpl>( return std::make_unique<TabContainerImpl>(
*tab_strip, hover_card_controller, drag_context, *tab_strip, tab_strip); *tab_strip, hover_card_controller, drag_context, *tab_strip, tab_strip);
@ -453,7 +451,7 @@ class TabStrip::TabDragContextImpl : public TabDragContext,
constexpr int kHorizontalMoveThreshold = 16; // DIPs. constexpr int kHorizontalMoveThreshold = 16; // DIPs.
double ratio = static_cast<double>(tab_strip_->GetInactiveTabWidth()) / double ratio = static_cast<double>(tab_strip_->GetInactiveTabWidth()) /
TabStyle::GetStandardWidth(); TabStyle::Get()->GetStandardWidth();
return base::ClampRound(ratio * kHorizontalMoveThreshold); return base::ClampRound(ratio * kHorizontalMoveThreshold);
} }
@ -492,7 +490,7 @@ class TabStrip::TabDragContextImpl : public TabDragContext,
DCHECK(!views.empty()); DCHECK(!views.empty());
std::vector<gfx::Rect> bounds; std::vector<gfx::Rect> bounds;
const int overlap = TabStyle::GetTabOverlap(); const int overlap = TabStyle::Get()->GetTabOverlap();
int x = 0; int x = 0;
for (const TabSlotView* view : views) { for (const TabSlotView* view : views) {
const int width = view->width(); const int width = view->width();
@ -835,7 +833,7 @@ class TabStrip::TabDragContextImpl : public TabDragContext,
if (candidate_index == 0) if (candidate_index == 0)
return 0; return 0;
const int tab_overlap = TabStyle::GetTabOverlap(); const int tab_overlap = TabStyle::Get()->GetTabOverlap();
// We'll insert just right of the tab at |candidate_index| - 1. // We'll insert just right of the tab at |candidate_index| - 1.
int ideal_x = int ideal_x =
@ -874,7 +872,7 @@ class TabStrip::TabDragContextImpl : public TabDragContext,
return 0; return 0;
const int header_width = const int header_width =
GetTabGroupHeader(*right_group)->bounds().width() - GetTabGroupHeader(*right_group)->bounds().width() -
TabStyle::GetTabOverlap(); TabStyle::Get()->GetTabOverlap();
return header_width; return header_width;
} }
} }
@ -911,7 +909,8 @@ TabStrip::TabStrip(std::unique_ptr<TabStripController> controller)
*AddChildViewAt(MakeTabContainer(this, *AddChildViewAt(MakeTabContainer(this,
hover_card_controller_.get(), hover_card_controller_.get(),
base::to_address(drag_context_)), base::to_address(drag_context_)),
0)) { 0)),
style_(TabStyle::Get()) {
// TODO(pbos): This is probably incorrect, the background of individual tabs // TODO(pbos): This is probably incorrect, the background of individual tabs
// depend on their selected state. This should probably be pushed down into // depend on their selected state. This should probably be pushed down into
// tabs. // tabs.
@ -955,7 +954,7 @@ int TabStrip::GetSizeNeededForViews(const std::vector<TabSlotView*>& views) {
for (const TabSlotView* view : views) for (const TabSlotView* view : views)
width += view->width(); width += view->width();
if (!views.empty()) if (!views.empty())
width -= TabStyle::GetTabOverlap() * (views.size() - 1); width -= TabStyle::Get()->GetTabOverlap() * (views.size() - 1);
return width; return width;
} }
@ -1153,8 +1152,16 @@ void TabStrip::OnGroupClosed(const tab_groups::TabGroupId& group) {
bool TabStrip::ShouldDrawStrokes() const { bool TabStrip::ShouldDrawStrokes() const {
// If the controller says we can't draw strokes, don't. // If the controller says we can't draw strokes, don't.
if (!controller_->CanDrawStrokes()) if (!controller_->CanDrawStrokes()) {
return false; return false;
}
// The Tabstrip in the refreshed style does not meet the contrast ratio
// requirements listed below but does not have strokes for Tabs or the bottom
// border.
if (features::IsChromeRefresh2023()) {
return false;
}
// The tabstrip normally avoids strokes and relies on the active tab // The tabstrip normally avoids strokes and relies on the active tab
// contrasting sufficiently with the frame background. When there isn't // contrasting sufficiently with the frame background. When there isn't
@ -1324,7 +1331,7 @@ absl::optional<int> TabStrip::GetFocusedTabIndex() const {
} }
views::View* TabStrip::GetTabViewForPromoAnchor(int index_hint) { views::View* TabStrip::GetTabViewForPromoAnchor(int index_hint) {
return tab_at(base::clamp(index_hint, 0, GetTabCount() - 1)); return tab_at(std::clamp(index_hint, 0, GetTabCount() - 1));
} }
views::View* TabStrip::GetDefaultFocusableChild() { views::View* TabStrip::GetDefaultFocusableChild() {

View file

@ -7,7 +7,6 @@
#include <algorithm> #include <algorithm>
#include <utility> #include <utility>
#include "base/cxx17_backports.h"
#include "base/i18n/rtl.h" #include "base/i18n/rtl.h"
#include "base/memory/raw_ptr.h" #include "base/memory/raw_ptr.h"
#include "base/numerics/safe_conversions.h" #include "base/numerics/safe_conversions.h"
@ -19,6 +18,7 @@
#include "chrome/browser/ui/color/chrome_color_id.h" #include "chrome/browser/ui/color/chrome_color_id.h"
#include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/layout_constants.h"
#include "chrome/browser/ui/tabs/tab_types.h" #include "chrome/browser/ui/tabs/tab_types.h"
#include "chrome/browser/ui/tabs/tab_style.h"
#include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/views/frame/browser_non_client_frame_view.h" #include "chrome/browser/ui/views/frame/browser_non_client_frame_view.h"
#include "chrome/browser/ui/views/tabs/glow_hover_controller.h" #include "chrome/browser/ui/views/tabs/glow_hover_controller.h"
@ -32,6 +32,7 @@
#include "third_party/skia/include/core/SkScalar.h" #include "third_party/skia/include/core/SkScalar.h"
#include "third_party/skia/include/pathops/SkPathOps.h" #include "third_party/skia/include/pathops/SkPathOps.h"
#include "ui/base/theme_provider.h" #include "ui/base/theme_provider.h"
#include "ui/base/ui_base_features.h"
#include "ui/gfx/canvas.h" #include "ui/gfx/canvas.h"
#include "ui/gfx/font_list.h" #include "ui/gfx/font_list.h"
#include "ui/gfx/geometry/skia_conversions.h" #include "ui/gfx/geometry/skia_conversions.h"
@ -50,20 +51,33 @@ constexpr ShapeModifier kNoLowerLeftArc = 0x01;
// Exclude the lower right arc. // Exclude the lower right arc.
constexpr ShapeModifier kNoLowerRightArc = 0x02; constexpr ShapeModifier kNoLowerRightArc = 0x02;
// Updates a target value, returning true if it changed.
template <class T>
bool UpdateValue(T* dest, const T& src) {
if (*dest == src) {
return false;
}
*dest = src;
return true;
}
// Tab style implementation for the GM2 refresh (Chrome 69). // Tab style implementation for the GM2 refresh (Chrome 69).
class GM2TabStyle : public TabStyleViews { class GM2TabStyleViews : public TabStyleViews {
public: public:
explicit GM2TabStyle(Tab* tab); explicit GM2TabStyleViews(Tab* tab);
GM2TabStyle(const GM2TabStyle&) = delete; ~GM2TabStyleViews() override = default;
GM2TabStyle& operator=(const GM2TabStyle&) = delete; GM2TabStyleViews(const GM2TabStyleViews&) = delete;
GM2TabStyleViews& operator=(const GM2TabStyleViews&) = delete;
const Tab* tab() const { return tab_; }
protected: protected:
// TabStyle: // TabStyle:
SkPath GetPath( SkPath GetPath(TabStyle::PathType path_type,
PathType path_type,
float scale, float scale,
bool force_active = false, bool force_active = false,
RenderUnits render_units = RenderUnits::kPixels) const override; TabStyle::RenderUnits render_units =
TabStyle::RenderUnits::kPixels) const override;
gfx::Insets GetContentsInsets() const override; gfx::Insets GetContentsInsets() const override;
float GetZValue() const override; float GetZValue() const override;
float GetActiveOpacity() const override; float GetActiveOpacity() const override;
@ -72,17 +86,35 @@ class GM2TabStyle : public TabStyleViews {
const gfx::FontList& GetFontList() const override; const gfx::FontList& GetFontList() const override;
void PaintTab(gfx::Canvas* canvas) const override; void PaintTab(gfx::Canvas* canvas) const override;
void SetHoverLocation(const gfx::Point& location) override; void SetHoverLocation(const gfx::Point& location) override;
void ShowHover(ShowHoverStyle style) override; void ShowHover(TabStyle::ShowHoverStyle style) override;
void HideHover(HideHoverStyle style) override; void HideHover(TabStyle::HideHoverStyle style) override;
// Returns the color for the separator.
virtual SkColor GetTabSeparatorColor() const;
// Painting helper functions:
virtual SkColor GetTabBackgroundColor(TabActive active) const;
// Returns the thickness of the stroke drawn around the top and sides of the
// tab. Only active tabs may have a stroke, and not in all cases. If there
// is no stroke, returns 0. If |should_paint_as_active| is true, the tab is
// treated as an active tab regardless of its true current state.
virtual int GetStrokeThickness(bool should_paint_as_active = false) const;
virtual bool ShouldPaintTabBackgroundColor(TabActive active,
bool has_custom_background) const;
// Returns the progress (0 to 1) of the hover animation.
double GetHoverAnimationValue() const override;
private: private:
// Gets the bounds for the leading and trailing separators for a tab. // Gets the bounds for the leading and trailing separators for a tab.
SeparatorBounds GetSeparatorBounds(float scale) const; TabStyle::SeparatorBounds GetSeparatorBounds(float scale) const;
// Returns the opacities of the separators. If |for_layout| is true, returns // Returns the opacities of the separators. If |for_layout| is true, returns
// the "layout" opacities, which ignore the effects of surrounding tabs' hover // the "layout" opacities, which ignore the effects of surrounding tabs' hover
// effects and consider only the current tab's state. // effects and consider only the current tab's state.
SeparatorOpacities GetSeparatorOpacities(bool for_layout) const; TabStyle::SeparatorOpacities GetSeparatorOpacities(bool for_layout) const;
// Returns a single separator's opacity based on whether it is the // Returns a single separator's opacity based on whether it is the
// logically |leading| separator. |for_layout| has the same meaning as in // logically |leading| separator. |for_layout| has the same meaning as in
@ -102,9 +134,6 @@ class GM2TabStyle : public TabStyleViews {
// Returns whether the hover animation is being shown. // Returns whether the hover animation is being shown.
bool IsHoverActive() const; bool IsHoverActive() const;
// Returns the progress (0 to 1) of the hover animation.
double GetHoverAnimationValue() const;
// Returns the opacity of the hover effect that should be drawn, which may not // Returns the opacity of the hover effect that should be drawn, which may not
// be the same as GetHoverAnimationValue. // be the same as GetHoverAnimationValue.
float GetHoverOpacity() const; float GetHoverOpacity() const;
@ -112,22 +141,11 @@ class GM2TabStyle : public TabStyleViews {
// Gets the throb value. A value of 0 indicates no throbbing. // Gets the throb value. A value of 0 indicates no throbbing.
float GetThrobValue() const; float GetThrobValue() const;
// Returns the thickness of the stroke drawn around the top and sides of the
// tab. Only active tabs may have a stroke, and not in all cases. If there
// is no stroke, returns 0. If |should_paint_as_active| is true, the tab is
// treated as an active tab regardless of its true current state.
int GetStrokeThickness(bool should_paint_as_active = false) const;
bool ShouldPaintTabBackgroundColor(TabActive active,
bool has_custom_background) const;
SkColor GetTabBackgroundColor(TabActive active) const;
// When selected, non-active, non-hovered tabs are adjacent to each other, // When selected, non-active, non-hovered tabs are adjacent to each other,
// there are anti-aliasing artifacts in the overlapped lower arc region. This // there are anti-aliasing artifacts in the overlapped lower arc region. This
// returns how to modify the tab shape to eliminate the lower arcs on the // returns how to modify the tab shape to eliminate the lower arcs on the
// right or left based on the state of the adjacent tab(s). // right or left based on the state of the adjacent tab(s).
ShapeModifier GetShapeModifier(PathType path_type) const; ShapeModifier GetShapeModifier(TabStyle::PathType path_type) const;
// Painting helper functions: // Painting helper functions:
void PaintInactiveTabBackground(gfx::Canvas* canvas) const; void PaintInactiveTabBackground(gfx::Canvas* canvas) const;
@ -140,19 +158,20 @@ class GM2TabStyle : public TabStyleViews {
bool paint_hover_effect, bool paint_hover_effect,
absl::optional<int> fill_id, absl::optional<int> fill_id,
int y_inset) const; int y_inset) const;
virtual void PaintBackgroundHover(gfx::Canvas* canvas, float scale) const;
void PaintBackgroundStroke(gfx::Canvas* canvas, void PaintBackgroundStroke(gfx::Canvas* canvas,
TabActive active, TabActive active,
SkColor stroke_color) const; SkColor stroke_color) const;
void PaintSeparators(gfx::Canvas* canvas) const; void PaintSeparators(gfx::Canvas* canvas) const;
// Given a tab of width |width|, returns the radius to use for the corners. // Given a tab of width |width|, returns the radius to use for the corners.
static float GetTopCornerRadiusForWidth(int width); virtual float GetTopCornerRadiusForWidth(int width) const;
// Scales |bounds| by scale and aligns so that adjacent tabs meet up exactly // Scales |bounds| by scale and aligns so that adjacent tabs meet up exactly
// during painting. // during painting.
static gfx::RectF ScaleAndAlignBounds(const gfx::Rect& bounds, gfx::RectF ScaleAndAlignBounds(const gfx::Rect& bounds,
float scale, float scale,
int stroke_thickness); int stroke_thickness) const;
const raw_ptr<const Tab> tab_; const raw_ptr<const Tab> tab_;
@ -161,37 +180,11 @@ class GM2TabStyle : public TabStyleViews {
gfx::FontList heavy_font_; gfx::FontList heavy_font_;
}; };
void DrawHighlight(gfx::Canvas* canvas,
const SkPoint& p,
SkScalar radius,
SkColor color) {
// TODO(crbug/1308932): Remove FromColor and make all SkColor4f.
const SkColor4f colors[2] = {
SkColor4f::FromColor(color),
SkColor4f::FromColor(SkColorSetA(color, SK_AlphaTRANSPARENT))};
cc::PaintFlags flags;
flags.setAntiAlias(true);
flags.setShader(cc::PaintShader::MakeRadialGradient(
p, radius, colors, nullptr, 2, SkTileMode::kClamp));
canvas->sk_canvas()->drawRect(
SkRect::MakeXYWH(p.x() - radius, p.y() - radius, radius * 2, radius * 2),
flags);
}
// Updates a target value, returning true if it changed.
template <class T>
bool UpdateValue(T* dest, const T& src) {
if (*dest == src)
return false;
*dest = src;
return true;
}
// GM2TabStyle ----------------------------------------------------------------- // GM2TabStyle -----------------------------------------------------------------
GM2TabStyle::GM2TabStyle(Tab* tab) GM2TabStyleViews::GM2TabStyleViews(Tab* tab)
: tab_(tab), : tab_(tab),
hover_controller_(gfx::Animation::ShouldRenderRichAnimation() hover_controller_((tab && gfx::Animation::ShouldRenderRichAnimation())
? new GlowHoverController(tab) ? new GlowHoverController(tab)
: nullptr), : nullptr),
normal_font_(views::style::GetFont(views::style::CONTEXT_LABEL, normal_font_(views::style::GetFont(views::style::CONTEXT_LABEL,
@ -202,10 +195,11 @@ GM2TabStyle::GM2TabStyle(Tab* tab)
// repurposing CONTEXT_BUTTON_MD. // repurposing CONTEXT_BUTTON_MD.
} }
SkPath GM2TabStyle::GetPath(PathType path_type, SkPath GM2TabStyleViews::GetPath(TabStyle::PathType path_type,
float scale, float scale,
bool force_active, bool force_active,
RenderUnits render_units) const { TabStyle::RenderUnits render_units) const {
CHECK(tab());
const int stroke_thickness = GetStrokeThickness(force_active); const int stroke_thickness = GetStrokeThickness(force_active);
// We'll do the entire path calculation in aligned pixels. // We'll do the entire path calculation in aligned pixels.
@ -214,7 +208,7 @@ SkPath GM2TabStyle::GetPath(PathType path_type,
gfx::RectF aligned_bounds = gfx::RectF aligned_bounds =
ScaleAndAlignBounds(tab_->bounds(), scale, stroke_thickness); ScaleAndAlignBounds(tab_->bounds(), scale, stroke_thickness);
if (path_type == PathType::kInteriorClip) { if (path_type == TabStyle::PathType::kInteriorClip) {
// When there is a separator, animate the clip to account for it, in sync // When there is a separator, animate the clip to account for it, in sync
// with the separator's fading. // with the separator's fading.
// TODO(pkasting): Consider crossfading the favicon instead of animating // TODO(pkasting): Consider crossfading the favicon instead of animating
@ -228,13 +222,12 @@ SkPath GM2TabStyle::GetPath(PathType path_type,
// Calculate the corner radii. Note that corner radius is based on original // Calculate the corner radii. Note that corner radius is based on original
// tab width (in DIP), not our new, scaled-and-aligned bounds. // tab width (in DIP), not our new, scaled-and-aligned bounds.
const float radius = GetTopCornerRadiusForWidth(tab_->width()) * scale; float top_radius = GetTopCornerRadiusForWidth(tab_->width()) * scale;
float top_radius = radius; float bottom_radius = tab_style()->GetBottomCornerRadius() * scale;
float bottom_radius = radius;
// Compute |extension| as the width outside the separators. This is a fixed // Compute |extension| as the width outside the separators. This is a fixed
// value equal to the normal corner radius. // value equal to the normal corner radius.
const float extension = GetCornerRadius() * scale; const float extension = bottom_radius;
// Calculate the bounds of the actual path. // Calculate the bounds of the actual path.
const float left = aligned_bounds.x(); const float left = aligned_bounds.x();
@ -253,20 +246,21 @@ SkPath GM2TabStyle::GetPath(PathType path_type,
// Path-specific adjustments: // Path-specific adjustments:
const float stroke_adjustment = stroke_thickness * scale; const float stroke_adjustment = stroke_thickness * scale;
bool extend_to_top = false; bool extend_to_top = false;
if (path_type == PathType::kInteriorClip) { if (path_type == TabStyle::PathType::kInteriorClip) {
// Inside of the border runs |stroke_thickness| inside the outer edge. // Inside of the border runs |stroke_thickness| inside the outer edge.
tab_left += stroke_adjustment; tab_left += stroke_adjustment;
tab_right -= stroke_adjustment; tab_right -= stroke_adjustment;
tab_top += stroke_adjustment; tab_top += stroke_adjustment;
top_radius -= stroke_adjustment; top_radius -= stroke_adjustment;
} else if (path_type == PathType::kFill || path_type == PathType::kBorder) { } else if (path_type == TabStyle::PathType::kFill ||
path_type == TabStyle::PathType::kBorder) {
tab_left += 0.5f * stroke_adjustment; tab_left += 0.5f * stroke_adjustment;
tab_right -= 0.5f * stroke_adjustment; tab_right -= 0.5f * stroke_adjustment;
tab_top += 0.5f * stroke_adjustment; tab_top += 0.5f * stroke_adjustment;
top_radius -= 0.5f * stroke_adjustment; top_radius -= 0.5f * stroke_adjustment;
tab_bottom -= 0.5f * stroke_adjustment; tab_bottom -= 0.5f * stroke_adjustment;
bottom_radius -= 0.5f * stroke_adjustment; bottom_radius -= 0.5f * stroke_adjustment;
} else if (path_type == PathType::kHitTest) { } else if (path_type == TabStyle::PathType::kHitTest) {
// Outside border needs to draw its bottom line a stroke width above the // Outside border needs to draw its bottom line a stroke width above the
// bottom of the tab, to line up with the stroke that runs across the rest // bottom of the tab, to line up with the stroke that runs across the rest
// of the bottom of the tab bar (when strokes are enabled). // of the bottom of the tab bar (when strokes are enabled).
@ -290,10 +284,10 @@ SkPath GM2TabStyle::GetPath(PathType path_type,
SkPath path; SkPath path;
if (path_type == PathType::kInteriorClip) { if (path_type == TabStyle::PathType::kInteriorClip) {
// Clip path is a simple rectangle. // Clip path is a simple rectangle.
path.addRect(tab_left, tab_top, tab_right, tab_bottom); path.addRect(tab_left, tab_top, tab_right, tab_bottom);
} else if (path_type == PathType::kHighlight) { } else if (path_type == TabStyle::PathType::kHighlight) {
// The path is a round rect inset by the focus ring thickness. The // The path is a round rect inset by the focus ring thickness. The
// radius is also adjusted by the inset. // radius is also adjusted by the inset.
const float inset = views::FocusRing::kDefaultHaloThickness + const float inset = views::FocusRing::kDefaultHaloThickness +
@ -301,7 +295,7 @@ SkPath GM2TabStyle::GetPath(PathType path_type,
SkRRect rrect = SkRRect::MakeRectXY( SkRRect rrect = SkRRect::MakeRectXY(
SkRect::MakeLTRB(tab_left + inset, tab_top + inset, tab_right - inset, SkRect::MakeLTRB(tab_left + inset, tab_top + inset, tab_right - inset,
tab_bottom - inset), tab_bottom - inset),
radius - inset, radius - inset); top_radius - inset, top_radius - inset);
path.addRRect(rrect); path.addRRect(rrect);
} else { } else {
// Avoid mallocs at every new path verb by preallocating an // Avoid mallocs at every new path verb by preallocating an
@ -395,9 +389,10 @@ SkPath GM2TabStyle::GetPath(PathType path_type,
// ┌─╯ ╰─┓ // ┌─╯ ╰─┓
path.lineTo(right, extended_bottom); path.lineTo(right, extended_bottom);
if (path_type != PathType::kBorder) if (path_type != TabStyle::PathType::kBorder) {
path.close(); path.close();
} }
}
// Convert path to be relative to the tab origin. // Convert path to be relative to the tab origin.
gfx::PointF origin(tab_->origin()); gfx::PointF origin(tab_->origin());
@ -405,22 +400,24 @@ SkPath GM2TabStyle::GetPath(PathType path_type,
path.offset(-origin.x(), -origin.y()); path.offset(-origin.x(), -origin.y());
// Possibly convert back to DIPs. // Possibly convert back to DIPs.
if (render_units == RenderUnits::kDips && scale != 1.0f) if (render_units == TabStyle::RenderUnits::kDips && scale != 1.0f) {
path.transform(SkMatrix::Scale(1.0f / scale, 1.0f / scale)); path.transform(SkMatrix::Scale(1.0f / scale, 1.0f / scale));
}
return path; return path;
} }
gfx::Insets GM2TabStyle::GetContentsInsets() const { gfx::Insets GM2TabStyleViews::GetContentsInsets() const {
const int stroke_thickness = GetStrokeThickness(); const int stroke_thickness = GetStrokeThickness();
const int horizontal_inset = GetContentsHorizontalInsetSize(); const int horizontal_inset = tab_style()->GetContentsHorizontalInsetSize();
return gfx::Insets::TLBR( return gfx::Insets::TLBR(
stroke_thickness, horizontal_inset, stroke_thickness, horizontal_inset,
stroke_thickness + GetLayoutConstant(TABSTRIP_TOOLBAR_OVERLAP), stroke_thickness + GetLayoutConstant(TABSTRIP_TOOLBAR_OVERLAP),
horizontal_inset); horizontal_inset);
} }
float GM2TabStyle::GetZValue() const { float GM2TabStyleViews::GetZValue() const {
CHECK(tab());
// This will return values so that inactive tabs can be sorted in the // This will return values so that inactive tabs can be sorted in the
// following order: // following order:
// //
@ -453,17 +450,18 @@ float GM2TabStyle::GetZValue() const {
return sort_value; return sort_value;
} }
float GM2TabStyle::GetActiveOpacity() const { float GM2TabStyleViews::GetActiveOpacity() const {
CHECK(tab());
if (tab_->IsActive()) if (tab_->IsActive())
return 1.0f; return 1.0f;
if (tab_->IsSelected()) if (tab_->IsSelected())
return kSelectedTabOpacity; return tab_style()->GetSelectedTabOpacity();
if (tab_->mouse_hovered()) if (tab_->mouse_hovered())
return GetHoverOpacity(); return GetHoverOpacity();
return 0.0f; return 0.0f;
} }
TabActive GM2TabStyle::GetApparentActiveState() const { TabActive GM2TabStyleViews::GetApparentActiveState() const {
// In some cases, inactive tabs may have background more like active tabs than // In some cases, inactive tabs may have background more like active tabs than
// inactive tabs, so colors should be adapted to ensure appropriate contrast. // inactive tabs, so colors should be adapted to ensure appropriate contrast.
// In particular, text should have plenty of contrast in all cases, so switch // In particular, text should have plenty of contrast in all cases, so switch
@ -472,7 +470,8 @@ TabActive GM2TabStyle::GetApparentActiveState() const {
return GetActiveOpacity() > 0.5f ? TabActive::kActive : TabActive::kInactive; return GetActiveOpacity() > 0.5f ? TabActive::kActive : TabActive::kInactive;
} }
TabStyle::TabColors GM2TabStyle::CalculateColors() const { TabStyle::TabColors GM2TabStyleViews::CalculateColors() const {
CHECK(tab());
const TabActive active = GetApparentActiveState(); const TabActive active = GetApparentActiveState();
const SkColor foreground_color = const SkColor foreground_color =
tab_->controller()->GetTabForegroundColor(active); tab_->controller()->GetTabForegroundColor(active);
@ -501,7 +500,8 @@ const gfx::FontList& GM2TabStyle::GetFontList() const {
return normal_font_; return normal_font_;
} }
void GM2TabStyle::PaintTab(gfx::Canvas* canvas) const { void GM2TabStyleViews::PaintTab(gfx::Canvas* canvas) const {
CHECK(tab());
absl::optional<int> active_tab_fill_id; absl::optional<int> active_tab_fill_id;
int active_tab_y_inset = 0; int active_tab_y_inset = 0;
if (tab_->GetThemeProvider()->HasCustomImage(IDR_THEME_TOOLBAR)) { if (tab_->GetThemeProvider()->HasCustomImage(IDR_THEME_TOOLBAR)) {
@ -526,7 +526,8 @@ void GM2TabStyle::PaintTab(gfx::Canvas* canvas) const {
} }
} }
void GM2TabStyle::SetHoverLocation(const gfx::Point& location) { void GM2TabStyleViews::SetHoverLocation(const gfx::Point& location) {
CHECK(tab());
// There's a "glow" that gets drawn over inactive tabs based on the mouse's // There's a "glow" that gets drawn over inactive tabs based on the mouse's
// location. There is no glow for the active tab so don't update the hover // location. There is no glow for the active tab so don't update the hover
// controller and incur a redraw. // controller and incur a redraw.
@ -534,30 +535,34 @@ void GM2TabStyle::SetHoverLocation(const gfx::Point& location) {
hover_controller_->SetLocation(location); hover_controller_->SetLocation(location);
} }
void GM2TabStyle::ShowHover(ShowHoverStyle style) { void GM2TabStyleViews::ShowHover(TabStyle::ShowHoverStyle style) {
CHECK(tab());
if (!hover_controller_) if (!hover_controller_)
return; return;
if (style == ShowHoverStyle::kSubtle) { if (style == TabStyle::ShowHoverStyle::kSubtle) {
hover_controller_->SetSubtleOpacityScale( hover_controller_->SetSubtleOpacityScale(
tab_->controller()->GetHoverOpacityForRadialHighlight()); tab_->controller()->GetHoverOpacityForRadialHighlight());
} }
hover_controller_->Show(style); hover_controller_->Show(style);
} }
void GM2TabStyle::HideHover(HideHoverStyle style) { void GM2TabStyleViews::HideHover(TabStyle::HideHoverStyle style) {
CHECK(tab());
if (hover_controller_) if (hover_controller_)
hover_controller_->Hide(style); hover_controller_->Hide(style);
} }
TabStyle::SeparatorBounds GM2TabStyle::GetSeparatorBounds(float scale) const { TabStyle::SeparatorBounds GM2TabStyleViews::GetSeparatorBounds(
float scale) const {
CHECK(tab());
const gfx::RectF aligned_bounds = const gfx::RectF aligned_bounds =
ScaleAndAlignBounds(tab_->bounds(), scale, GetStrokeThickness()); ScaleAndAlignBounds(tab_->bounds(), scale, GetStrokeThickness());
const int corner_radius = GetCornerRadius() * scale; const int corner_radius = tab_style()->GetBottomCornerRadius() * scale;
gfx::SizeF separator_size(GetSeparatorSize()); gfx::SizeF separator_size(tab_style()->GetSeparatorSize());
separator_size.Scale(scale); separator_size.Scale(scale);
SeparatorBounds separator_bounds; TabStyle::SeparatorBounds separator_bounds;
separator_bounds.leading = separator_bounds.leading =
gfx::RectF(aligned_bounds.x() + corner_radius, gfx::RectF(aligned_bounds.x() + corner_radius,
@ -577,7 +582,7 @@ TabStyle::SeparatorBounds GM2TabStyle::GetSeparatorBounds(float scale) const {
return separator_bounds; return separator_bounds;
} }
TabStyle::SeparatorOpacities GM2TabStyle::GetSeparatorOpacities( TabStyle::SeparatorOpacities GM2TabStyleViews::GetSeparatorOpacities(
bool for_layout) const { bool for_layout) const {
// Adjacent slots should be visually separated from each other. This can be // Adjacent slots should be visually separated from each other. This can be
// achieved in multiple ways: // achieved in multiple ways:
@ -602,7 +607,9 @@ TabStyle::SeparatorOpacities GM2TabStyle::GetSeparatorOpacities(
return {leading_opacity, trailing_opacity}; return {leading_opacity, trailing_opacity};
} }
float GM2TabStyle::GetSeparatorOpacity(bool for_layout, bool leading) const { float GM2TabStyleViews::GetSeparatorOpacity(bool for_layout,
bool leading) const {
CHECK(tab());
// If the current tab is active, never show the separator. // If the current tab is active, never show the separator.
if (tab_->IsActive()) if (tab_->IsActive())
return 0.0f; return 0.0f;
@ -686,60 +693,64 @@ float GM2TabStyle::GetSeparatorOpacity(bool for_layout, bool leading) const {
return GetHoverInterpolatedSeparatorOpacity(for_layout, adjacent_tab); return GetHoverInterpolatedSeparatorOpacity(for_layout, adjacent_tab);
} }
float GM2TabStyle::GetHoverInterpolatedSeparatorOpacity( float GM2TabStyleViews::GetHoverInterpolatedSeparatorOpacity(
bool for_layout, bool for_layout,
const Tab* other_tab) const { const Tab* other_tab) const {
CHECK(tab());
// Fade out the intervening separator while this tab or an adjacent tab is // Fade out the intervening separator while this tab or an adjacent tab is
// hovered, which prevents sudden opacity changes when scrubbing the mouse // hovered, which prevents sudden opacity changes when scrubbing the mouse
// across the tabstrip. If that adjacent tab is active, don't consider its // across the tabstrip. If that adjacent tab is active, don't consider its
// hover animation value, otherwise the separator on this tab will disappear // hover animation value, otherwise the separator on this tab will disappear
// while that tab is being dragged. // while that tab is being dragged.
auto adjacent_hover_value = [for_layout](const Tab* other_tab) { auto adjacent_hover_value = [for_layout](const Tab* other_tab) {
if (for_layout || !other_tab || other_tab->IsActive()) if (for_layout || !other_tab || other_tab->IsActive()) {
return 0.0f; return 0.0f;
auto* tab_style = static_cast<const GM2TabStyle*>(other_tab->tab_style()); }
return static_cast<float>(tab_style->GetHoverAnimationValue()); return static_cast<float>(
other_tab->tab_style_views()->GetHoverAnimationValue());
}; };
const float hover_value = GetHoverAnimationValue(); const float hover_value = GetHoverAnimationValue();
return 1.0f - std::max(hover_value, adjacent_hover_value(other_tab)); return 1.0f - std::max(hover_value, adjacent_hover_value(other_tab));
} }
bool GM2TabStyle::ShouldExtendHitTest() const { bool GM2TabStyleViews::ShouldExtendHitTest() const {
const views::Widget* widget = tab_->GetWidget(); const views::Widget* widget = tab_->GetWidget();
return widget->IsMaximized() || widget->IsFullscreen(); return widget->IsMaximized() || widget->IsFullscreen();
} }
bool GM2TabStyle::IsHoverActive() const { bool GM2TabStyleViews::IsHoverActive() const {
if (!hover_controller_) if (!hover_controller_)
return false; return false;
return hover_controller_->ShouldDraw(); return hover_controller_->ShouldDraw();
} }
double GM2TabStyle::GetHoverAnimationValue() const { double GM2TabStyleViews::GetHoverAnimationValue() const {
if (!hover_controller_) if (!hover_controller_)
return 0.0; return 0.0;
return hover_controller_->GetAnimationValue(); return hover_controller_->GetAnimationValue();
} }
float GM2TabStyle::GetHoverOpacity() const { float GM2TabStyleViews::GetHoverOpacity() const {
CHECK(tab());
// Opacity boost varies on tab width. The interpolation is nonlinear so // Opacity boost varies on tab width. The interpolation is nonlinear so
// that most tabs will fall on the low end of the opacity range, but very // that most tabs will fall on the low end of the opacity range, but very
// narrow tabs will still stand out on the high end. // narrow tabs will still stand out on the high end.
const float range_start = static_cast<float>(GetStandardWidth()); const float range_start = static_cast<float>(tab_style()->GetStandardWidth());
constexpr float kWidthForMaxHoverOpacity = 32.0f; constexpr float kWidthForMaxHoverOpacity = 32.0f;
const float value_in_range = static_cast<float>(tab_->width()); const float value_in_range = static_cast<float>(tab_->width());
const float t = base::clamp( const float t = std::clamp(
(value_in_range - range_start) / (kWidthForMaxHoverOpacity - range_start), (value_in_range - range_start) / (kWidthForMaxHoverOpacity - range_start),
0.0f, 1.0f); 0.0f, 1.0f);
return tab_->controller()->GetHoverOpacityForTab(t * t); return tab_->controller()->GetHoverOpacityForTab(t * t);
} }
float GM2TabStyle::GetThrobValue() const { float GM2TabStyleViews::GetThrobValue() const {
const bool is_selected = tab_->IsSelected(); const bool is_selected = tab_->IsSelected();
double val = is_selected ? kSelectedTabOpacity : 0; double val = is_selected ? tab_style()->GetSelectedTabOpacity() : 0;
if (IsHoverActive()) { if (IsHoverActive()) {
constexpr float kSelectedTabThrobScale = 0.95f - kSelectedTabOpacity; const float kSelectedTabThrobScale =
0.95f - tab_style()->GetSelectedTabOpacity();
const float opacity = GetHoverOpacity(); const float opacity = GetHoverOpacity();
const float offset = const float offset =
is_selected ? (kSelectedTabThrobScale * opacity) : opacity; is_selected ? (kSelectedTabThrobScale * opacity) : opacity;
@ -749,7 +760,8 @@ float GM2TabStyle::GetThrobValue() const {
return val; return val;
} }
int GM2TabStyle::GetStrokeThickness(bool should_paint_as_active) const { int GM2TabStyleViews::GetStrokeThickness(bool should_paint_as_active) const {
CHECK(tab());
absl::optional<tab_groups::TabGroupId> group = tab_->group(); absl::optional<tab_groups::TabGroupId> group = tab_->group();
if (group.has_value() && tab_->IsActive()) if (group.has_value() && tab_->IsActive())
return TabGroupUnderline::kStrokeThickness; return TabGroupUnderline::kStrokeThickness;
@ -760,9 +772,10 @@ int GM2TabStyle::GetStrokeThickness(bool should_paint_as_active) const {
return 0; return 0;
} }
bool GM2TabStyle::ShouldPaintTabBackgroundColor( bool GM2TabStyleViews::ShouldPaintTabBackgroundColor(
TabActive active, TabActive active,
bool has_custom_background) const { bool has_custom_background) const {
CHECK(tab());
// In the active case, always paint the tab background. The fill image may be // In the active case, always paint the tab background. The fill image may be
// transparent. // transparent.
if (active == TabActive::kActive) if (active == TabActive::kActive)
@ -777,17 +790,25 @@ bool GM2TabStyle::ShouldPaintTabBackgroundColor(
ThemeProperties::SHOULD_FILL_BACKGROUND_TAB_COLOR); ThemeProperties::SHOULD_FILL_BACKGROUND_TAB_COLOR);
} }
SkColor GM2TabStyle::GetTabBackgroundColor(TabActive active) const { SkColor GM2TabStyleViews::GetTabSeparatorColor() const {
CHECK(tab());
return tab_->controller()->GetTabSeparatorColor();
}
SkColor GM2TabStyleViews::GetTabBackgroundColor(TabActive active) const {
CHECK(tab());
SkColor color = tab_->controller()->GetTabBackgroundColor( SkColor color = tab_->controller()->GetTabBackgroundColor(
active, BrowserFrameActiveState::kUseCurrent); active, BrowserFrameActiveState::kUseCurrent);
return color; return color;
} }
ShapeModifier GM2TabStyle::GetShapeModifier(PathType path_type) const { ShapeModifier GM2TabStyleViews::GetShapeModifier(
TabStyle::PathType path_type) const {
CHECK(tab());
ShapeModifier shape_modifier = kNone; ShapeModifier shape_modifier = kNone;
if (path_type == PathType::kFill && tab_->IsSelected() && !IsHoverActive() && if (path_type == TabStyle::PathType::kFill && tab_->IsSelected() &&
!tab_->IsActive()) { !IsHoverActive() && !tab_->IsActive()) {
auto check_adjacent_tab = [](const Tab* tab, int offset, auto check_adjacent_tab = [](const Tab* tab, int offset,
ShapeModifier modifier) { ShapeModifier modifier) {
const Tab* adjacent_tab = tab->controller()->GetAdjacentTab(tab, offset); const Tab* adjacent_tab = tab->controller()->GetAdjacentTab(tab, offset);
@ -802,17 +823,19 @@ ShapeModifier GM2TabStyle::GetShapeModifier(PathType path_type) const {
return shape_modifier; return shape_modifier;
} }
void GM2TabStyle::PaintInactiveTabBackground(gfx::Canvas* canvas) const { void GM2TabStyleViews::PaintInactiveTabBackground(gfx::Canvas* canvas) const {
CHECK(tab());
PaintTabBackground(canvas, TabActive::kInactive, PaintTabBackground(canvas, TabActive::kInactive,
tab_->controller()->GetCustomBackgroundId( tab_->controller()->GetCustomBackgroundId(
BrowserFrameActiveState::kUseCurrent), BrowserFrameActiveState::kUseCurrent),
0); 0);
} }
void GM2TabStyle::PaintTabBackground(gfx::Canvas* canvas, void GM2TabStyleViews::PaintTabBackground(gfx::Canvas* canvas,
TabActive active, TabActive active,
absl::optional<int> fill_id, absl::optional<int> fill_id,
int y_inset) const { int y_inset) const {
CHECK(tab());
// |y_inset| is only set when |fill_id| is being used. // |y_inset| is only set when |fill_id| is being used.
DCHECK(!y_inset || fill_id.has_value()); DCHECK(!y_inset || fill_id.has_value());
@ -833,12 +856,14 @@ void GM2TabStyle::PaintTabBackground(gfx::Canvas* canvas,
PaintSeparators(canvas); PaintSeparators(canvas);
} }
void GM2TabStyle::PaintTabBackgroundFill(gfx::Canvas* canvas, void GM2TabStyleViews::PaintTabBackgroundFill(gfx::Canvas* canvas,
TabActive active, TabActive active,
bool paint_hover_effect, bool paint_hover_effect,
absl::optional<int> fill_id, absl::optional<int> fill_id,
int y_inset) const { int y_inset) const {
const SkPath fill_path = GetPath(PathType::kFill, canvas->image_scale(), CHECK(tab());
const SkPath fill_path =
GetPath(TabStyle::PathType::kFill, canvas->image_scale(),
active == TabActive::kActive); active == TabActive::kActive);
gfx::ScopedCanvas scoped_canvas(canvas); gfx::ScopedCanvas scoped_canvas(canvas);
const float scale = canvas->UndoDeviceScaleFactor(); const float scale = canvas->UndoDeviceScaleFactor();
@ -865,18 +890,38 @@ void GM2TabStyle::PaintTabBackgroundFill(gfx::Canvas* canvas,
if (paint_hover_effect) { if (paint_hover_effect) {
SkPoint hover_location(gfx::PointToSkPoint(hover_controller_->location())); SkPoint hover_location(gfx::PointToSkPoint(hover_controller_->location()));
hover_location.scale(SkFloatToScalar(scale)); hover_location.scale(SkFloatToScalar(scale));
const SkScalar kMinHoverRadius = 16; PaintBackgroundHover(canvas, scale);
const SkScalar radius =
std::max(SkFloatToScalar(tab_->width() / 4.f), kMinHoverRadius);
DrawHighlight(canvas, hover_location, radius * scale,
SkColorSetA(GetTabBackgroundColor(TabActive::kActive),
hover_controller_->GetAlpha()));
} }
} }
void GM2TabStyle::PaintBackgroundStroke(gfx::Canvas* canvas, void GM2TabStyleViews::PaintBackgroundHover(gfx::Canvas* canvas,
float scale) const {
SkPoint hover_location(gfx::PointToSkPoint(hover_controller_->location()));
hover_location.scale(SkFloatToScalar(scale));
const SkScalar kMinHoverRadius = 16;
const SkScalar radius =
std::max(SkFloatToScalar(tab_->width() / 4.f), kMinHoverRadius) * scale;
const SkColor color = SkColorSetA(GetTabBackgroundColor(TabActive::kActive),
hover_controller_->GetAlpha());
// TODO(crbug/1308932): Remove FromColor and make all SkColor4f.
const SkColor4f colors[2] = {
SkColor4f::FromColor(color),
SkColor4f::FromColor(SkColorSetA(color, SK_AlphaTRANSPARENT))};
cc::PaintFlags flags;
flags.setAntiAlias(true);
flags.setShader(cc::PaintShader::MakeRadialGradient(
hover_location, radius, colors, nullptr, 2, SkTileMode::kClamp));
canvas->sk_canvas()->drawRect(
SkRect::MakeXYWH(hover_location.x() - radius, hover_location.y() - radius,
radius * 2, radius * 2),
flags);
}
void GM2TabStyleViews::PaintBackgroundStroke(gfx::Canvas* canvas,
TabActive active, TabActive active,
SkColor stroke_color) const { SkColor stroke_color) const {
CHECK(tab());
const bool is_active = active == TabActive::kActive; const bool is_active = active == TabActive::kActive;
const int stroke_thickness = GetStrokeThickness(is_active); const int stroke_thickness = GetStrokeThickness(is_active);
if (!stroke_thickness) if (!stroke_thickness)
@ -894,7 +939,7 @@ void GM2TabStyle::PaintBackgroundStroke(gfx::Canvas* canvas,
canvas->DrawPath(outer_path, flags); canvas->DrawPath(outer_path, flags);
} }
void GM2TabStyle::PaintSeparators(gfx::Canvas* canvas) const { void GM2TabStyleViews::PaintSeparators(gfx::Canvas* canvas) const {
const auto separator_opacities = GetSeparatorOpacities(false); const auto separator_opacities = GetSeparatorOpacities(false);
if (!separator_opacities.left && !separator_opacities.right) if (!separator_opacities.left && !separator_opacities.right)
return; return;
@ -904,8 +949,7 @@ void GM2TabStyle::PaintSeparators(gfx::Canvas* canvas) const {
TabStyle::SeparatorBounds separator_bounds = GetSeparatorBounds(scale); TabStyle::SeparatorBounds separator_bounds = GetSeparatorBounds(scale);
const SkColor separator_base_color = const SkColor separator_base_color = GetTabSeparatorColor();
tab_->controller()->GetTabSeparatorColor();
const auto separator_color = [separator_base_color](float opacity) { const auto separator_color = [separator_base_color](float opacity) {
return SkColorSetA(separator_base_color, return SkColorSetA(separator_base_color,
gfx::Tween::IntValueBetween(opacity, SK_AlphaTRANSPARENT, gfx::Tween::IntValueBetween(opacity, SK_AlphaTRANSPARENT,
@ -920,34 +964,32 @@ void GM2TabStyle::PaintSeparators(gfx::Canvas* canvas) const {
canvas->DrawRect(separator_bounds.trailing, flags); canvas->DrawRect(separator_bounds.trailing, flags);
} }
// static float GM2TabStyleViews::GetTopCornerRadiusForWidth(int width) const {
float GM2TabStyle::GetTopCornerRadiusForWidth(int width) {
// Get the width of the top of the tab by subtracting the width of the outer // Get the width of the top of the tab by subtracting the width of the outer
// corners. // corners.
const int ideal_radius = GetCornerRadius(); const int ideal_radius = tab_style()->GetTopCornerRadius();
const int top_width = width - ideal_radius * 2; const int top_width = width - ideal_radius * 2;
// To maintain a round-rect appearance, ensure at least one third of the top // To maintain a round-rect appearance, ensure at least one third of the top
// of the tab is flat. // of the tab is flat.
const float radius = top_width / 3.f; const float radius = top_width / 3.f;
return base::clamp<float>(radius, 0, ideal_radius); return std::clamp<float>(radius, 0, ideal_radius);
} }
// static gfx::RectF GM2TabStyleViews::ScaleAndAlignBounds(const gfx::Rect& bounds,
gfx::RectF GM2TabStyle::ScaleAndAlignBounds(const gfx::Rect& bounds,
float scale, float scale,
int stroke_thickness) { int stroke_thickness) const {
// Convert to layout bounds. We must inset the width such that the right edge // Convert to layout bounds. We must inset the width such that the right edge
// of one tab's layout bounds is the same as the left edge of the next tab's; // of one tab's layout bounds is the same as the left edge of the next tab's;
// this way the two tabs' separators will be drawn at the same coordinate. // this way the two tabs' separators will be drawn at the same coordinate.
gfx::RectF aligned_bounds(bounds); gfx::RectF aligned_bounds(bounds);
const int corner_radius = GetCornerRadius(); const int bottom_corner_radius = tab_style()->GetBottomCornerRadius();
// Note: This intentionally doesn't subtract TABSTRIP_TOOLBAR_OVERLAP from the // Note: This intentionally doesn't subtract TABSTRIP_TOOLBAR_OVERLAP from the
// bottom inset, because we want to pixel-align the bottom of the stroke, not // bottom inset, because we want to pixel-align the bottom of the stroke, not
// the bottom of the overlap. // the bottom of the overlap.
auto layout_insets = auto layout_insets = gfx::InsetsF::TLBR(
gfx::InsetsF::TLBR(stroke_thickness, corner_radius, stroke_thickness, stroke_thickness, bottom_corner_radius, stroke_thickness,
corner_radius + GetSeparatorSize().width()); bottom_corner_radius + tab_style()->GetSeparatorSize().width());
aligned_bounds.Inset(layout_insets); aligned_bounds.Inset(layout_insets);
// Scale layout bounds from DIP to px. // Scale layout bounds from DIP to px.
@ -968,6 +1010,93 @@ gfx::RectF GM2TabStyle::ScaleAndAlignBounds(const gfx::Rect& bounds,
return aligned_bounds; return aligned_bounds;
} }
class ChromeRefresh2023TabStyleViews : public GM2TabStyleViews {
public:
explicit ChromeRefresh2023TabStyleViews(Tab* tab);
~ChromeRefresh2023TabStyleViews() override = default;
SkColor GetTabBackgroundColor(TabActive active) const override;
int GetStrokeThickness(bool should_paint_as_active = false) const override;
void PaintBackgroundHover(gfx::Canvas* canvas, float scale) const override;
SkColor GetTabSeparatorColor() const override;
bool ShouldPaintTabBackgroundColor(TabActive active,
bool has_custom_background) const override;
};
ChromeRefresh2023TabStyleViews::ChromeRefresh2023TabStyleViews(Tab* tab)
: GM2TabStyleViews(tab) {}
SkColor ChromeRefresh2023TabStyleViews::GetTabBackgroundColor(
TabActive active) const {
CHECK(tab());
const auto* cp = tab()->GetWidget()->GetColorProvider();
DCHECK(cp);
if (!cp) {
return gfx::kPlaceholderColor;
}
constexpr ChromeColorIds kColorIds[2][2] = {
{kColorTabBackgroundInactiveFrameInactive,
kColorTabBackgroundInactiveFrameActive},
{kColorTabBackgroundActiveFrameInactive,
kColorTabBackgroundActiveFrameActive}};
return cp->GetColor(kColorIds[int(active == TabActive::kActive)][int(
tab()->controller()->ShouldPaintAsActiveFrame())]);
}
int ChromeRefresh2023TabStyleViews::GetStrokeThickness(
bool should_paint_as_active) const {
CHECK(tab());
if (tab()->group().has_value() && tab()->IsActive()) {
return TabGroupUnderline::kStrokeThickness;
}
return 0;
}
void ChromeRefresh2023TabStyleViews::PaintBackgroundHover(gfx::Canvas* canvas,
float scale) const {
const SkPath fill_path =
GetPath(TabStyle::PathType::kHighlight, canvas->image_scale(), true);
canvas->ClipPath(fill_path, true);
// Override the color for ChromeRefresh2023
const auto* cp = tab()->GetWidget()->GetColorProvider();
const SkColor color =
cp->GetColor(tab()->controller()->ShouldPaintAsActiveFrame()
? kColorTabBackgroundHoverFrameActive
: kColorTabBackgroundHoverFrameInactive);
const SkColor4f color_with_alpha_animation = SkColor4f::FromColor(
SkColorSetA(color, GetHoverAnimationValue() * SkColorGetA(color)));
cc::PaintFlags flags;
flags.setAntiAlias(true);
flags.setColor(color_with_alpha_animation);
canvas->DrawRect(gfx::ScaleToEnclosingRect(tab()->GetLocalBounds(), scale),
flags);
}
SkColor ChromeRefresh2023TabStyleViews::GetTabSeparatorColor() const {
CHECK(tab());
const auto* cp = tab()->GetWidget()->GetColorProvider();
DCHECK(cp);
if (!cp) {
return gfx::kPlaceholderColor;
}
return cp->GetColor(tab()->controller()->ShouldPaintAsActiveFrame()
? kColorTabDividerFrameActive
: kColorTabDividerFrameInactive);
}
bool ChromeRefresh2023TabStyleViews::ShouldPaintTabBackgroundColor(
TabActive active,
bool has_custom_background) const {
return (tab()->IsActive() || tab()->IsSelected()) &&
GM2TabStyleViews::ShouldPaintTabBackgroundColor(active,
has_custom_background);
}
} // namespace } // namespace
// static // static
@ -1012,19 +1141,29 @@ ui::metadata::TypeConverter<TabStyle::TabColors>::GetValidStrings() {
return ValidStrings(); return ValidStrings();
} }
// TabStyle -------------------------------------------------------------------- // TabStyleViews ---------------------------------------------------------------
TabStyleViews::TabStyleViews() : tab_style_(TabStyle::Get()) {}
TabStyleViews::~TabStyleViews() = default; TabStyleViews::~TabStyleViews() = default;
// static // static
std::unique_ptr<TabStyleViews> TabStyleViews::CreateForTab(Tab* tab) { std::unique_ptr<TabStyleViews> TabStyleViews::CreateForTab(Tab* tab) {
return std::make_unique<GM2TabStyle>(tab); // If refresh is turned on use ChromeRefresh styling.
if (features::IsChromeRefresh2023()) {
return std::make_unique<ChromeRefresh2023TabStyleViews>(tab);
}
return std::make_unique<GM2TabStyleViews>(tab);
} }
// static // static
int TabStyleViews::GetMinimumActiveWidth() { std::unique_ptr<TabStyleViews> TabStyleViews::Create() {
int min_active_width = return TabStyleViews::CreateForTab(nullptr);
TabCloseButton::GetGlyphSize() + GetContentsHorizontalInsetSize() * 2; }
int TabStyleViews::GetMinimumActiveWidth() const {
int min_active_width = TabCloseButton::GetGlyphSize() +
tab_style()->GetContentsHorizontalInsetSize() * 2;
if (base::FeatureList::IsEnabled(features::kScrollableTabStrip)) { if (base::FeatureList::IsEnabled(features::kScrollableTabStrip)) {
return std::max( return std::max(
min_active_width, min_active_width,
@ -1035,15 +1174,15 @@ int TabStyleViews::GetMinimumActiveWidth() {
return min_active_width; return min_active_width;
} }
// static int TabStyleViews::GetMinimumInactiveWidth() const {
int TabStyleViews::GetMinimumInactiveWidth() {
// Allow tabs to shrink until they appear to be 16 DIP wide excluding // Allow tabs to shrink until they appear to be 16 DIP wide excluding
// outer corners. // outer corners.
constexpr int kInteriorWidth = 16; constexpr int kInteriorWidth = 16;
// The overlap contains the trailing separator that is part of the interior // The overlap contains the trailing separator that is part of the interior
// width; avoid double-counting it. // width; avoid double-counting it.
int min_inactive_width = int min_inactive_width = kInteriorWidth -
kInteriorWidth - GetSeparatorSize().width() + GetTabOverlap(); tab_style()->GetSeparatorSize().width() +
tab_style()->GetTabOverlap();
if (base::FeatureList::IsEnabled(features::kScrollableTabStrip)) { if (base::FeatureList::IsEnabled(features::kScrollableTabStrip)) {
return std::max(min_inactive_width, return std::max(min_inactive_width,

View file

@ -21,6 +21,7 @@
#include "chrome/app/chrome_command_ids.h" #include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/apps/intent_helper/intent_picker_features.h" #include "chrome/browser/apps/intent_helper/intent_picker_features.h"
#include "chrome/browser/command_updater.h" #include "chrome/browser/command_updater.h"
#include "chrome/browser/companion/core/features.h"
#include "chrome/browser/download/bubble/download_bubble_prefs.h" #include "chrome/browser/download/bubble/download_bubble_prefs.h"
#include "chrome/browser/media/router/media_router_feature.h" #include "chrome/browser/media/router/media_router_feature.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
@ -104,6 +105,7 @@
#include "ui/gfx/paint_vector_icon.h" #include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/scoped_canvas.h" #include "ui/gfx/scoped_canvas.h"
#include "ui/views/accessibility/view_accessibility.h" #include "ui/views/accessibility/view_accessibility.h"
#include "ui/views/background.h"
#include "ui/views/cascading_property.h" #include "ui/views/cascading_property.h"
#include "ui/views/layout/fill_layout.h" #include "ui/views/layout/fill_layout.h"
#include "ui/views/layout/flex_layout.h" #include "ui/views/layout/flex_layout.h"
@ -164,6 +166,8 @@ auto& GetViewCommandMap() {
constexpr int kToolbarDividerWidth = 2; constexpr int kToolbarDividerWidth = 2;
constexpr int kToolbarDividerHeight = 16; constexpr int kToolbarDividerHeight = 16;
constexpr int kToolbarDividerCornerRadius = 1; constexpr int kToolbarDividerCornerRadius = 1;
constexpr int kToolbarDividerSpacing = 9;
} // namespace } // namespace
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -209,18 +213,51 @@ void ToolbarView::Init() {
// Make sure the toolbar shows by default. // Make sure the toolbar shows by default.
size_animation_.Reset(1); size_animation_.Reset(1);
std::unique_ptr<DownloadToolbarButtonView> download_button;
if (download::IsDownloadBubbleEnabled(browser_->profile())) {
download_button =
std::make_unique<DownloadToolbarButtonView>(browser_view_);
}
if (display_mode_ != DisplayMode::NORMAL) { if (display_mode_ != DisplayMode::NORMAL) {
location_bar_ = AddChildView(std::move(location_bar)); location_bar_ = AddChildView(std::move(location_bar));
location_bar_->Init(); location_bar_->Init();
}
if (display_mode_ == DisplayMode::CUSTOM_TAB) { if (display_mode_ == DisplayMode::CUSTOM_TAB) {
custom_tab_bar_ = custom_tab_bar_ =
AddChildView(std::make_unique<CustomTabBarView>(browser_view_, this)); AddChildView(std::make_unique<CustomTabBarView>(browser_view_, this));
}
SetLayoutManager(std::make_unique<views::FillLayout>()); SetLayoutManager(std::make_unique<views::FillLayout>());
initialized_ = true; initialized_ = true;
return; return;
} else if (display_mode_ == DisplayMode::LOCATION) {
// Add the download button for popups.
if (download_button) {
download_button_ = AddChildView(std::move(download_button));
download_button_->SetPreferredSize(
gfx::Size(location_bar_->GetPreferredSize().height(),
location_bar_->GetPreferredSize().height()));
download_button_->SetFocusBehavior(FocusBehavior::ALWAYS);
// Hide the icon by default; it will show up when there's a download.
download_button_->Hide();
}
SetBackground(
views::CreateThemedSolidBackground(kColorLocationBarBackground));
SetLayoutManager(std::make_unique<views::FlexLayout>())
->SetOrientation(views::LayoutOrientation::kHorizontal)
.SetCrossAxisAlignment(views::LayoutAlignment::kCenter)
.SetDefault(views::kFlexBehaviorKey,
views::FlexSpecification(
views::LayoutOrientation::kHorizontal,
views::MinimumFlexSizeRule::kPreferredSnapToZero))
.SetFlexAllocationOrder(views::FlexAllocationOrder::kReverse);
location_bar_->SetProperty(
views::kFlexBehaviorKey,
views::FlexSpecification(views::LayoutOrientation::kHorizontal,
views::MinimumFlexSizeRule::kScaleToZero,
views::MaximumFlexSizeRule::kUnbounded));
initialized_ = true;
return;
} }
const auto callback = [](Browser* browser, int command, const auto callback = [](Browser* browser, int command,
@ -267,12 +304,6 @@ void ToolbarView::Init() {
browser_view_, MediaToolbarButtonContextualMenu::Create(browser_)); browser_view_, MediaToolbarButtonContextualMenu::Create(browser_));
} }
std::unique_ptr<DownloadToolbarButtonView> download_button;
if (download::IsDownloadBubbleEnabled(browser_->profile())) {
download_button =
std::make_unique<DownloadToolbarButtonView>(browser_view_);
}
std::unique_ptr<send_tab_to_self::SendTabToSelfToolbarIconView> std::unique_ptr<send_tab_to_self::SendTabToSelfToolbarIconView>
send_tab_to_self_button; send_tab_to_self_button;
if (!browser_->profile()->IsOffTheRecord()) { if (!browser_->profile()->IsOffTheRecord()) {
@ -285,7 +316,8 @@ void ToolbarView::Init() {
std::unique_ptr<SidePanelToolbarContainer> side_panel_toolbar_container; std::unique_ptr<SidePanelToolbarContainer> side_panel_toolbar_container;
if (browser_view_->unified_side_panel() && if (browser_view_->unified_side_panel() &&
!base::CommandLine::ForCurrentProcess()->HasSwitch("hide-sidepanel-button")) { !base::CommandLine::ForCurrentProcess()->HasSwitch("hide-sidepanel-button")) {
if (base::FeatureList::IsEnabled(features::kSidePanelCompanion)) { if (base::FeatureList::IsEnabled(
companion::features::kSidePanelCompanion)) {
side_panel_toolbar_container = side_panel_toolbar_container =
std::make_unique<SidePanelToolbarContainer>(browser_view_); std::make_unique<SidePanelToolbarContainer>(browser_view_);
} else { } else {
@ -330,11 +362,8 @@ void ToolbarView::Init() {
} }
} }
if (base::FeatureList::IsEnabled(
performance_manager::features::kBatterySaverModeAvailable)) {
battery_saver_button_ = battery_saver_button_ =
AddChildView(std::make_unique<BatterySaverButton>(browser_view_)); AddChildView(std::make_unique<BatterySaverButton>(browser_view_));
}
if (cast) if (cast)
cast_ = AddChildView(std::move(cast)); cast_ = AddChildView(std::move(cast));
@ -669,17 +698,15 @@ void ToolbarView::Layout() {
return; return;
} }
if (display_mode_ == DisplayMode::LOCATION) { if (display_mode_ == DisplayMode::NORMAL) {
location_bar_->SetBounds(0, 0, width(),
location_bar_->GetPreferredSize().height());
return;
}
LayoutCommon(); LayoutCommon();
#if BUILDFLAG(IS_MAC)
if (features::IsChromeRefresh2023()) { if (features::IsChromeRefresh2023()) {
UpdateClipPath(); UpdateClipPath();
} }
#endif
}
// Call super implementation to ensure layout manager and child layouts // Call super implementation to ensure layout manager and child layouts
// happen. // happen.
@ -741,9 +768,10 @@ void ToolbarView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
} }
void ToolbarView::InitLayout() { void ToolbarView::InitLayout() {
const int default_margin = GetLayoutConstant(TOOLBAR_ELEMENT_PADDING); const int default_margin = GetLayoutConstant(TOOLBAR_ICON_DEFAULT_MARGIN);
// TODO(dfried): rename this constant. // TODO(dfried): rename this constant.
const int location_bar_margin = GetLayoutConstant(TOOLBAR_STANDARD_SPACING); const int location_bar_margin = GetLayoutConstant(TOOLBAR_STANDARD_SPACING);
const views::FlexSpecification account_container_flex_rule = const views::FlexSpecification account_container_flex_rule =
views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToMinimum, views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToMinimum,
views::MaximumFlexSizeRule::kPreferred) views::MaximumFlexSizeRule::kPreferred)
@ -789,9 +817,8 @@ void ToolbarView::InitLayout() {
} }
if (toolbar_divider_) { if (toolbar_divider_) {
SkColor color = GetColorProvider()->GetColor(ui::kColorSysOutline); toolbar_divider_->SetProperty(views::kMarginsKey,
toolbar_divider_->SetBackground( gfx::Insets::VH(0, kToolbarDividerSpacing));
views::CreateRoundedRectBackground(color, kToolbarDividerCornerRadius));
} }
LayoutCommon(); LayoutCommon();
@ -815,6 +842,13 @@ void ToolbarView::LayoutCommon() {
app_menu_button_->SetTrailingMargin( app_menu_button_->SetTrailingMargin(
extend_buttons_to_edge ? interior_margin.right() : 0); extend_buttons_to_edge ? interior_margin.right() : 0);
if (toolbar_divider_ && extensions_container_) {
toolbar_divider_->SetVisible(extensions_container_->GetVisible());
const SkColor toolbar_extension_separator_color =
GetColorProvider()->GetColor(kColorToolbarExtensionSeparatorEnabled);
toolbar_divider_->SetBackground(views::CreateRoundedRectBackground(
toolbar_extension_separator_color, kToolbarDividerCornerRadius));
}
// Cast button visibility is controlled externally. // Cast button visibility is controlled externally.
} }

View file

@ -44,6 +44,7 @@
#include "components/favicon/core/favicon_backend.h" #include "components/favicon/core/favicon_backend.h"
#include "components/history/core/browser/download_constants.h" #include "components/history/core/browser/download_constants.h"
#include "components/history/core/browser/download_row.h" #include "components/history/core/browser/download_row.h"
#include "components/history/core/browser/features.h"
#include "components/history/core/browser/history_backend_client.h" #include "components/history/core/browser/history_backend_client.h"
#include "components/history/core/browser/history_backend_observer.h" #include "components/history/core/browser/history_backend_observer.h"
#include "components/history/core/browser/history_constants.h" #include "components/history/core/browser/history_constants.h"
@ -100,6 +101,9 @@ namespace history {
namespace { namespace {
using OsType = syncer::DeviceInfo::OsType;
using FormFactor = syncer::DeviceInfo::FormFactor;
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
// Use to keep track of paths used to host HistoryBackends. This class // Use to keep track of paths used to host HistoryBackends. This class
// is thread-safe. No two backends should ever run at the same time using the // is thread-safe. No two backends should ever run at the same time using the
@ -239,6 +243,49 @@ class DeleteForeignVisitsDBTask : public HistoryDBTask {
void DoneRunOnMainThread() override {} void DoneRunOnMainThread() override {}
}; };
// On iOS devices, Returns true if the device that created the foreign visit is
// an Android or iOS device, and has a mobile form factor.
//
// On non-iOS devices, returns false.
bool CanAddForeignVisitToSegments(
const VisitRow& foreign_visit,
const std::string& local_device_originator_cache_guid,
const SyncDeviceInfoMap& sync_device_info) {
#if BUILDFLAG(IS_IOS)
if (!history::IsSyncSegmentsDataEnabled() ||
foreign_visit.originator_cache_guid.empty() ||
!foreign_visit.consider_for_ntp_most_visited) {
return false;
}
auto foreign_device_info_iter =
sync_device_info.find(foreign_visit.originator_cache_guid);
auto local_device_info_iter =
sync_device_info.find(local_device_originator_cache_guid);
if (foreign_device_info_iter == sync_device_info.end() ||
local_device_info_iter == sync_device_info.end()) {
return false;
}
std::pair<OsType, FormFactor> foreign_device_info =
foreign_device_info_iter->second;
std::pair<OsType, FormFactor> local_device_info =
local_device_info_iter->second;
if (local_device_info.first != OsType::kIOS ||
local_device_info.second != FormFactor::kPhone) {
return false;
}
return foreign_device_info.second == FormFactor::kPhone &&
(foreign_device_info.first == OsType::kAndroid ||
foreign_device_info.first == OsType::kIOS);
#else
return false;
#endif
}
} // namespace } // namespace
std::u16string FormatUrlForRedirectComparison(const GURL& url) { std::u16string FormatUrlForRedirectComparison(const GURL& url) {
@ -437,31 +484,68 @@ SegmentID HistoryBackend::GetLastSegmentID(VisitID from_visit) {
VisitID visit_id = from_visit; VisitID visit_id = from_visit;
while (visit_id) { while (visit_id) {
VisitRow row; VisitRow row;
if (!db_->GetRowForVisit(visit_id, &row)) if (!db_->GetRowForVisit(visit_id, &row)) {
return 0; return 0;
if (row.segment_id) }
if (row.segment_id) {
return row.segment_id; // Found a visit in this change with a segment. return row.segment_id; // Found a visit in this change with a segment.
}
// Check the referrer of this visit, if any. // Check the referrer of this visit, if any.
visit_id = row.referring_visit; visit_id = row.referring_visit;
if (visit_set.find(visit_id) != visit_set.end()) { if (visit_set.find(visit_id) != visit_set.end()) {
NOTREACHED() << "Loop in referer chain, giving up"; DLOG(WARNING) << "Loop in referer chain, possible db corruption";
break; return 0;
} }
visit_set.insert(visit_id); visit_set.insert(visit_id);
} }
return 0; return 0;
} }
SegmentID HistoryBackend::UpdateSegments(const GURL& url, SegmentID HistoryBackend::AssignSegmentForNewVisit(
const GURL& url,
VisitID from_visit, VisitID from_visit,
VisitID visit_id, VisitID visit_id,
ui::PageTransition transition_type, ui::PageTransition transition_type,
const Time ts) { const Time ts) {
if (!db_) if (!db_) {
return 0; return 0;
}
// We only consider main frames.
if (!ui::PageTransitionIsMainFrame(transition_type)) {
return 0;
}
SegmentID segment_id = CalculateSegmentID(url, from_visit, transition_type);
if (!segment_id) {
return 0;
}
// Set the segment in the visit.
if (!db_->SetSegmentID(visit_id, segment_id)) {
DLOG(WARNING) << "AssignSegmentForNewVisit: SetSegmentID failed: "
<< segment_id;
return 0;
}
// Finally, increase the counter for that segment / day.
if (!db_->UpdateSegmentVisitCount(segment_id, ts, 1)) {
DLOG(WARNING)
<< "AssignSegmentForNewVisit: UpdateSegmentVisitCount failed: "
<< segment_id;
return 0;
}
return segment_id;
}
SegmentID HistoryBackend::CalculateSegmentID(
const GURL& url,
VisitID from_visit,
ui::PageTransition transition_type) {
// We only consider main frames. // We only consider main frames.
if (!ui::PageTransitionIsMainFrame(transition_type)) if (!ui::PageTransitionIsMainFrame(transition_type))
return 0; return 0;
@ -496,7 +580,8 @@ SegmentID HistoryBackend::UpdateSegments(const GURL& url,
if (!segment_id) { if (!segment_id) {
segment_id = db_->CreateSegment(url_id, segment_name); segment_id = db_->CreateSegment(url_id, segment_name);
if (!segment_id) { if (!segment_id) {
DLOG(ERROR) << "UpdateSegments: CreateSegment failed: " << segment_name; DLOG(WARNING) << "CalculateSegmentID: CreateSegment failed: "
<< segment_name;
return 0; return 0;
} }
} else { } else {
@ -511,25 +596,57 @@ SegmentID HistoryBackend::UpdateSegments(const GURL& url,
// TYPED. (For example GENERATED). In this case this visit doesn't count // TYPED. (For example GENERATED). In this case this visit doesn't count
// toward any segment. // toward any segment.
segment_id = GetLastSegmentID(from_visit); segment_id = GetLastSegmentID(from_visit);
if (!segment_id)
return 0;
} }
// Set the segment in the visit.
if (!db_->SetSegmentID(visit_id, segment_id)) {
DLOG(ERROR) << "UpdateSegments: SetSegmentID failed: " << segment_id;
return 0;
}
// Finally, increase the counter for that segment / day.
if (!db_->IncreaseSegmentVisitCount(segment_id, ts, 1)) {
DLOG(ERROR) << "UpdateSegments: IncreaseSegmentVisitCount failed: "
<< segment_id;
return 0;
}
return segment_id; return segment_id;
} }
void HistoryBackend::UpdateSegmentForExistingForeignVisit(VisitRow& visit_row) {
CHECK(can_add_foreign_visits_to_segments_);
CHECK(!visit_row.originator_cache_guid.empty());
URLRow url_row;
if (!db_->GetURLRow(visit_row.url_id, &url_row)) {
DLOG(WARNING) << "Failed to get id " << visit_row.url_id
<< " from history.urls.";
return;
}
SegmentID new_segment_id =
(can_add_foreign_visits_to_segments_ &&
CanAddForeignVisitToSegments(
visit_row, local_device_originator_cache_guid_, sync_device_info_))
? CalculateSegmentID(url_row.url(), visit_row.referring_visit,
visit_row.transition)
: 0;
if (visit_row.segment_id == new_segment_id) {
return;
}
if (visit_row.segment_id != 0 &&
!db_->UpdateSegmentVisitCount(visit_row.segment_id, visit_row.visit_time,
-1)) {
// Decrement the count of the old segment.
DLOG(WARNING) << "UpdateSegmentForExistingForeignVisit: "
"UpdateSegmentVisitCount failed: "
<< visit_row.segment_id;
return;
}
if (new_segment_id != 0 &&
!db_->UpdateSegmentVisitCount(new_segment_id, visit_row.visit_time, 1)) {
DLOG(WARNING) << "UpdateSegmentForExistingForeignVisit: "
"UpdateSegmentVisitCount failed: "
<< new_segment_id;
return;
}
visit_row.segment_id = new_segment_id;
db_->SetSegmentID(visit_row.visit_id, new_segment_id);
}
void HistoryBackend::UpdateWithPageEndTime(ContextID context_id, void HistoryBackend::UpdateWithPageEndTime(ContextID context_id,
int nav_entry_id, int nav_entry_id,
const GURL& url, const GURL& url,
@ -899,14 +1016,15 @@ void HistoryBackend::AddPage(const HistoryAddPageArgs& request) {
last_visit_id = last_visit_id =
AddPageVisit(request.url, request.time, last_visit_id, t, AddPageVisit(request.url, request.time, last_visit_id, t,
request.hidden, request.visit_source, IsTypedIncrement(t), request.hidden, request.visit_source, IsTypedIncrement(t),
opener_visit, request.title) opener_visit, request.consider_for_ntp_most_visited,
request.title)
.second; .second;
// Update the segment for this visit. KEYWORD_GENERATED visits should not // Update the segment for this visit. KEYWORD_GENERATED visits should not
// result in changing most visited, so we don't update segments (most // result in changing most visited, so we don't update segments (most
// visited db). // visited db).
if (!is_keyword_generated && request.consider_for_ntp_most_visited) { if (!is_keyword_generated && request.consider_for_ntp_most_visited) {
UpdateSegments(request.url, from_visit_id, last_visit_id, t, AssignSegmentForNewVisit(request.url, from_visit_id, last_visit_id, t,
request.time); request.time);
} }
} else { } else {
@ -1024,12 +1142,13 @@ void HistoryBackend::AddPage(const HistoryAddPageArgs& request) {
AddPageVisit(redirects[redirect_index], request.time, last_visit_id, AddPageVisit(redirects[redirect_index], request.time, last_visit_id,
t, request.hidden, request.visit_source, t, request.hidden, request.visit_source,
should_increment_typed_count, should_increment_typed_count,
redirect_index == 0 ? opener_visit : 0, request.title) redirect_index == 0 ? opener_visit : 0,
request.consider_for_ntp_most_visited, request.title)
.second; .second;
if (t & ui::PAGE_TRANSITION_CHAIN_START) { if (t & ui::PAGE_TRANSITION_CHAIN_START) {
if (request.consider_for_ntp_most_visited) { if (request.consider_for_ntp_most_visited) {
UpdateSegments(redirects[redirect_index], from_visit_id, AssignSegmentForNewVisit(redirects[redirect_index], from_visit_id,
last_visit_id, t, request.time); last_visit_id, t, request.time);
} }
} }
@ -1092,8 +1211,6 @@ void HistoryBackend::InitImpl(
// we only set db_ to the created database if creation is successful. That // we only set db_ to the created database if creation is successful. That
// way other methods won't do anything as db_ is still null. // way other methods won't do anything as db_ is still null.
TimeTicks beginning_time = TimeTicks::Now();
// Compute the file names. // Compute the file names.
history_dir_ = history_database_params.history_dir; history_dir_ = history_database_params.history_dir;
@ -1190,8 +1307,6 @@ void HistoryBackend::InitImpl(
// Start expiring old stuff if flag unset. // Start expiring old stuff if flag unset.
if (!base::CommandLine::ForCurrentProcess()->HasSwitch("keep-all-history")) if (!base::CommandLine::ForCurrentProcess()->HasSwitch("keep-all-history"))
expirer_.StartExpiringOldStuff(base::Days(kExpireDaysThreshold)); expirer_.StartExpiringOldStuff(base::Days(kExpireDaysThreshold));
LOCAL_HISTOGRAM_TIMES("History.InitTime", TimeTicks::Now() - beginning_time);
} }
void HistoryBackend::OnMemoryPressure( void HistoryBackend::OnMemoryPressure(
@ -1227,6 +1342,7 @@ std::pair<URLID, VisitID> HistoryBackend::AddPageVisit(
VisitSource visit_source, VisitSource visit_source,
bool should_increment_typed_count, bool should_increment_typed_count,
VisitID opener_visit, VisitID opener_visit,
bool consider_for_ntp_most_visited,
absl::optional<std::u16string> title, absl::optional<std::u16string> title,
absl::optional<base::TimeDelta> visit_duration, absl::optional<base::TimeDelta> visit_duration,
absl::optional<std::string> originator_cache_guid, absl::optional<std::string> originator_cache_guid,
@ -1284,8 +1400,9 @@ std::pair<URLID, VisitID> HistoryBackend::AddPageVisit(
visit_info.originator_referring_visit = *originator_referring_visit; visit_info.originator_referring_visit = *originator_referring_visit;
if (originator_opener_visit.has_value()) if (originator_opener_visit.has_value())
visit_info.originator_opener_visit = *originator_opener_visit; visit_info.originator_opener_visit = *originator_opener_visit;
visit_info.is_known_to_sync = is_known_to_sync;
visit_info.is_known_to_sync = is_known_to_sync;
visit_info.consider_for_ntp_most_visited = consider_for_ntp_most_visited;
visit_info.visit_id = db_->AddVisit(&visit_info, visit_source); visit_info.visit_id = db_->AddVisit(&visit_info, visit_source);
if (visit_info.visit_time < first_recorded_time_) if (visit_info.visit_time < first_recorded_time_)
@ -1374,6 +1491,10 @@ int HistoryBackend::GetForeignVisitsToDeletePerBatchForTest() {
return GetForeignVisitsToDeletePerBatch(); return GetForeignVisitsToDeletePerBatch();
} }
sql::Database& HistoryBackend::GetDBForTesting() {
return db_->GetDBForTesting(); // IN-TEST
}
void HistoryBackend::SetPageTitle(const GURL& url, void HistoryBackend::SetPageTitle(const GURL& url,
const std::u16string& title) { const std::u16string& title) {
TRACE_EVENT0("browser", "HistoryBackend::SetPageTitle"); TRACE_EVENT0("browser", "HistoryBackend::SetPageTitle");
@ -1516,7 +1637,8 @@ bool HistoryBackend::AddVisits(const GURL& url,
if (!AddPageVisit(url, visit.first, /*referring_visit=*/0, visit.second, if (!AddPageVisit(url, visit.first, /*referring_visit=*/0, visit.second,
/*hidden=*/!ui::PageTransitionIsMainFrame(visit.second), /*hidden=*/!ui::PageTransitionIsMainFrame(visit.second),
visit_source, IsTypedIncrement(visit.second), visit_source, IsTypedIncrement(visit.second),
/*opener_visit=*/0) /*opener_visit=*/0,
/*consider_for_ntp_most_visited=*/true)
.first) { .first) {
return false; return false;
} }
@ -1558,11 +1680,11 @@ VisitID HistoryBackend::AddSyncedVisit(
return kInvalidVisitID; return kInvalidVisitID;
} }
auto [url_id, visit_id] = auto [url_id, visit_id] = AddPageVisit(
AddPageVisit(url, visit.visit_time, visit.referring_visit, url, visit.visit_time, visit.referring_visit, visit.transition, hidden,
visit.transition, hidden, VisitSource::SOURCE_SYNCED, VisitSource::SOURCE_SYNCED, IsTypedIncrement(visit.transition),
IsTypedIncrement(visit.transition), visit.opener_visit, visit.opener_visit, visit.consider_for_ntp_most_visited, title,
title, visit.visit_duration, visit.originator_cache_guid, visit.visit_duration, visit.originator_cache_guid,
visit.originator_visit_id, visit.originator_referring_visit, visit.originator_visit_id, visit.originator_referring_visit,
visit.originator_opener_visit, visit.is_known_to_sync); visit.originator_opener_visit, visit.is_known_to_sync);
@ -1583,6 +1705,13 @@ VisitID HistoryBackend::AddSyncedVisit(
db_->SetMayContainForeignVisits(true); db_->SetMayContainForeignVisits(true);
if (can_add_foreign_visits_to_segments_ &&
CanAddForeignVisitToSegments(visit, local_device_originator_cache_guid_,
sync_device_info_)) {
AssignSegmentForNewVisit(url, visit.referring_visit, visit_id,
visit.transition, visit.visit_time);
}
ScheduleCommit(); ScheduleCommit();
return visit_id; return visit_id;
} }
@ -1647,10 +1776,18 @@ VisitID HistoryBackend::UpdateSyncedVisit(
updated_row.referring_visit = original_row.referring_visit; updated_row.referring_visit = original_row.referring_visit;
updated_row.opener_visit = original_row.opener_visit; updated_row.opener_visit = original_row.opener_visit;
// `segment_id` is computed locally and not synced, so keep any value from the
// existing row. It'll be updated below, if necessary.
updated_row.segment_id = original_row.segment_id;
if (!db_->UpdateVisitRow(updated_row)) { if (!db_->UpdateVisitRow(updated_row)) {
return kInvalidVisitID; return kInvalidVisitID;
} }
if (can_add_foreign_visits_to_segments_) {
UpdateSegmentForExistingForeignVisit(updated_row);
}
// If provided, add or update the ContextAnnotations. // If provided, add or update the ContextAnnotations.
if (context_annotations) { if (context_annotations) {
VisitContextAnnotations existing_annotations; VisitContextAnnotations existing_annotations;
@ -1690,7 +1827,15 @@ bool HistoryBackend::UpdateVisitReferrerOpenerIDs(VisitID visit_id,
row.referring_visit = referrer_id; row.referring_visit = referrer_id;
row.opener_visit = opener_id; row.opener_visit = opener_id;
return db_->UpdateVisitRow(row); bool result = db_->UpdateVisitRow(row);
if (result && can_add_foreign_visits_to_segments_) {
UpdateSegmentForExistingForeignVisit(row);
}
ScheduleCommit();
return result;
} }
void HistoryBackend::DeleteAllForeignVisitsAndResetIsKnownToSync() { void HistoryBackend::DeleteAllForeignVisitsAndResetIsKnownToSync() {
@ -2198,11 +2343,19 @@ void HistoryBackend::ReplaceClusters(
ScheduleCommit(); ScheduleCommit();
} }
int64_t HistoryBackend::ReserveNextClusterId() { int64_t HistoryBackend::ReserveNextClusterIdWithVisit(
TRACE_EVENT0("browser", "HistoryBackend::ReserveNextClusterId"); const ClusterVisit& cluster_visit) {
return db_ ? db_->ReserveNextClusterId(/*originator_cache_guid=*/"", TRACE_EVENT0("browser", "HistoryBackend::ReserveNextClusterIdWithVisit");
int64_t cluster_id =
db_ ? db_->ReserveNextClusterId(/*originator_cache_guid=*/"",
/*originator_cluster_id=*/0) /*originator_cluster_id=*/0)
: 0; : 0;
if (cluster_id == 0) {
// DB write was not successful, just return.
return 0;
}
AddVisitsToCluster(cluster_id, {cluster_visit});
return cluster_id;
} }
void HistoryBackend::AddVisitsToCluster( void HistoryBackend::AddVisitsToCluster(
@ -2349,7 +2502,7 @@ VisitVector HistoryBackend::GetRedirectChain(VisitRow visit) {
if (!db_->GetRowForVisit(visit.referring_visit, &referring_visit)) if (!db_->GetRowForVisit(visit.referring_visit, &referring_visit))
return {}; return {};
if (visit_set.count(referring_visit.visit_id)) { if (visit_set.count(referring_visit.visit_id)) {
NOTREACHED() << "Loop in visit redirect chain, giving up"; DLOG(WARNING) << "Loop in visit redirect chain, possible db corruption";
break; break;
} }
result.push_back(referring_visit); result.push_back(referring_visit);
@ -2692,14 +2845,10 @@ void HistoryBackend::DeleteFTSIndexDatabases() {
base::FilePath::StringType filepattern = FILE_PATH_LITERAL("History Index *"); base::FilePath::StringType filepattern = FILE_PATH_LITERAL("History Index *");
base::FileEnumerator enumerator(history_dir_, false, base::FileEnumerator enumerator(history_dir_, false,
base::FileEnumerator::FILES, filepattern); base::FileEnumerator::FILES, filepattern);
int num_databases_deleted = 0;
base::FilePath current_file; base::FilePath current_file;
while (!(current_file = enumerator.Next()).empty()) { while (!(current_file = enumerator.Next()).empty()) {
if (sql::Database::Delete(current_file)) sql::Database::Delete(current_file);
num_databases_deleted++;
} }
UMA_HISTOGRAM_COUNTS_1M("History.DeleteFTSIndexDatabases",
num_databases_deleted);
} }
std::vector<favicon_base::FaviconRawBitmapResult> HistoryBackend::GetFavicon( std::vector<favicon_base::FaviconRawBitmapResult> HistoryBackend::GetFavicon(
@ -3321,6 +3470,20 @@ void HistoryBackend::KillHistoryDatabase() {
CloseAllDatabases(); CloseAllDatabases();
} }
void HistoryBackend::SetSyncDeviceInfo(SyncDeviceInfoMap sync_device_info) {
sync_device_info_ = std::move(sync_device_info);
}
void HistoryBackend::SetLocalDeviceOriginatorCacheGuid(
std::string local_device_originator_cache_guid) {
local_device_originator_cache_guid_ =
std::move(local_device_originator_cache_guid);
}
void HistoryBackend::SetCanAddForeignVisitsToSegments(bool add_foreign_visits) {
can_add_foreign_visits_to_segments_ = add_foreign_visits;
}
void HistoryBackend::ProcessDBTask( void HistoryBackend::ProcessDBTask(
std::unique_ptr<HistoryDBTask> task, std::unique_ptr<HistoryDBTask> task,
scoped_refptr<base::SequencedTaskRunner> origin_loop, scoped_refptr<base::SequencedTaskRunner> origin_loop,

View file

@ -15,6 +15,7 @@
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/functional/bind.h" #include "base/functional/bind.h"
#include "base/functional/callback.h" #include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/observer_list.h" #include "base/observer_list.h"
@ -308,7 +309,7 @@ class DeviceVariationsRestrictionByPolicyApplicator {
} }
} }
PrefService* const policy_pref_service_; const raw_ptr<PrefService, ExperimentalAsh> policy_pref_service_;
// Watch the changes of the variations prefs. // Watch the changes of the variations prefs.
std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_; std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
@ -927,6 +928,10 @@ bool VariationsService::SetUpFieldTrials(
&safe_seed_manager_, /*add_entropy_source_to_variations_ids=*/true); &safe_seed_manager_, /*add_entropy_source_to_variations_ids=*/true);
} }
SeedType VariationsService::GetSeedType() const {
return field_trial_creator_.seed_type();
}
void VariationsService::OverrideCachedUIStrings() { void VariationsService::OverrideCachedUIStrings() {
field_trial_creator_.OverrideCachedUIStrings(); field_trial_creator_.OverrideCachedUIStrings();
} }

View file

@ -116,7 +116,11 @@ about:version template page
</if> </if>
<if expr="is_android"> <if expr="is_android">
<tr> <tr>
<td class="label">targetSdkVersion</td> <td class="label">APK versionCode</td>
<td class="version">$i18n{version_code}</td>
</tr>
<tr>
<td class="label">APK targetSdkVersion</td>
<td class="version">$i18n{target_sdk_version}</td> <td class="version">$i18n{target_sdk_version}</td>
</tr> </tr>
<tr> <tr>
@ -198,6 +202,10 @@ about:version template page
<td class="version" id="linker">$i18n{linker}</td> <td class="version" id="linker">$i18n{linker}</td>
</tr> </tr>
</if> </if>
<tr id="variations-seed-section" hidden>
<td class="label">$i18n{variations_seed_name}</td>
<td class="version" id="variations-seed">$i18n{variations_seed}</td>
</tr>
<tr id="variations-section"> <tr id="variations-section">
<td class="label">$i18n{variations_name}</td> <td class="label">$i18n{variations_name}</td>
<td class="version" id="variations-list"></td> <td class="version" id="variations-list"></td>

View file

@ -225,6 +225,7 @@ source_set("browser") {
"//services/viz/privileged/mojom", "//services/viz/privileged/mojom",
"//services/viz/public/cpp/gpu", "//services/viz/public/cpp/gpu",
"//services/viz/public/mojom", "//services/viz/public/mojom",
"//services/webnn/public/mojom",
"//skia", "//skia",
"//skia:skia_resources", "//skia:skia_resources",
"//skia/public/mojom", "//skia/public/mojom",
@ -1121,8 +1122,11 @@ source_set("browser") {
"interest_group/ad_auction_result_metrics.h", "interest_group/ad_auction_result_metrics.h",
"interest_group/ad_auction_service_impl.cc", "interest_group/ad_auction_service_impl.cc",
"interest_group/ad_auction_service_impl.h", "interest_group/ad_auction_service_impl.h",
"interest_group/auction_metrics_recorder.cc",
"interest_group/auction_metrics_recorder.h",
"interest_group/auction_process_manager.cc", "interest_group/auction_process_manager.cc",
"interest_group/auction_process_manager.h", "interest_group/auction_process_manager.h",
"interest_group/auction_result.h",
"interest_group/auction_runner.cc", "interest_group/auction_runner.cc",
"interest_group/auction_runner.h", "interest_group/auction_runner.h",
"interest_group/auction_shared_storage_host.cc", "interest_group/auction_shared_storage_host.cc",
@ -1207,6 +1211,8 @@ source_set("browser") {
"loader/prefetch_url_loader.h", "loader/prefetch_url_loader.h",
"loader/prefetch_url_loader_service.cc", "loader/prefetch_url_loader_service.cc",
"loader/prefetch_url_loader_service.h", "loader/prefetch_url_loader_service.h",
"loader/resource_cache_manager.cc",
"loader/resource_cache_manager.h",
"loader/shared_cors_origin_access_list_impl.cc", "loader/shared_cors_origin_access_list_impl.cc",
"loader/shared_cors_origin_access_list_impl.h", "loader/shared_cors_origin_access_list_impl.h",
"loader/url_loader_throttles.cc", "loader/url_loader_throttles.cc",
@ -1467,6 +1473,8 @@ source_set("browser") {
"preloading/prefetch/prefetch_streaming_url_loader_status.h", "preloading/prefetch/prefetch_streaming_url_loader_status.h",
"preloading/prefetch/prefetch_type.cc", "preloading/prefetch/prefetch_type.cc",
"preloading/prefetch/prefetch_type.h", "preloading/prefetch/prefetch_type.h",
"preloading/prefetch/prefetch_url_loader_helper.cc",
"preloading/prefetch/prefetch_url_loader_helper.h",
"preloading/prefetch/prefetch_url_loader_interceptor.cc", "preloading/prefetch/prefetch_url_loader_interceptor.cc",
"preloading/prefetch/prefetch_url_loader_interceptor.h", "preloading/prefetch/prefetch_url_loader_interceptor.h",
"preloading/prefetch/proxy_lookup_client_impl.cc", "preloading/prefetch/proxy_lookup_client_impl.cc",
@ -1507,6 +1515,8 @@ source_set("browser") {
"preloading/prerender/prerender_new_tab_handle.h", "preloading/prerender/prerender_new_tab_handle.h",
"preloading/prerender/prerender_subframe_navigation_throttle.cc", "preloading/prerender/prerender_subframe_navigation_throttle.cc",
"preloading/prerender/prerender_subframe_navigation_throttle.h", "preloading/prerender/prerender_subframe_navigation_throttle.h",
"preloading/prerender/prerender_trigger_type_impl.cc",
"preloading/prerender/prerender_trigger_type_impl.h",
"preloading/prerenderer.h", "preloading/prerenderer.h",
"preloading/prerenderer_impl.cc", "preloading/prerenderer_impl.cc",
"preloading/prerenderer_impl.h", "preloading/prerenderer_impl.h",
@ -1585,6 +1595,8 @@ source_set("browser") {
"renderer_host/code_cache_host_impl.h", "renderer_host/code_cache_host_impl.h",
"renderer_host/commit_deferring_condition_runner.cc", "renderer_host/commit_deferring_condition_runner.cc",
"renderer_host/commit_deferring_condition_runner.h", "renderer_host/commit_deferring_condition_runner.h",
"renderer_host/concurrent_navigations_commit_deferring_condition.cc",
"renderer_host/concurrent_navigations_commit_deferring_condition.h",
"renderer_host/cookie_utils.cc", "renderer_host/cookie_utils.cc",
"renderer_host/cookie_utils.h", "renderer_host/cookie_utils.h",
"renderer_host/cross_origin_opener_policy_access_report_manager.cc", "renderer_host/cross_origin_opener_policy_access_report_manager.cc",
@ -1715,6 +1727,7 @@ source_set("browser") {
"renderer_host/isolated_web_app_throttle.h", "renderer_host/isolated_web_app_throttle.h",
"renderer_host/keep_alive_handle_factory.cc", "renderer_host/keep_alive_handle_factory.cc",
"renderer_host/keep_alive_handle_factory.h", "renderer_host/keep_alive_handle_factory.h",
"renderer_host/loading_state.h",
"renderer_host/local_network_access_util.cc", "renderer_host/local_network_access_util.cc",
"renderer_host/local_network_access_util.h", "renderer_host/local_network_access_util.h",
"renderer_host/media/aec_dump_manager_impl.cc", "renderer_host/media/aec_dump_manager_impl.cc",
@ -1799,6 +1812,12 @@ source_set("browser") {
"renderer_host/navigation_request_info.h", "renderer_host/navigation_request_info.h",
"renderer_host/navigation_throttle_runner.cc", "renderer_host/navigation_throttle_runner.cc",
"renderer_host/navigation_throttle_runner.h", "renderer_host/navigation_throttle_runner.h",
"renderer_host/navigation_transitions/navigation_entry_screenshot.cc",
"renderer_host/navigation_transitions/navigation_entry_screenshot.h",
"renderer_host/navigation_transitions/navigation_entry_screenshot_cache.cc",
"renderer_host/navigation_transitions/navigation_entry_screenshot_cache.h",
"renderer_host/navigation_transitions/navigation_entry_screenshot_manager.cc",
"renderer_host/navigation_transitions/navigation_entry_screenshot_manager.h",
"renderer_host/navigation_type.h", "renderer_host/navigation_type.h",
"renderer_host/navigator.cc", "renderer_host/navigator.cc",
"renderer_host/navigator.h", "renderer_host/navigator.h",
@ -2231,6 +2250,8 @@ source_set("browser") {
"webid/flags.h", "webid/flags.h",
"webid/idp_network_request_manager.cc", "webid/idp_network_request_manager.cc",
"webid/idp_network_request_manager.h", "webid/idp_network_request_manager.h",
"webid/mdocs/mdoc_provider.cc",
"webid/mdocs/mdoc_provider.h",
"webid/webid_utils.cc", "webid/webid_utils.cc",
"webid/webid_utils.h", "webid/webid_utils.h",
"webrtc/webrtc_connections_observer.cc", "webrtc/webrtc_connections_observer.cc",
@ -2271,6 +2292,8 @@ source_set("browser") {
"webui/web_ui_impl.h", "webui/web_ui_impl.h",
"webui/web_ui_main_frame_observer.cc", "webui/web_ui_main_frame_observer.cc",
"webui/web_ui_main_frame_observer.h", "webui/web_ui_main_frame_observer.h",
"webui/web_ui_managed_interface.cc",
"webui/web_ui_managed_interface.h",
"webui/web_ui_message_handler.cc", "webui/web_ui_message_handler.cc",
"webui/web_ui_url_loader_factory.cc", "webui/web_ui_url_loader_factory.cc",
"worker_host/dedicated_worker_host.cc", "worker_host/dedicated_worker_host.cc",
@ -2377,13 +2400,15 @@ source_set("browser") {
"lock_screen/lock_screen_storage_impl.h", "lock_screen/lock_screen_storage_impl.h",
"ml/ml_service_impl_cros.cc", "ml/ml_service_impl_cros.cc",
"ml/ml_service_impl_cros.h", "ml/ml_service_impl_cros.h",
"renderer_host/pepper/firewall_hole_proxy.cc",
"smart_card/smart_card_reader_tracker.cc", "smart_card/smart_card_reader_tracker.cc",
"smart_card/smart_card_reader_tracker.h", "smart_card/smart_card_reader_tracker.h",
"smart_card/smart_card_reader_tracker_impl.cc",
"smart_card/smart_card_reader_tracker_impl.h",
"smart_card/smart_card_service.cc", "smart_card/smart_card_service.cc",
"smart_card/smart_card_service.h", "smart_card/smart_card_service.h",
] ]
deps += [ deps += [
"//chromeos/components/firewall_hole",
"//chromeos/crosapi/mojom", "//chromeos/crosapi/mojom",
"//chromeos/services/machine_learning/public/cpp", "//chromeos/services/machine_learning/public/cpp",
"//chromeos/services/machine_learning/public/mojom", "//chromeos/services/machine_learning/public/mojom",
@ -2462,10 +2487,10 @@ source_set("browser") {
] ]
deps += [ deps += [
"//third_party/abseil-cpp:absl", "//third_party/abseil-cpp:absl",
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics:fuchsia.accessibility.semantics_hlcpp", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics:fuchsia.accessibility.semantics_cpp",
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.accessibility.semantics:fuchsia.accessibility.semantics_cpp_hlcpp_conversion",
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mediacodec:fuchsia.mediacodec_hlcpp", "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.mediacodec:fuchsia.mediacodec_hlcpp",
"//third_party/fuchsia-sdk/sdk/pkg/inspect", "//third_party/fuchsia-sdk/sdk/pkg/inspect",
"//third_party/fuchsia-sdk/sdk/pkg/scenic_cpp",
"//third_party/fuchsia-sdk/sdk/pkg/sys_inspect_cpp", "//third_party/fuchsia-sdk/sdk/pkg/sys_inspect_cpp",
"//third_party/fuchsia-sdk/sdk/pkg/zx", "//third_party/fuchsia-sdk/sdk/pkg/zx",
"//ui/accessibility", "//ui/accessibility",
@ -2594,6 +2619,8 @@ source_set("browser") {
"renderer_host/browser_compositor_ios.mm", "renderer_host/browser_compositor_ios.mm",
"renderer_host/delegated_frame_host_client_ios.cc", "renderer_host/delegated_frame_host_client_ios.cc",
"renderer_host/delegated_frame_host_client_ios.h", "renderer_host/delegated_frame_host_client_ios.h",
"renderer_host/popup_menu_helper_ios.h",
"renderer_host/popup_menu_helper_ios.mm",
"renderer_host/render_widget_host_view_ios.h", "renderer_host/render_widget_host_view_ios.h",
"renderer_host/render_widget_host_view_ios.mm", "renderer_host/render_widget_host_view_ios.mm",
"web_contents/web_contents_view_ios.h", "web_contents/web_contents_view_ios.h",
@ -3082,6 +3109,8 @@ source_set("browser") {
"web_contents/web_contents_view_android.cc", "web_contents/web_contents_view_android.cc",
"web_contents/web_contents_view_android.h", "web_contents/web_contents_view_android.h",
"webauth/web_authentication_delegate_android.cc", "webauth/web_authentication_delegate_android.cc",
"webid/mdocs/mdoc_provider_android.cc",
"webid/mdocs/mdoc_provider_android.h",
] ]
deps += [ deps += [
@ -3118,10 +3147,6 @@ source_set("browser") {
# The WebAuthn devtools protocol API is not supported in Android yet. # The WebAuthn devtools protocol API is not supported in Android yet.
"$target_gen_dir/devtools/protocol/web_authn.cc", "$target_gen_dir/devtools/protocol/web_authn.cc",
"$target_gen_dir/devtools/protocol/web_authn.h", "$target_gen_dir/devtools/protocol/web_authn.h",
# Devtools frontend not included in Android
"devtools/devtools_frontend_host_impl.cc",
"devtools/devtools_frontend_host_impl.h",
"devtools/protocol/webauthn_handler.cc", "devtools/protocol/webauthn_handler.cc",
"devtools/protocol/webauthn_handler.h", "devtools/protocol/webauthn_handler.h",
"media/session/audio_focus_delegate_default.cc", "media/session/audio_focus_delegate_default.cc",
@ -3188,11 +3213,20 @@ source_set("browser") {
deps += [ deps += [
"//components/speech:speech", "//components/speech:speech",
"//components/vector_icons", "//components/vector_icons",
"//content/browser/devtools:devtools_resources_extern",
"//content/browser/tracing:resources", "//content/browser/tracing:resources",
] ]
} }
# Devtools frontend not included in Android and iOS
if (!is_android && !is_ios) {
sources += [
"devtools/devtools_frontend_host_impl.cc",
"devtools/devtools_frontend_host_impl.h",
]
deps += [ "//content/browser/devtools:devtools_resources_extern" ]
}
if (use_aura) { if (use_aura) {
deps += [ deps += [
"//ui/aura", "//ui/aura",

View file

@ -34,6 +34,10 @@
#include "media/base/android/media_codec_util.h" // nogncheck #include "media/base/android/media_codec_util.h" // nogncheck
#endif #endif
#if BUILDFLAG(IS_WIN)
#include "base/win/windows_version.h"
#endif
namespace media { namespace media {
namespace { namespace {
@ -273,6 +277,8 @@ bool IsAACSupported(const AudioType& type) {
if (__builtin_available(macOS 10.15, *)) if (__builtin_available(macOS 10.15, *))
return true; return true;
return false; return false;
#elif BUILDFLAG(IS_WIN)
return base::win::GetVersion() >= base::win::Version::WIN11_22H2;
#else #else
return false; return false;
#endif #endif

View file

@ -49,7 +49,7 @@ VideoDecoderConfig::AlphaMode GetAlphaMode(const AVStream* stream) {
VideoColorSpace GetGuessedColorSpace(const VideoColorSpace& color_space) { VideoColorSpace GetGuessedColorSpace(const VideoColorSpace& color_space) {
return VideoColorSpace::FromGfxColorSpace( return VideoColorSpace::FromGfxColorSpace(
// convert to gfx color space and make a guess. // convert to gfx color space and make a guess.
color_space.ToGfxColorSpace()); color_space.GuessGfxColorSpace());
} }
} // namespace } // namespace

View file

@ -32,8 +32,9 @@ is_cast_media_device = is_castos || is_cast_android
# allow_oop_video_decoder where appropriate. Also, finish replacing usages of # allow_oop_video_decoder where appropriate. Also, finish replacing usages of
# (is_linux || is_chromeos_ash) with allow_hosting_oop_video_decoder where # (is_linux || is_chromeos_ash) with allow_hosting_oop_video_decoder where
# appropriate. # appropriate.
allow_oop_video_decoder = is_linux || is_chromeos allow_hosting_oop_video_decoder =
allow_hosting_oop_video_decoder = is_linux || is_chromeos_ash (is_chromeos_ash || is_linux) && (use_vaapi || use_v4l2_codec)
allow_oop_video_decoder = is_chromeos_lacros || allow_hosting_oop_video_decoder
declare_args() { declare_args() {
# Allows distributions to link pulseaudio directly (DT_NEEDED) instead of # Allows distributions to link pulseaudio directly (DT_NEEDED) instead of
@ -76,8 +77,6 @@ declare_args() {
# on-device decoding and bitstream passthrough as supported by device. # on-device decoding and bitstream passthrough as supported by device.
enable_platform_dts_audio = true enable_platform_dts_audio = true
enable_mse_mpeg2ts_stream_parser = true
# Enable Dolby Vision demuxing. Enabled by default for Chromecast and Windows. # Enable Dolby Vision demuxing. Enabled by default for Chromecast and Windows.
# Actual decoding must be provided by the platform. Since most Dolby Vision # Actual decoding must be provided by the platform. Since most Dolby Vision
# profiles use HEVC, `enable_platform_hevc` is required to enable this. # profiles use HEVC, `enable_platform_hevc` is required to enable this.
@ -93,9 +92,6 @@ declare_args() {
# kAllowClearDolbyVisionInMseWhenPlatformEncryptedDvEnabled. # kAllowClearDolbyVisionInMseWhenPlatformEncryptedDvEnabled.
enable_platform_encrypted_dolby_vision = true enable_platform_encrypted_dolby_vision = true
# Enable HLS with SAMPLE-AES decryption.
enable_hls_sample_aes = true
# Enable logging override, e.g. enable DVLOGs through level 2 at build time. # Enable logging override, e.g. enable DVLOGs through level 2 at build time.
# On Cast devices, these are logged as INFO. # On Cast devices, these are logged as INFO.
# When enabled on Fuchsia, these are logged as VLOGs. # When enabled on Fuchsia, these are logged as VLOGs.
@ -123,11 +119,12 @@ declare_args() {
enable_av1_decoder = enable_dav1d_decoder enable_av1_decoder = enable_dav1d_decoder
# Enable HEVC/H265 demuxing. Actual decoding must be provided by the # Enable HEVC/H265 demuxing. Actual decoding must be provided by the
# platform. # platform. Always enable this for Lacros, it determines support at runtime.
# TODO(b/194429120): Enable this for Lacros builds.
# TODO(crbug.com/1336055): Revisit the default value for this setting as it # TODO(crbug.com/1336055): Revisit the default value for this setting as it
# applies to video-capable devices. # applies to video-capable devices.
enable_platform_hevc = true enable_platform_hevc = true
enable_mse_mpeg2ts_stream_parser = true
} }
declare_args() { declare_args() {
@ -147,20 +144,10 @@ assert(!enable_platform_dolby_vision || proprietary_codecs,
assert( assert(
!enable_platform_encrypted_dolby_vision || enable_platform_dolby_vision, !enable_platform_encrypted_dolby_vision || enable_platform_dolby_vision,
"enable_platform_dolby_vision required for enable_platform_encrypted_dolby_vision") "enable_platform_dolby_vision required for enable_platform_encrypted_dolby_vision")
assert(!enable_hls_sample_aes || proprietary_codecs,
"proprietary_codecs required for enable_hls_sample_aes")
assert(!enable_platform_dts_audio || proprietary_codecs, assert(!enable_platform_dts_audio || proprietary_codecs,
"proprietary_codecs required for enable_platform_dts_audio") "proprietary_codecs required for enable_platform_dts_audio")
assert(!enable_hls_sample_aes || enable_mse_mpeg2ts_stream_parser,
"enable_mse_mpeg2ts_stream_parser required for enable_hls_sample_aes")
assert(!enable_hls_demuxer || enable_mse_mpeg2ts_stream_parser,
"enable_mse_mpeg2ts_stream_parser required for enable_hls_demuxer")
assert(!enable_platform_hevc || proprietary_codecs, assert(!enable_platform_hevc || proprietary_codecs,
"proprietary_codecs required for enable_platform_hevc") "proprietary_codecs required for enable_platform_hevc")
assert(!enable_hevc_parser_and_hw_decoder || enable_platform_hevc, assert(!enable_hevc_parser_and_hw_decoder || enable_platform_hevc,
"enable_platform_hevc required for enable_hevc_parser_and_hw_decoder") "enable_platform_hevc required for enable_hevc_parser_and_hw_decoder")
@ -258,8 +245,7 @@ if (is_cast_media_device) {
"video_decoder", "video_decoder",
] ]
_default_mojo_media_host = "gpu" _default_mojo_media_host = "gpu"
} else if (is_mac || (is_win && (enable_platform_dts_audio || } else if (is_mac || is_win) {
enable_platform_ac3_eac3_audio))) {
_default_mojo_media_services = [ _default_mojo_media_services = [
"audio_decoder", "audio_decoder",
"audio_encoder", "audio_encoder",