1// Copyright (c) 2011 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 "webkit/glue/user_agent.h"
6
7#if defined(OS_POSIX) && !defined(OS_MACOSX)
8#include <sys/utsname.h>
9#endif
10
11#include "base/string_util.h"
12#include "base/stringprintf.h"
13#include "base/sys_info.h"
14
15#if defined(OS_WIN)
16#include "base/win/windows_version.h"
17#endif
18
19// Generated
20#include "webkit_version.h"  // NOLINT
21
22namespace webkit_glue {
23
24// Forward declare GetProductVersionInfo.  This is implemented in
25// renderer_glue.cc as part of the renderer lib.
26std::string GetProductVersion();
27
28std::string GetWebKitVersion() {
29  return base::StringPrintf("%d.%d (%s)",
30                            WEBKIT_VERSION_MAJOR,
31                            WEBKIT_VERSION_MINOR,
32                            WEBKIT_SVN_REVISION);
33}
34
35std::string GetWebKitRevision() {
36  return WEBKIT_SVN_REVISION;
37}
38
39std::string BuildOSCpuInfo() {
40  std::string os_cpu;
41
42#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_CHROMEOS)
43  int32 os_major_version = 0;
44  int32 os_minor_version = 0;
45  int32 os_bugfix_version = 0;
46  base::SysInfo::OperatingSystemVersionNumbers(&os_major_version,
47                                               &os_minor_version,
48                                               &os_bugfix_version);
49#endif
50#if defined(OS_POSIX) && !defined(OS_MACOSX)
51  // Should work on any Posix system.
52  struct utsname unixinfo;
53  uname(&unixinfo);
54
55  std::string cputype;
56  // special case for biarch systems
57  if (strcmp(unixinfo.machine, "x86_64") == 0 &&
58      sizeof(void*) == sizeof(int32)) {  // NOLINT
59    cputype.assign("i686 (x86_64)");
60  } else {
61    cputype.assign(unixinfo.machine);
62  }
63#endif
64
65#if defined(OS_WIN)
66  std::string architecture_token;
67  base::win::OSInfo* os_info = base::win::OSInfo::GetInstance();
68  if (os_info->wow64_status() == base::win::OSInfo::WOW64_ENABLED) {
69    architecture_token = "; WOW64";
70  } else {
71    base::win::OSInfo::WindowsArchitecture windows_architecture =
72        os_info->architecture();
73    if (windows_architecture == base::win::OSInfo::X64_ARCHITECTURE)
74      architecture_token = "; Win64; x64";
75    else if (windows_architecture == base::win::OSInfo::IA64_ARCHITECTURE)
76      architecture_token = "; Win64; IA64";
77  }
78#endif
79
80  base::StringAppendF(
81      &os_cpu,
82#if defined(OS_WIN)
83      "Windows NT %d.%d%s",
84      os_major_version,
85      os_minor_version,
86      architecture_token.c_str()
87#elif defined(OS_MACOSX)
88      "Intel Mac OS X %d_%d_%d",
89      os_major_version,
90      os_minor_version,
91      os_bugfix_version
92#elif defined(OS_CHROMEOS)
93      "CrOS "
94#if defined(TOUCH_UI)
95      "Touch "
96#endif
97      "%s %d.%d.%d",
98      cputype.c_str(),   // e.g. i686
99      os_major_version,
100      os_minor_version,
101      os_bugfix_version
102#else
103      "%s %s",
104      unixinfo.sysname,  // e.g. Linux
105      cputype.c_str()    // e.g. i686
106#endif
107  );  // NOLINT
108
109  return os_cpu;
110}
111
112void BuildUserAgent(bool mimic_windows, std::string* result) {
113  const char kUserAgentPlatform[] =
114#if defined(OS_WIN)
115      "";
116#elif defined(OS_MACOSX)
117      "Macintosh; ";
118#elif defined(USE_X11)
119      "X11; ";           // strange, but that's what Firefox uses
120#else
121      "Unknown; ";
122#endif
123
124  // Get the product name and version, and replace Safari's Version/X string
125  // with it.  This is done to expose our product name in a manner that is
126  // maximally compatible with Safari, we hope!!
127  std::string product = GetProductVersion();
128
129  // Derived from Safari's UA string.
130  base::StringAppendF(
131      result,
132      "Mozilla/5.0 (%s%s) AppleWebKit/%d.%d"
133      " (KHTML, like Gecko) %s Safari/%d.%d",
134      mimic_windows ? "Windows " : kUserAgentPlatform,
135      BuildOSCpuInfo().c_str(),
136      WEBKIT_VERSION_MAJOR,
137      WEBKIT_VERSION_MINOR,
138      product.c_str(),
139      WEBKIT_VERSION_MAJOR,
140      WEBKIT_VERSION_MINOR);
141}
142
143}  // namespace webkit_glue
144
145