[email protected] | efd2c3f | 2014-03-11 09:57:25 | [diff] [blame] | 1 | // Copyright 2014 The Chromium Authors. All rights reserved. |
[email protected] | 420286748 | 2010-08-27 19:28:25 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
[email protected] | efd2c3f | 2014-03-11 09:57:25 | [diff] [blame] | 5 | #include "content/public/common/user_agent.h" |
| 6 | |
avi | a9aa7a8 | 2015-12-25 03:06:31 | [diff] [blame] | 7 | #include <stdint.h> |
| 8 | |
Melissa Galonsky | 15417f9 | 2018-08-10 16:03:35 | [diff] [blame] | 9 | #include "base/feature_list.h" |
[email protected] | efd2c3f | 2014-03-11 09:57:25 | [diff] [blame] | 10 | #include "base/logging.h" |
| 11 | #include "base/strings/string_util.h" |
| 12 | #include "base/strings/stringprintf.h" |
Sebastien Marchand | 75a7cdf | 2018-11-13 23:47:03 | [diff] [blame] | 13 | #include "base/system/sys_info.h" |
[email protected] | efd2c3f | 2014-03-11 09:57:25 | [diff] [blame] | 14 | #include "build/build_config.h" |
tfarina | c2103c4 | 2015-10-27 21:37:34 | [diff] [blame] | 15 | #include "build/util/webkit_version.h" |
[email protected] | 420286748 | 2010-08-27 19:28:25 | [diff] [blame] | 16 | |
[email protected] | b4e3e8d5 | 2011-03-05 01:16:28 | [diff] [blame] | 17 | #if defined(OS_WIN) |
| 18 | #include "base/win/windows_version.h" |
Fabrice de Gans-Riberi | 91fa3505 | 2018-05-07 19:33:48 | [diff] [blame] | 19 | #elif (defined(OS_POSIX) && !defined(OS_MACOSX)) || defined(OS_FUCHSIA) |
| 20 | #include <sys/utsname.h> |
[email protected] | b4e3e8d5 | 2011-03-05 01:16:28 | [diff] [blame] | 21 | #endif |
| 22 | |
[email protected] | efd2c3f | 2014-03-11 09:57:25 | [diff] [blame] | 23 | namespace content { |
| 24 | |
Lei Zhang | 6c11913 | 2018-11-15 01:44:33 | [diff] [blame] | 25 | namespace { |
| 26 | |
Melissa Galonsky | 15417f9 | 2018-08-10 16:03:35 | [diff] [blame] | 27 | #if defined(OS_ANDROID) |
| 28 | const base::Feature kAndroidUserAgentStringContainsBuildId{ |
| 29 | "AndroidUserAgentStringContainsBuildId", base::FEATURE_DISABLED_BY_DEFAULT}; |
| 30 | #endif // defined(OS_ANDROID) |
| 31 | |
Lei Zhang | 6c11913 | 2018-11-15 01:44:33 | [diff] [blame] | 32 | std::string GetUserAgentPlatform() { |
| 33 | return |
| 34 | #if defined(OS_WIN) |
| 35 | ""; |
| 36 | #elif defined(OS_MACOSX) |
| 37 | "Macintosh; "; |
| 38 | #elif defined(USE_X11) || defined(USE_OZONE) |
| 39 | "X11; "; // strange, but that's what Firefox uses |
| 40 | #elif defined(OS_ANDROID) |
| 41 | "Linux; "; |
| 42 | #elif defined(OS_POSIX) || defined(OS_FUCHSIA) |
| 43 | "Unknown; "; |
| 44 | #endif |
| 45 | } |
| 46 | |
| 47 | } // namespace |
| 48 | |
[email protected] | 420286748 | 2010-08-27 19:28:25 | [diff] [blame] | 49 | std::string GetWebKitVersion() { |
[email protected] | 5193d537 | 2011-01-22 00:41:52 | [diff] [blame] | 50 | return base::StringPrintf("%d.%d (%s)", |
| 51 | WEBKIT_VERSION_MAJOR, |
| 52 | WEBKIT_VERSION_MINOR, |
| 53 | WEBKIT_SVN_REVISION); |
| 54 | } |
| 55 | |
| 56 | std::string GetWebKitRevision() { |
| 57 | return WEBKIT_SVN_REVISION; |
[email protected] | 420286748 | 2010-08-27 19:28:25 | [diff] [blame] | 58 | } |
| 59 | |
Melissa Galonsky | 15417f9 | 2018-08-10 16:03:35 | [diff] [blame] | 60 | std::string BuildOSCpuInfo(bool include_android_build_number) { |
[email protected] | 420286748 | 2010-08-27 19:28:25 | [diff] [blame] | 61 | std::string os_cpu; |
| 62 | |
[email protected] | abef4b33 | 2012-08-21 23:55:52 | [diff] [blame] | 63 | #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) ||\ |
| 64 | defined(OS_ANDROID) |
avi | a9aa7a8 | 2015-12-25 03:06:31 | [diff] [blame] | 65 | int32_t os_major_version = 0; |
| 66 | int32_t os_minor_version = 0; |
| 67 | int32_t os_bugfix_version = 0; |
[email protected] | 420286748 | 2010-08-27 19:28:25 | [diff] [blame] | 68 | base::SysInfo::OperatingSystemVersionNumbers(&os_major_version, |
| 69 | &os_minor_version, |
| 70 | &os_bugfix_version); |
| 71 | #endif |
[email protected] | abef4b33 | 2012-08-21 23:55:52 | [diff] [blame] | 72 | |
[email protected] | b4e3e8d5 | 2011-03-05 01:16:28 | [diff] [blame] | 73 | #if defined(OS_WIN) |
| 74 | std::string architecture_token; |
[email protected] | f48122119 | 2011-04-07 22:15:34 | [diff] [blame] | 75 | base::win::OSInfo* os_info = base::win::OSInfo::GetInstance(); |
| 76 | if (os_info->wow64_status() == base::win::OSInfo::WOW64_ENABLED) { |
[email protected] | b4e3e8d5 | 2011-03-05 01:16:28 | [diff] [blame] | 77 | architecture_token = "; WOW64"; |
| 78 | } else { |
[email protected] | f48122119 | 2011-04-07 22:15:34 | [diff] [blame] | 79 | base::win::OSInfo::WindowsArchitecture windows_architecture = |
Lei Zhang | 10d9e156 | 2019-03-14 18:46:02 | [diff] [blame] | 80 | os_info->GetArchitecture(); |
[email protected] | f48122119 | 2011-04-07 22:15:34 | [diff] [blame] | 81 | if (windows_architecture == base::win::OSInfo::X64_ARCHITECTURE) |
[email protected] | b4e3e8d5 | 2011-03-05 01:16:28 | [diff] [blame] | 82 | architecture_token = "; Win64; x64"; |
[email protected] | f48122119 | 2011-04-07 22:15:34 | [diff] [blame] | 83 | else if (windows_architecture == base::win::OSInfo::IA64_ARCHITECTURE) |
[email protected] | b4e3e8d5 | 2011-03-05 01:16:28 | [diff] [blame] | 84 | architecture_token = "; Win64; IA64"; |
| 85 | } |
Fabrice de Gans-Riberi | 91fa3505 | 2018-05-07 19:33:48 | [diff] [blame] | 86 | #elif defined(OS_ANDROID) |
Bo Liu | 4f2b4e14 | 2017-05-26 21:41:51 | [diff] [blame] | 87 | std::string android_version_str = base::SysInfo::OperatingSystemVersion(); |
Lei Zhang | 4b6ba9f | 2018-09-05 04:58:48 | [diff] [blame] | 88 | std::string android_info_str = GetAndroidOSInfo(include_android_build_number); |
Fabrice de Gans-Riberi | 91fa3505 | 2018-05-07 19:33:48 | [diff] [blame] | 89 | #elif (defined(OS_POSIX) && !defined(OS_MACOSX)) || defined(OS_FUCHSIA) |
| 90 | // Should work on any Posix system. |
| 91 | struct utsname unixinfo; |
| 92 | uname(&unixinfo); |
| 93 | |
| 94 | std::string cputype; |
| 95 | // special case for biarch systems |
| 96 | if (strcmp(unixinfo.machine, "x86_64") == 0 && |
| 97 | sizeof(void*) == sizeof(int32_t)) { // NOLINT |
| 98 | cputype.assign("i686 (x86_64)"); |
| 99 | } else { |
| 100 | cputype.assign(unixinfo.machine); |
| 101 | } |
[email protected] | abef4b33 | 2012-08-21 23:55:52 | [diff] [blame] | 102 | #endif |
| 103 | |
[email protected] | a77fa2dc | 2010-11-15 12:11:11 | [diff] [blame] | 104 | base::StringAppendF( |
[email protected] | 420286748 | 2010-08-27 19:28:25 | [diff] [blame] | 105 | &os_cpu, |
| 106 | #if defined(OS_WIN) |
robliao | ab2b82e8 | 2016-12-16 03:10:50 | [diff] [blame] | 107 | "Windows NT %d.%d%s", |
| 108 | os_major_version, |
| 109 | os_minor_version, |
[email protected] | b4e3e8d5 | 2011-03-05 01:16:28 | [diff] [blame] | 110 | architecture_token.c_str() |
[email protected] | 420286748 | 2010-08-27 19:28:25 | [diff] [blame] | 111 | #elif defined(OS_MACOSX) |
| 112 | "Intel Mac OS X %d_%d_%d", |
| 113 | os_major_version, |
| 114 | os_minor_version, |
| 115 | os_bugfix_version |
| 116 | #elif defined(OS_CHROMEOS) |
[email protected] | 71de819 | 2011-03-16 15:11:16 | [diff] [blame] | 117 | "CrOS " |
[email protected] | 71de819 | 2011-03-16 15:11:16 | [diff] [blame] | 118 | "%s %d.%d.%d", |
[email protected] | 3c2952a | 2011-03-03 19:49:47 | [diff] [blame] | 119 | cputype.c_str(), // e.g. i686 |
[email protected] | 420286748 | 2010-08-27 19:28:25 | [diff] [blame] | 120 | os_major_version, |
| 121 | os_minor_version, |
| 122 | os_bugfix_version |
[email protected] | d0924cb3 | 2012-06-19 16:56:09 | [diff] [blame] | 123 | #elif defined(OS_ANDROID) |
[email protected] | 8720e50e | 2012-09-20 10:43:58 | [diff] [blame] | 124 | "Android %s%s", |
| 125 | android_version_str.c_str(), |
[email protected] | abef4b33 | 2012-08-21 23:55:52 | [diff] [blame] | 126 | android_info_str.c_str() |
Fabrice de Gans-Riberi | 91fa3505 | 2018-05-07 19:33:48 | [diff] [blame] | 127 | #elif defined(OS_POSIX) || defined(OS_FUCHSIA) |
| 128 | "%s %s", |
| 129 | unixinfo.sysname, // e.g. Linux |
| 130 | cputype.c_str() // e.g. i686 |
[email protected] | 420286748 | 2010-08-27 19:28:25 | [diff] [blame] | 131 | #endif |
| 132 | ); // NOLINT |
| 133 | |
| 134 | return os_cpu; |
| 135 | } |
| 136 | |
John Delaney | ac24e57 | 2019-04-30 19:47:02 | [diff] [blame] | 137 | base::StringPiece GetFrozenUserAgent(bool mobile) { |
| 138 | #if defined(OS_ANDROID) |
| 139 | return mobile ? frozen_user_agent_strings::kAndroidMobile |
| 140 | : frozen_user_agent_strings::kAndroid; |
| 141 | #endif |
| 142 | return frozen_user_agent_strings::kDesktop; |
| 143 | } |
| 144 | |
gsennton | e98c5bb4 | 2015-03-30 19:22:57 | [diff] [blame] | 145 | std::string BuildUserAgentFromProduct(const std::string& product) { |
[email protected] | 3e807c4 | 2012-08-28 23:25:58 | [diff] [blame] | 146 | std::string os_info; |
Lei Zhang | 6c11913 | 2018-11-15 01:44:33 | [diff] [blame] | 147 | base::StringAppendF(&os_info, "%s%s", GetUserAgentPlatform().c_str(), |
Melissa Galonsky | 15417f9 | 2018-08-10 16:03:35 | [diff] [blame] | 148 | BuildOSCpuInfo(false).c_str()); |
gsennton | e98c5bb4 | 2015-03-30 19:22:57 | [diff] [blame] | 149 | return BuildUserAgentFromOSAndProduct(os_info, product); |
| 150 | } |
| 151 | |
Melissa Galonsky | 15417f9 | 2018-08-10 16:03:35 | [diff] [blame] | 152 | #if defined(OS_ANDROID) |
gsennton | e98c5bb4 | 2015-03-30 19:22:57 | [diff] [blame] | 153 | std::string BuildUserAgentFromProductAndExtraOSInfo( |
| 154 | const std::string& product, |
Melissa Galonsky | 15417f9 | 2018-08-10 16:03:35 | [diff] [blame] | 155 | const std::string& extra_os_info, |
Lei Zhang | 4b6ba9f | 2018-09-05 04:58:48 | [diff] [blame] | 156 | bool include_android_build_number) { |
gsennton | e98c5bb4 | 2015-03-30 19:22:57 | [diff] [blame] | 157 | std::string os_info; |
Lei Zhang | 6c11913 | 2018-11-15 01:44:33 | [diff] [blame] | 158 | base::StringAppendF(&os_info, "%s%s%s", GetUserAgentPlatform().c_str(), |
Melissa Galonsky | 15417f9 | 2018-08-10 16:03:35 | [diff] [blame] | 159 | BuildOSCpuInfo(include_android_build_number).c_str(), |
| 160 | extra_os_info.c_str()); |
[email protected] | 3e807c4 | 2012-08-28 23:25:58 | [diff] [blame] | 161 | return BuildUserAgentFromOSAndProduct(os_info, product); |
| 162 | } |
Lei Zhang | 4b6ba9f | 2018-09-05 04:58:48 | [diff] [blame] | 163 | |
| 164 | std::string GetAndroidOSInfo(bool include_android_build_number) { |
| 165 | std::string android_info_str; |
| 166 | |
| 167 | // Send information about the device. |
| 168 | bool semicolon_inserted = false; |
| 169 | std::string android_build_codename = base::SysInfo::GetAndroidBuildCodename(); |
| 170 | std::string android_device_name = base::SysInfo::HardwareModelName(); |
| 171 | if (!android_device_name.empty() && "REL" == android_build_codename) { |
| 172 | android_info_str += "; " + android_device_name; |
| 173 | semicolon_inserted = true; |
| 174 | } |
| 175 | |
| 176 | // Append the build ID. |
| 177 | if (base::FeatureList::IsEnabled(kAndroidUserAgentStringContainsBuildId) || |
| 178 | include_android_build_number) { |
| 179 | std::string android_build_id = base::SysInfo::GetAndroidBuildID(); |
| 180 | if (!android_build_id.empty()) { |
| 181 | if (!semicolon_inserted) |
| 182 | android_info_str += ";"; |
| 183 | android_info_str += " Build/" + android_build_id; |
| 184 | } |
| 185 | } |
| 186 | |
| 187 | return android_info_str; |
| 188 | } |
| 189 | #endif // defined(OS_ANDROID) |
[email protected] | d7196e3 | 2011-06-16 22:35:50 | [diff] [blame] | 190 | |
[email protected] | 3e807c4 | 2012-08-28 23:25:58 | [diff] [blame] | 191 | std::string BuildUserAgentFromOSAndProduct(const std::string& os_info, |
| 192 | const std::string& product) { |
| 193 | // Derived from Safari's UA string. |
[email protected] | d7196e3 | 2011-06-16 22:35:50 | [diff] [blame] | 194 | // This is done to expose our product name in a manner that is maximally |
| 195 | // compatible with Safari, we hope!! |
[email protected] | 3e807c4 | 2012-08-28 23:25:58 | [diff] [blame] | 196 | std::string user_agent; |
[email protected] | a77fa2dc | 2010-11-15 12:11:11 | [diff] [blame] | 197 | base::StringAppendF( |
[email protected] | d7196e3 | 2011-06-16 22:35:50 | [diff] [blame] | 198 | &user_agent, |
[email protected] | 3e807c4 | 2012-08-28 23:25:58 | [diff] [blame] | 199 | "Mozilla/5.0 (%s) AppleWebKit/%d.%d (KHTML, like Gecko) %s Safari/%d.%d", |
| 200 | os_info.c_str(), |
[email protected] | 420286748 | 2010-08-27 19:28:25 | [diff] [blame] | 201 | WEBKIT_VERSION_MAJOR, |
| 202 | WEBKIT_VERSION_MINOR, |
| 203 | product.c_str(), |
| 204 | WEBKIT_VERSION_MAJOR, |
| 205 | WEBKIT_VERSION_MINOR); |
[email protected] | d7196e3 | 2011-06-16 22:35:50 | [diff] [blame] | 206 | return user_agent; |
[email protected] | 420286748 | 2010-08-27 19:28:25 | [diff] [blame] | 207 | } |
| 208 | |
[email protected] | efd2c3f | 2014-03-11 09:57:25 | [diff] [blame] | 209 | } // namespace content |