• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "content/public/common/user_agent.h"
6 
7 #include "base/logging.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/stringprintf.h"
10 #include "base/sys_info.h"
11 #include "build/build_config.h"
12 
13 #if defined(OS_POSIX) && !defined(OS_MACOSX)
14 #include <sys/utsname.h>
15 #endif
16 
17 #if defined(OS_WIN)
18 #include "base/win/windows_version.h"
19 #endif
20 
21 // Generated
22 #include "webkit_version.h"  // NOLINT
23 
24 namespace content {
25 
26 namespace {
27 
28 #if defined(OS_ANDROID)
GetAndroidDeviceName()29 std::string GetAndroidDeviceName() {
30   return base::SysInfo::GetDeviceName();
31 }
32 #endif
33 
34 }  // namespace
35 
GetWebKitVersion()36 std::string GetWebKitVersion() {
37   return base::StringPrintf("%d.%d (%s)",
38                             WEBKIT_VERSION_MAJOR,
39                             WEBKIT_VERSION_MINOR,
40                             WEBKIT_SVN_REVISION);
41 }
42 
GetWebKitMajorVersion()43 int GetWebKitMajorVersion() {
44   return WEBKIT_VERSION_MAJOR;
45 }
46 
GetWebKitMinorVersion()47 int GetWebKitMinorVersion() {
48   return WEBKIT_VERSION_MINOR;
49 }
50 
GetWebKitRevision()51 std::string GetWebKitRevision() {
52   return WEBKIT_SVN_REVISION;
53 }
54 
BuildOSCpuInfo()55 std::string BuildOSCpuInfo() {
56   std::string os_cpu;
57 
58 #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS) ||\
59     defined(OS_ANDROID)
60   int32 os_major_version = 0;
61   int32 os_minor_version = 0;
62   int32 os_bugfix_version = 0;
63   base::SysInfo::OperatingSystemVersionNumbers(&os_major_version,
64                                                &os_minor_version,
65                                                &os_bugfix_version);
66 #endif
67 
68 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
69   // Should work on any Posix system.
70   struct utsname unixinfo;
71   uname(&unixinfo);
72 
73   std::string cputype;
74   // special case for biarch systems
75   if (strcmp(unixinfo.machine, "x86_64") == 0 &&
76       sizeof(void*) == sizeof(int32)) {  // NOLINT
77     cputype.assign("i686 (x86_64)");
78   } else {
79     cputype.assign(unixinfo.machine);
80   }
81 #endif
82 
83 #if defined(OS_WIN)
84   std::string architecture_token;
85   base::win::OSInfo* os_info = base::win::OSInfo::GetInstance();
86   if (os_info->wow64_status() == base::win::OSInfo::WOW64_ENABLED) {
87     architecture_token = "; WOW64";
88   } else {
89     base::win::OSInfo::WindowsArchitecture windows_architecture =
90         os_info->architecture();
91     if (windows_architecture == base::win::OSInfo::X64_ARCHITECTURE)
92       architecture_token = "; Win64; x64";
93     else if (windows_architecture == base::win::OSInfo::IA64_ARCHITECTURE)
94       architecture_token = "; Win64; IA64";
95   }
96 #endif
97 
98 #if defined(OS_ANDROID)
99   std::string android_version_str;
100   base::StringAppendF(
101       &android_version_str, "%d.%d", os_major_version, os_minor_version);
102   if (os_bugfix_version != 0)
103     base::StringAppendF(&android_version_str, ".%d", os_bugfix_version);
104 
105   std::string android_info_str;
106 
107   // Send information about the device.
108   bool semicolon_inserted = false;
109   std::string android_build_codename = base::SysInfo::GetAndroidBuildCodename();
110   std::string android_device_name = GetAndroidDeviceName();
111   if ("REL" == android_build_codename && android_device_name.size() > 0) {
112     android_info_str += "; " + android_device_name;
113     semicolon_inserted = true;
114   }
115 
116   // Append the build ID.
117   std::string android_build_id = base::SysInfo::GetAndroidBuildID();
118   if (android_build_id.size() > 0) {
119     if (!semicolon_inserted) {
120       android_info_str += ";";
121     }
122     android_info_str += " Build/" + android_build_id;
123   }
124 #endif
125 
126   base::StringAppendF(
127       &os_cpu,
128 #if defined(OS_WIN)
129       "Windows NT %d.%d%s",
130       os_major_version,
131       os_minor_version,
132       architecture_token.c_str()
133 #elif defined(OS_MACOSX)
134       "Intel Mac OS X %d_%d_%d",
135       os_major_version,
136       os_minor_version,
137       os_bugfix_version
138 #elif defined(OS_CHROMEOS)
139       "CrOS "
140       "%s %d.%d.%d",
141       cputype.c_str(),   // e.g. i686
142       os_major_version,
143       os_minor_version,
144       os_bugfix_version
145 #elif defined(OS_ANDROID)
146       "Android %s%s",
147       android_version_str.c_str(),
148       android_info_str.c_str()
149 #else
150       "%s %s",
151       unixinfo.sysname,  // e.g. Linux
152       cputype.c_str()    // e.g. i686
153 #endif
154   );  // NOLINT
155 
156   return os_cpu;
157 }
158 
BuildUserAgentFromProduct(const std::string & product)159 std::string BuildUserAgentFromProduct(const std::string& product) {
160   const char kUserAgentPlatform[] =
161 #if defined(OS_WIN)
162       "";
163 #elif defined(OS_MACOSX)
164       "Macintosh; ";
165 #elif defined(USE_X11) || defined(USE_OZONE)
166       "X11; ";           // strange, but that's what Firefox uses
167 #elif defined(OS_ANDROID)
168       "Linux; ";
169 #else
170       "Unknown; ";
171 #endif
172 
173   std::string os_info;
174   base::StringAppendF(
175       &os_info, "%s%s", kUserAgentPlatform, BuildOSCpuInfo().c_str());
176   return BuildUserAgentFromOSAndProduct(os_info, product);
177 }
178 
BuildUserAgentFromOSAndProduct(const std::string & os_info,const std::string & product)179 std::string BuildUserAgentFromOSAndProduct(const std::string& os_info,
180                                            const std::string& product) {
181   // Derived from Safari's UA string.
182   // This is done to expose our product name in a manner that is maximally
183   // compatible with Safari, we hope!!
184   std::string user_agent;
185   base::StringAppendF(
186       &user_agent,
187       "Mozilla/5.0 (%s) AppleWebKit/%d.%d (KHTML, like Gecko) %s Safari/%d.%d",
188       os_info.c_str(),
189       WEBKIT_VERSION_MAJOR,
190       WEBKIT_VERSION_MINOR,
191       product.c_str(),
192       WEBKIT_VERSION_MAJOR,
193       WEBKIT_VERSION_MINOR);
194   return user_agent;
195 }
196 
197 }  // namespace content
198