OLD | NEW |
| (Empty) |
1 # Copyright (c) 2011 Google Inc. All rights reserved. | |
2 # | |
3 # Redistribution and use in source and binary forms, with or without | |
4 # modification, are permitted provided that the following conditions are | |
5 # met: | |
6 # | |
7 # * Redistributions of source code must retain the above copyright | |
8 # notice, this list of conditions and the following disclaimer. | |
9 # * Redistributions in binary form must reproduce the above | |
10 # copyright notice, this list of conditions and the following disclaimer | |
11 # in the documentation and/or other materials provided with the | |
12 # distribution. | |
13 # * Neither the name of Google Inc. nor the names of its | |
14 # contributors may be used to endorse or promote products derived from | |
15 # this software without specific prior written permission. | |
16 # | |
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
28 | |
29 import re | |
30 import sys | |
31 | |
32 | |
33 class PlatformInfo(object): | |
34 """This class provides a consistent (and mockable) interpretation of | |
35 system-specific values (like sys.platform and platform.mac_ver()) | |
36 to be used by the rest of the webkitpy code base. | |
37 | |
38 Public (static) properties: | |
39 -- os_name | |
40 -- os_version | |
41 | |
42 Note that 'future' is returned for os_version if the operating system is | |
43 newer than one known to the code. | |
44 """ | |
45 | |
46 def __init__(self, sys_module, platform_module, filesystem_module, executive
): | |
47 self._executive = executive | |
48 self._filesystem = filesystem_module | |
49 self._platform_module = platform_module | |
50 self.os_name = self._determine_os_name(sys_module.platform) | |
51 if self.os_name == 'linux': | |
52 self.os_version = self._determine_linux_version(platform_module) | |
53 if self.os_name == 'freebsd': | |
54 self.os_version = platform_module.release() | |
55 if self.os_name.startswith('mac'): | |
56 self.os_version = self._determine_mac_version(platform_module.mac_ve
r()[0]) | |
57 if self.os_name.startswith('win'): | |
58 self.os_version = self._determine_win_version(self._win_version_tupl
e(sys_module)) | |
59 self._is_cygwin = sys_module.platform == 'cygwin' | |
60 | |
61 def is_mac(self): | |
62 return self.os_name == 'mac' | |
63 | |
64 def is_win(self): | |
65 return self.os_name == 'win' | |
66 | |
67 def is_cygwin(self): | |
68 return self._is_cygwin | |
69 | |
70 def is_linux(self): | |
71 return self.os_name == 'linux' | |
72 | |
73 def is_freebsd(self): | |
74 return self.os_name == 'freebsd' | |
75 | |
76 def is_highdpi(self): | |
77 if self.is_mac(): | |
78 output = self._executive.run_command(['system_profiler', 'SPDisplays
DataType'], | |
79 error_handler=self._executive.i
gnore_error) | |
80 if output and 'Retina: Yes' in output: | |
81 return True | |
82 return False | |
83 | |
84 def display_name(self): | |
85 # platform.platform() returns Darwin information for Mac, which is just
confusing. | |
86 if self.is_mac(): | |
87 return "Mac OS X %s" % self._platform_module.mac_ver()[0] | |
88 | |
89 # Returns strings like: | |
90 # Linux-2.6.18-194.3.1.el5-i686-with-redhat-5.5-Final | |
91 # Windows-2008ServerR2-6.1.7600 | |
92 return self._platform_module.platform() | |
93 | |
94 def total_bytes_memory(self): | |
95 if self.is_mac(): | |
96 return long(self._executive.run_command(["sysctl", "-n", "hw.memsize
"])) | |
97 return None | |
98 | |
99 def terminal_width(self): | |
100 """Returns sys.maxint if the width cannot be determined.""" | |
101 try: | |
102 if self.is_win(): | |
103 # From http://code.activestate.com/recipes/440694-determine-size
-of-console-window-on-windows/ | |
104 from ctypes import windll, create_string_buffer | |
105 handle = windll.kernel32.GetStdHandle(-12) # -12 == stderr | |
106 console_screen_buffer_info = create_string_buffer(22) # 22 == s
izeof(console_screen_buffer_info) | |
107 if windll.kernel32.GetConsoleScreenBufferInfo(handle, console_sc
reen_buffer_info): | |
108 import struct | |
109 _, _, _, _, _, left, _, right, _, _, _ = struct.unpack("hhhh
Hhhhhhh", console_screen_buffer_info.raw) | |
110 # Note that we return 1 less than the width since writing in
to the rightmost column | |
111 # automatically performs a line feed. | |
112 return right - left | |
113 return sys.maxsize | |
114 else: | |
115 import fcntl | |
116 import struct | |
117 import termios | |
118 packed = fcntl.ioctl(sys.stderr.fileno(), termios.TIOCGWINSZ, '\
0' * 8) | |
119 _, columns, _, _ = struct.unpack('HHHH', packed) | |
120 return columns | |
121 except: | |
122 return sys.maxsize | |
123 | |
124 def linux_distribution(self): | |
125 if not self.is_linux(): | |
126 return None | |
127 | |
128 if self._filesystem.exists('/etc/redhat-release'): | |
129 return 'redhat' | |
130 if self._filesystem.exists('/etc/debian_version'): | |
131 return 'debian' | |
132 if self._filesystem.exists('/etc/arch-release'): | |
133 return 'arch' | |
134 | |
135 return 'unknown' | |
136 | |
137 def _determine_os_name(self, sys_platform): | |
138 if sys_platform == 'darwin': | |
139 return 'mac' | |
140 if sys_platform.startswith('linux'): | |
141 return 'linux' | |
142 if sys_platform in ('win32', 'cygwin'): | |
143 return 'win' | |
144 if sys_platform.startswith('freebsd'): | |
145 return 'freebsd' | |
146 raise AssertionError('unrecognized platform string "%s"' % sys_platform) | |
147 | |
148 def _determine_mac_version(self, mac_version_string): | |
149 minor_release = int(mac_version_string.split('.')[1]) | |
150 # FIXME: This should really be >= 9, and we should get rid of 'future'. | |
151 assert minor_release >= 6, 'Unsupported mac os version: %s' % mac_versio
n_string | |
152 if minor_release in (9, 10, 11): | |
153 return 'mac10.%d' % minor_release | |
154 return 'future' | |
155 | |
156 def _determine_linux_version(self, _): | |
157 return 'trusty' | |
158 | |
159 def _determine_win_version(self, win_version_tuple): | |
160 if win_version_tuple[:2] == (10, 0): | |
161 return '10' | |
162 if win_version_tuple[:2] == (6, 3): | |
163 return '8.1' | |
164 if win_version_tuple[:2] == (6, 2): | |
165 return '8' | |
166 if win_version_tuple[:3] == (6, 1, 7601): | |
167 return '7sp1' | |
168 if win_version_tuple[:3] == (6, 1, 7600): | |
169 return '7sp0' | |
170 if win_version_tuple[:2] == (6, 0): | |
171 return 'vista' | |
172 if win_version_tuple[:2] == (5, 1): | |
173 return 'xp' | |
174 assert (win_version_tuple[0] > 10 or | |
175 win_version_tuple[0] == 10 and win_version_tuple[1] > 0), ( | |
176 'Unrecognized Windows version tuple: "%s"' % (win_version_tuple,)) | |
177 return 'future' | |
178 | |
179 def _win_version_tuple(self, sys_module): | |
180 if hasattr(sys_module, 'getwindowsversion'): | |
181 return sys_module.getwindowsversion() | |
182 return self._win_version_tuple_from_cmd() | |
183 | |
184 def _win_version_tuple_from_cmd(self): | |
185 # Note that this should only ever be called on windows, so this should a
lways work. | |
186 ver_output = self._executive.run_command(['cmd', '/c', 'ver'], decode_ou
tput=False) | |
187 match_object = re.search(r'(?P<major>\d+)\.(?P<minor>\d)\.(?P<build>\d+)
', ver_output) | |
188 assert match_object, 'cmd returned an unexpected version string: ' + ver
_output | |
189 return tuple(map(int, match_object.groups())) | |
OLD | NEW |