| 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 |