#include "components/embedder_support/user_agent_utils.h"
#include <string>
#include <vector>
#include "base/command_line.h"
#include "base/debug/stack_trace.h"
#include "base/feature_list.h"
#include "base/no_destructor.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/system/sys_info.h"
#include "base/version.h"
#include "build/branding_buildflags.h"
#include "build/build_config.h"
#include "components/embedder_support/pref_names.h"
#include "components/embedder_support/switches.h"
#include "components/policy/core/common/policy_pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/version_info/version_info.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/user_agent.h"
#include "net/http/http_util.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
#if BUILDFLAG(IS_WIN)
#include <windows.h>
#include "base/win/registry.h"
#include "base/win/windows_version.h"
#endif
namespace embedder_support {
namespace {
#if BUILDFLAG(IS_WIN)
constexpr wchar_t kWindowsRuntimeWellKnownContractsRegKeyName[] =
L"SOFTWARE\\Microsoft\\WindowsRuntime\\WellKnownContracts";
constexpr wchar_t kUniversalApiContractName[] =
L"Windows.Foundation.UniversalApiContract";
const int kHighestKnownUniversalApiContractVersion = 15;
int GetPreRS5UniversalApiContractVersion() {
const base::win::Version version = base::win::OSInfo::Kernel32Version();
if (version == base::win::Version::WIN10) {
return 1;
}
if (version == base::win::Version::WIN10_TH2) {
return 2;
}
if (version == base::win::Version::WIN10_RS1) {
return 3;
}
if (version == base::win::Version::WIN10_RS2) {
return 4;
}
if (version == base::win::Version::WIN10_RS3) {
return 5;
}
if (version == base::win::Version::WIN10_RS4) {
return 6;
}
NOTREACHED_IN_MIGRATION();
return 0;
}
const std::string& GetUniversalApiContractVersion() {
static const base::NoDestructor<std::string> universal_api_contract_version(
[] {
int major_version = 0;
int minor_version = 0;
if (base::win::OSInfo::Kernel32Version() <=
base::win::Version::WIN10_RS4) {
major_version = GetPreRS5UniversalApiContractVersion();
} else {
base::win::RegKey version_key(
HKEY_LOCAL_MACHINE, kWindowsRuntimeWellKnownContractsRegKeyName,
KEY_QUERY_VALUE | KEY_WOW64_64KEY);
if (version_key.Valid()) {
DWORD universal_api_contract_version = 0;
LONG result = version_key.ReadValueDW(
kUniversalApiContractName, &universal_api_contract_version);
if (result == ERROR_SUCCESS) {
major_version = HIWORD(universal_api_contract_version);
minor_version = LOWORD(universal_api_contract_version);
} else {
major_version = kHighestKnownUniversalApiContractVersion;
}
} else {
major_version = kHighestKnownUniversalApiContractVersion;
}
}
return base::StrCat({base::NumberToString(major_version), ".",
base::NumberToString(minor_version), ".0"});
}());
return *universal_api_contract_version;
}
const std::string& GetWindowsPlatformVersion() {
return GetUniversalApiContractVersion();
}
#endif
bool ShouldReduceUserAgentMinorVersion(
UserAgentReductionEnterprisePolicyState user_agent_reduction) { … }
bool ShouldSendUserAgentUnifiedPlatform(
UserAgentReductionEnterprisePolicyState user_agent_reduction) { … }
const blink::UserAgentBrandList GetUserAgentBrandList(
const std::string& major_version,
bool enable_updated_grease_by_policy,
const std::string& full_version,
blink::UserAgentBrandVersionType output_version_type) { … }
const blink::UserAgentBrandList GetUserAgentBrandMajorVersionList(
bool enable_updated_grease_by_policy) { … }
blink::UserAgentBrandList GetUserAgentBrandFullVersionList(
bool enable_updated_grease_by_policy) { … }
std::vector<std::string> GetFormFactorsClientHint(
const blink::UserAgentMetadata& metadata,
bool is_mobile) { … }
}
std::string GetProductAndVersion(
UserAgentReductionEnterprisePolicyState user_agent_reduction) { … }
std::string GetUserAgentInternal(
UserAgentReductionEnterprisePolicyState user_agent_reduction) { … }
std::optional<std::string> GetUserAgentFromCommandLine() { … }
std::string GetUserAgent(
UserAgentReductionEnterprisePolicyState user_agent_reduction) { … }
blink::UserAgentBrandList GenerateBrandVersionList(
int seed,
std::optional<std::string> brand,
const std::string& version,
std::optional<std::string> maybe_greasey_brand,
std::optional<std::string> maybe_greasey_version,
bool enable_updated_grease_by_policy,
blink::UserAgentBrandVersionType output_version_type) { … }
blink::UserAgentBrandVersion GetProcessedGreasedBrandVersion(
const std::string& greasey_brand,
const std::string& greasey_version,
blink::UserAgentBrandVersionType output_version_type) { … }
blink::UserAgentBrandVersion GetGreasedUserAgentBrandVersion(
std::vector<int> permuted_order,
int seed,
std::optional<std::string> maybe_greasey_brand,
std::optional<std::string> maybe_greasey_version,
bool enable_updated_grease_by_policy,
blink::UserAgentBrandVersionType output_version_type) { … }
std::string GetPlatformForUAMetadata() { … }
blink::UserAgentMetadata GetUserAgentMetadata(bool only_low_entropy_ch) { … }
blink::UserAgentMetadata GetUserAgentMetadata(const PrefService* pref_service,
bool only_low_entropy_ch) { … }
#if BUILDFLAG(IS_ANDROID)
void SetDesktopUserAgentOverride(content::WebContents* web_contents,
const blink::UserAgentMetadata& metadata,
bool override_in_new_tabs) {
const char kLinuxInfoStr[] = "X11; Linux x86_64";
blink::UserAgentOverride spoofed_ua;
spoofed_ua.ua_string_override = content::BuildUserAgentFromOSAndProduct(
kLinuxInfoStr, GetProductAndVersion());
spoofed_ua.ua_metadata_override = metadata;
spoofed_ua.ua_metadata_override->platform = "Linux";
spoofed_ua.ua_metadata_override->platform_version =
std::string();
spoofed_ua.ua_metadata_override->model = std::string();
spoofed_ua.ua_metadata_override->mobile = false;
spoofed_ua.ua_metadata_override->form_factors =
GetFormFactorsClientHint(metadata, false);
spoofed_ua.ua_metadata_override->architecture = "x86";
spoofed_ua.ua_metadata_override->bitness = "64";
spoofed_ua.ua_metadata_override->wow64 = false;
web_contents->SetUserAgentOverride(spoofed_ua, override_in_new_tabs);
}
#endif
#if BUILDFLAG(IS_WIN)
int GetHighestKnownUniversalApiContractVersionForTesting() {
return kHighestKnownUniversalApiContractVersion;
}
#endif
embedder_support::UserAgentReductionEnterprisePolicyState
GetUserAgentReductionFromPrefs(const PrefService* pref_service) { … }
}