#include "components/embedder_support/user_agent_utils.h"
#include <string>
#include <vector>
#include "base/command_line.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/system/sys_info.h"
#include "base/test/gtest_util.h"
#include "base/test/scoped_command_line.h"
#include "base/test/scoped_feature_list.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/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "components/version_info/version_info.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/user_agent.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/user_agent/user_agent_brand_version_type.h"
#include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
#include "third_party/re2/src/re2/re2.h"
#if BUILDFLAG(IS_POSIX)
#include <sys/utsname.h>
#endif
#if BUILDFLAG(IS_WIN)
#include <windows.foundation.metadata.h>
#include <wrl.h>
#include "base/win/core_winrt_util.h"
#include "base/win/hstring_reference.h"
#include "base/win/scoped_hstring.h"
#include "base/win/scoped_winrt_initializer.h"
#endif
namespace embedder_support {
namespace {
static constexpr char kChromeProductVersionRegex[] = …;
#if BUILDFLAG(IS_ANDROID)
const char kAndroid[] =
"Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/%s.0.0.0 "
"%sSafari/537.36";
#else
const char kDesktop[] = …;
#endif
void CheckUserAgentStringOrdering(bool mobile_device) { … }
#if BUILDFLAG(IS_WIN)
void VerifyWinPlatformVersion(std::string version) {
base::win::ScopedWinrtInitializer scoped_winrt_initializer;
ASSERT_TRUE(scoped_winrt_initializer.Succeeded());
base::win::HStringReference api_info_class_name(
RuntimeClass_Windows_Foundation_Metadata_ApiInformation);
Microsoft::WRL::ComPtr<
ABI::Windows::Foundation::Metadata::IApiInformationStatics>
api;
HRESULT result = base::win::RoGetActivationFactory(api_info_class_name.Get(),
IID_PPV_ARGS(&api));
ASSERT_EQ(result, S_OK);
base::win::HStringReference universal_contract_name(
L"Windows.Foundation.UniversalApiContract");
std::vector<std::string> version_parts = base::SplitString(
version, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
EXPECT_EQ(version_parts[2], "0");
int major_version;
base::StringToInt(version_parts[0], &major_version);
EXPECT_LE(major_version,
GetHighestKnownUniversalApiContractVersionForTesting());
int minor_version;
base::StringToInt(version_parts[1], &minor_version);
boolean is_supported = false;
result = api->IsApiContractPresentByMajor(universal_contract_name.Get(),
major_version, &is_supported);
EXPECT_EQ(result, S_OK);
EXPECT_TRUE(is_supported)
<< " expected major version " << major_version << " to be supported.";
result = api->IsApiContractPresentByMajorAndMinor(
universal_contract_name.Get(), major_version, minor_version,
&is_supported);
EXPECT_EQ(result, S_OK);
EXPECT_TRUE(is_supported)
<< " expected major version " << major_version << " and minor version "
<< minor_version << " to be supported.";
result = api->IsApiContractPresentByMajorAndMinor(
universal_contract_name.Get(), major_version, minor_version + 1,
&is_supported);
EXPECT_EQ(result, S_OK);
EXPECT_FALSE(is_supported) << " expected minor version " << minor_version + 1
<< " to not be supported with a major version of "
<< major_version << ".";
result = api->IsApiContractPresentByMajor(universal_contract_name.Get(),
major_version + 1, &is_supported);
EXPECT_EQ(result, S_OK);
EXPECT_FALSE(is_supported) << " expected major version " << major_version + 1
<< " to not be supported.";
}
#endif
bool ContainsBrandVersion(const blink::UserAgentBrandList& brand_list,
const blink::UserAgentBrandVersion brand_version) { … }
}
class UserAgentUtilsTest : public testing::Test,
public testing::WithParamInterface<bool> { … };
TEST_F(UserAgentUtilsTest, UserAgentStringOrdering) { … }
TEST_F(UserAgentUtilsTest, CustomUserAgent) { … }
TEST_F(UserAgentUtilsTest, InvalidCustomUserAgent) { … }
TEST_F(UserAgentUtilsTest, UserAgentStringReduced) { … }
TEST_F(UserAgentUtilsTest, UserAgentStringFull) { … }
TEST_F(UserAgentUtilsTest, ReduceUserAgentPlatformOsCpu) { … }
#if BUILDFLAG(IS_ANDROID)
TEST_F(UserAgentUtilsTest, ReduceUserAgentAndroidVersionDeviceModel) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
{blink::features::kReduceUserAgentMinorVersion,
blink::features::kReduceUserAgentAndroidVersionDeviceModel},
{});
const char* const kArguments[] = {"chrome"};
base::test::ScopedCommandLine scoped_command_line;
base::CommandLine* command_line = scoped_command_line.GetProcessCommandLine();
command_line->InitFromArgv(1, kArguments);
ASSERT_FALSE(command_line->HasSwitch(switches::kUseMobileUserAgent));
{
std::string buffer = GetUserAgent();
EXPECT_EQ("Linux; Android 10; K", GetUserAgentPlatformOsCpu(buffer));
std::string device_compat = "";
EXPECT_EQ(buffer,
base::StringPrintf(kAndroid,
version_info::GetMajorVersionNumber().c_str(),
device_compat.c_str()));
}
command_line->AppendSwitch(switches::kUseMobileUserAgent);
ASSERT_TRUE(command_line->HasSwitch(switches::kUseMobileUserAgent));
{
std::string buffer = GetUserAgent();
EXPECT_EQ("Linux; Android 10; K", GetUserAgentPlatformOsCpu(buffer));
std::string device_compat = "Mobile ";
EXPECT_EQ(buffer,
base::StringPrintf(kAndroid,
version_info::GetMajorVersionNumber().c_str(),
device_compat.c_str()));
}
}
#endif
TEST_F(UserAgentUtilsTest, UserAgentMetadata) { … }
TEST_F(UserAgentUtilsTest, UserAgentMetadataXR) { … }
TEST_F(UserAgentUtilsTest, GenerateBrandVersionListUnbranded) { … }
TEST_F(UserAgentUtilsTest, GenerateBrandVersionListUnbrandedVerifySeedChanges) { … }
TEST_F(UserAgentUtilsTest, GenerateBrandVersionListWithGreaseBrandOverride) { … }
TEST_F(UserAgentUtilsTest,
GenerateBrandVersionListWithGreaseBrandAndVersionOverride) { … }
TEST_F(UserAgentUtilsTest, GenerateBrandVersionListWithGreaseVersionOverride) { … }
TEST_F(UserAgentUtilsTest, GenerateBrandVersionListWithBrand) { … }
TEST_F(UserAgentUtilsTest, GenerateBrandVersionListInvalidSeed) { … }
TEST_F(UserAgentUtilsTest, GetGreasedUserAgentBrandVersionOldAlgorithm) { … }
TEST_F(UserAgentUtilsTest,
GetGreasedUserAgentBrandVersionOldAlgorithmIgnoresBrandOverrides) { … }
TEST_F(UserAgentUtilsTest,
GetGreasedUserAgentBrandVersionOldAlgorithmIgnoresVersionOverrides) { … }
TEST_F(
UserAgentUtilsTest,
GetGreasedUserAgentBrandVersionOldAlgorithmIgnoresBrandAndVersionOverrides) { … }
TEST_F(UserAgentUtilsTest, GetGreasedUserAgentBrandVersionNewAlgorithm) { … }
TEST_F(UserAgentUtilsTest,
GetGreasedUserAgentBrandVersionNewAlgorithmBrandOverride) { … }
TEST_F(UserAgentUtilsTest,
GetGreasedUserAgentBrandVersionNewAlgorithmVersionOverride) { … }
TEST_F(UserAgentUtilsTest,
GetGreasedUserAgentBrandVersionNewAlgorithmBrandAndVersionOverride) { … }
TEST_F(UserAgentUtilsTest, GetGreasedUserAgentBrandVersionFullVersions) { … }
TEST_F(UserAgentUtilsTest, GetGreasedUserAgentBrandVersionEnterpriseOverride) { … }
TEST_F(
UserAgentUtilsTest,
GetGreasedUserAgentBrandVersionEnterpriseOverrideSupersedesOtherOverrides) { … }
TEST_F(UserAgentUtilsTest, GetGreasedUserAgentBrandVersionNoLeadingWhitespace) { … }
TEST_F(UserAgentUtilsTest, GetProductAndVersion) { … }
TEST_F(UserAgentUtilsTest, GetUserAgent) { … }
TEST_F(UserAgentUtilsTest, HeadlessUserAgent) { … }
}