Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(205)

Unified Diff: tools/telemetry/telemetry/internal/platform/win_platform_backend.py

Issue 1647513002: Delete tools/telemetry. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tools/telemetry/telemetry/internal/platform/win_platform_backend.py
diff --git a/tools/telemetry/telemetry/internal/platform/win_platform_backend.py b/tools/telemetry/telemetry/internal/platform/win_platform_backend.py
deleted file mode 100644
index ec7e8ae45b7a89a5cd7bfd375aeb40a7d89ac37f..0000000000000000000000000000000000000000
--- a/tools/telemetry/telemetry/internal/platform/win_platform_backend.py
+++ /dev/null
@@ -1,409 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import atexit
-import collections
-import contextlib
-import ctypes
-import logging
-import os
-import platform
-import re
-import socket
-import struct
-import subprocess
-import sys
-import time
-import zipfile
-
-from catapult_base import cloud_storage # pylint: disable=import-error
-
-from telemetry.core import exceptions
-from telemetry.core import os_version as os_version_module
-from telemetry.core import util
-from telemetry import decorators
-from telemetry.internal.platform import desktop_platform_backend
-from telemetry.internal.platform.power_monitor import msr_power_monitor
-from telemetry.internal.util import path
-
-try:
- import pywintypes # pylint: disable=import-error
- import win32api # pylint: disable=import-error
- from win32com.shell import shell # pylint: disable=no-name-in-module
- from win32com.shell import shellcon # pylint: disable=no-name-in-module
- import win32con # pylint: disable=import-error
- import win32gui # pylint: disable=import-error
- import win32process # pylint: disable=import-error
- import win32security # pylint: disable=import-error
-except ImportError:
- pywintypes = None
- shell = None
- shellcon = None
- win32api = None
- win32con = None
- win32gui = None
- win32process = None
- win32security = None
-
-
-def _InstallWinRing0():
- """WinRing0 is used for reading MSRs."""
- executable_dir = os.path.dirname(sys.executable)
-
- python_is_64_bit = sys.maxsize > 2 ** 32
- dll_file_name = 'WinRing0x64.dll' if python_is_64_bit else 'WinRing0.dll'
- dll_path = os.path.join(executable_dir, dll_file_name)
-
- os_is_64_bit = platform.machine().endswith('64')
- driver_file_name = 'WinRing0x64.sys' if os_is_64_bit else 'WinRing0.sys'
- driver_path = os.path.join(executable_dir, driver_file_name)
-
- # Check for WinRing0 and download if needed.
- if not (os.path.exists(dll_path) and os.path.exists(driver_path)):
- win_binary_dir = os.path.join(
- path.GetTelemetryDir(), 'bin', 'win', 'AMD64')
- zip_path = os.path.join(win_binary_dir, 'winring0.zip')
- cloud_storage.GetIfChanged(zip_path, bucket=cloud_storage.PUBLIC_BUCKET)
- try:
- with zipfile.ZipFile(zip_path, 'r') as zip_file:
- error_message = (
- 'Failed to extract %s into %s. If python claims that '
- 'the zip file is locked, this may be a lie. The problem may be '
- 'that python does not have write permissions to the destination '
- 'directory.'
- )
- # Install DLL.
- if not os.path.exists(dll_path):
- try:
- zip_file.extract(dll_file_name, executable_dir)
- except:
- logging.error(error_message % (dll_file_name, executable_dir))
- raise
-
- # Install kernel driver.
- if not os.path.exists(driver_path):
- try:
- zip_file.extract(driver_file_name, executable_dir)
- except:
- logging.error(error_message % (driver_file_name, executable_dir))
- raise
- finally:
- os.remove(zip_path)
-
-
-def TerminateProcess(process_handle):
- if not process_handle:
- return
- if win32process.GetExitCodeProcess(process_handle) == win32con.STILL_ACTIVE:
- win32process.TerminateProcess(process_handle, 0)
- process_handle.close()
-
-
-class WinPlatformBackend(desktop_platform_backend.DesktopPlatformBackend):
- def __init__(self):
- super(WinPlatformBackend, self).__init__()
- self._msr_server_handle = None
- self._msr_server_port = None
- self._power_monitor = msr_power_monitor.MsrPowerMonitorWin(self)
-
- @classmethod
- def IsPlatformBackendForHost(cls):
- return sys.platform == 'win32'
-
- def __del__(self):
- self.close()
-
- def close(self):
- self.CloseMsrServer()
-
- def CloseMsrServer(self):
- if not self._msr_server_handle:
- return
-
- TerminateProcess(self._msr_server_handle)
- self._msr_server_handle = None
- self._msr_server_port = None
-
- def IsThermallyThrottled(self):
- raise NotImplementedError()
-
- def HasBeenThermallyThrottled(self):
- raise NotImplementedError()
-
- def GetSystemCommitCharge(self):
- performance_info = self._GetPerformanceInfo()
- return performance_info.CommitTotal * performance_info.PageSize / 1024
-
- @decorators.Cache
- def GetSystemTotalPhysicalMemory(self):
- performance_info = self._GetPerformanceInfo()
- return performance_info.PhysicalTotal * performance_info.PageSize / 1024
-
- def GetCpuStats(self, pid):
- cpu_info = self._GetWin32ProcessInfo(win32process.GetProcessTimes, pid)
- # Convert 100 nanosecond units to seconds
- cpu_time = (cpu_info['UserTime'] / 1e7 +
- cpu_info['KernelTime'] / 1e7)
- return {'CpuProcessTime': cpu_time}
-
- def GetCpuTimestamp(self):
- """Return current timestamp in seconds."""
- return {'TotalTime': time.time()}
-
- def GetMemoryStats(self, pid):
- memory_info = self._GetWin32ProcessInfo(
- win32process.GetProcessMemoryInfo, pid)
- return {'VM': memory_info['PagefileUsage'],
- 'VMPeak': memory_info['PeakPagefileUsage'],
- 'WorkingSetSize': memory_info['WorkingSetSize'],
- 'WorkingSetSizePeak': memory_info['PeakWorkingSetSize']}
-
- def KillProcess(self, pid, kill_process_tree=False):
- # os.kill for Windows is Python 2.7.
- cmd = ['taskkill', '/F', '/PID', str(pid)]
- if kill_process_tree:
- cmd.append('/T')
- subprocess.Popen(cmd, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT).communicate()
-
- def GetSystemProcessInfo(self):
- # [3:] To skip 2 blank lines and header.
- lines = subprocess.Popen(
- ['wmic', 'process', 'get',
- 'CommandLine,CreationDate,Name,ParentProcessId,ProcessId',
- '/format:csv'],
- stdout=subprocess.PIPE).communicate()[0].splitlines()[3:]
- process_info = []
- for line in lines:
- if not line:
- continue
- parts = line.split(',')
- pi = {}
- pi['ProcessId'] = int(parts[-1])
- pi['ParentProcessId'] = int(parts[-2])
- pi['Name'] = parts[-3]
- creation_date = None
- if parts[-4]:
- creation_date = float(re.split('[+-]', parts[-4])[0])
- pi['CreationDate'] = creation_date
- pi['CommandLine'] = ','.join(parts[1:-4])
- process_info.append(pi)
- return process_info
-
- def GetChildPids(self, pid):
- """Retunds a list of child pids of |pid|."""
- ppid_map = collections.defaultdict(list)
- creation_map = {}
- for pi in self.GetSystemProcessInfo():
- ppid_map[pi['ParentProcessId']].append(pi['ProcessId'])
- if pi['CreationDate']:
- creation_map[pi['ProcessId']] = pi['CreationDate']
-
- def _InnerGetChildPids(pid):
- if not pid or pid not in ppid_map:
- return []
- ret = [p for p in ppid_map[pid] if creation_map[p] >= creation_map[pid]]
- for child in ret:
- if child == pid:
- continue
- ret.extend(_InnerGetChildPids(child))
- return ret
-
- return _InnerGetChildPids(pid)
-
- def GetCommandLine(self, pid):
- for pi in self.GetSystemProcessInfo():
- if pid == pi['ProcessId']:
- return pi['CommandLine']
- raise exceptions.ProcessGoneException()
-
- @decorators.Cache
- def GetArchName(self):
- return platform.machine()
-
- def GetOSName(self):
- return 'win'
-
- @decorators.Cache
- def GetOSVersionName(self):
- os_version = platform.uname()[3]
-
- if os_version.startswith('5.1.'):
- return os_version_module.XP
- if os_version.startswith('6.0.'):
- return os_version_module.VISTA
- if os_version.startswith('6.1.'):
- return os_version_module.WIN7
- if os_version.startswith('6.2.'):
- return os_version_module.WIN8
- if os_version.startswith('10.'):
- return os_version_module.WIN10
-
- raise NotImplementedError('Unknown win version %s.' % os_version)
-
- def CanFlushIndividualFilesFromSystemCache(self):
- return True
-
- def _GetWin32ProcessInfo(self, func, pid):
- mask = (win32con.PROCESS_QUERY_INFORMATION |
- win32con.PROCESS_VM_READ)
- handle = None
- try:
- handle = win32api.OpenProcess(mask, False, pid)
- return func(handle)
- except pywintypes.error, e:
- errcode = e[0]
- if errcode == 87:
- raise exceptions.ProcessGoneException()
- raise
- finally:
- if handle:
- win32api.CloseHandle(handle)
-
- def _GetPerformanceInfo(self):
- class PerformanceInfo(ctypes.Structure):
- """Struct for GetPerformanceInfo() call
- http://msdn.microsoft.com/en-us/library/ms683210
- """
- _fields_ = [('size', ctypes.c_ulong),
- ('CommitTotal', ctypes.c_size_t),
- ('CommitLimit', ctypes.c_size_t),
- ('CommitPeak', ctypes.c_size_t),
- ('PhysicalTotal', ctypes.c_size_t),
- ('PhysicalAvailable', ctypes.c_size_t),
- ('SystemCache', ctypes.c_size_t),
- ('KernelTotal', ctypes.c_size_t),
- ('KernelPaged', ctypes.c_size_t),
- ('KernelNonpaged', ctypes.c_size_t),
- ('PageSize', ctypes.c_size_t),
- ('HandleCount', ctypes.c_ulong),
- ('ProcessCount', ctypes.c_ulong),
- ('ThreadCount', ctypes.c_ulong)]
-
- def __init__(self):
- self.size = ctypes.sizeof(self)
- # pylint: disable=bad-super-call
- super(PerformanceInfo, self).__init__()
-
- performance_info = PerformanceInfo()
- ctypes.windll.psapi.GetPerformanceInfo(
- ctypes.byref(performance_info), performance_info.size)
- return performance_info
-
- def IsCurrentProcessElevated(self):
- if self.GetOSVersionName() < os_version_module.VISTA:
- # TOKEN_QUERY is not defined before Vista. All processes are elevated.
- return True
-
- handle = win32process.GetCurrentProcess()
- with contextlib.closing(
- win32security.OpenProcessToken(handle, win32con.TOKEN_QUERY)) as token:
- return bool(win32security.GetTokenInformation(
- token, win32security.TokenElevation))
-
- def LaunchApplication(
- self, application, parameters=None, elevate_privilege=False):
- """Launch an application. Returns a PyHANDLE object."""
-
- parameters = ' '.join(parameters) if parameters else ''
- if elevate_privilege and not self.IsCurrentProcessElevated():
- # Use ShellExecuteEx() instead of subprocess.Popen()/CreateProcess() to
- # elevate privileges. A new console will be created if the new process has
- # different permissions than this process.
- proc_info = shell.ShellExecuteEx(
- fMask=shellcon.SEE_MASK_NOCLOSEPROCESS | shellcon.SEE_MASK_NO_CONSOLE,
- lpVerb='runas' if elevate_privilege else '',
- lpFile=application,
- lpParameters=parameters,
- nShow=win32con.SW_HIDE)
- if proc_info['hInstApp'] <= 32:
- raise Exception('Unable to launch %s' % application)
- return proc_info['hProcess']
- else:
- handle, _, _, _ = win32process.CreateProcess(
- None, application + ' ' + parameters, None, None, False,
- win32process.CREATE_NO_WINDOW, None, None, win32process.STARTUPINFO())
- return handle
-
- def CanMonitorPower(self):
- return self._power_monitor.CanMonitorPower()
-
- def CanMeasurePerApplicationPower(self):
- return self._power_monitor.CanMeasurePerApplicationPower()
-
- def StartMonitoringPower(self, browser):
- self._power_monitor.StartMonitoringPower(browser)
-
- def StopMonitoringPower(self):
- return self._power_monitor.StopMonitoringPower()
-
- def _StartMsrServerIfNeeded(self):
- if self._msr_server_handle:
- return
-
- _InstallWinRing0()
- self._msr_server_port = util.GetUnreservedAvailableLocalPort()
- # It might be flaky to get a port number without reserving it atomically,
- # but if the server process chooses a port, we have no way of getting it.
- # The stdout of the elevated process isn't accessible.
- parameters = (
- os.path.join(os.path.dirname(__file__), 'msr_server_win.py'),
- str(self._msr_server_port),
- )
- self._msr_server_handle = self.LaunchApplication(
- sys.executable, parameters, elevate_privilege=True)
- # Wait for server to start.
- try:
- socket.create_connection(('127.0.0.1', self._msr_server_port), 5).close()
- except socket.error:
- self.CloseMsrServer()
- atexit.register(TerminateProcess, self._msr_server_handle)
-
- def ReadMsr(self, msr_number, start=0, length=64):
- self._StartMsrServerIfNeeded()
- if not self._msr_server_handle:
- raise OSError('Unable to start MSR server.')
-
- sock = socket.create_connection(('127.0.0.1', self._msr_server_port), 0.2)
- try:
- sock.sendall(struct.pack('I', msr_number))
- response = sock.recv(8)
- finally:
- sock.close()
- return struct.unpack('Q', response)[0] >> start & ((1 << length) - 1)
-
- def IsCooperativeShutdownSupported(self):
- return True
-
- def CooperativelyShutdown(self, proc, app_name):
- pid = proc.pid
-
- # http://timgolden.me.uk/python/win32_how_do_i/
- # find-the-window-for-my-subprocess.html
- #
- # It seems that intermittently this code manages to find windows
- # that don't belong to Chrome -- for example, the cmd.exe window
- # running slave.bat on the tryservers. Try to be careful about
- # finding only Chrome's windows. This works for both the browser
- # and content_shell.
- #
- # It seems safest to send the WM_CLOSE messages after discovering
- # all of the sub-process's windows.
- def find_chrome_windows(hwnd, hwnds):
- _, win_pid = win32process.GetWindowThreadProcessId(hwnd)
- if (pid == win_pid and
- win32gui.IsWindowVisible(hwnd) and
- win32gui.IsWindowEnabled(hwnd) and
- win32gui.GetClassName(hwnd).lower().startswith(app_name)):
- hwnds.append(hwnd)
- return True
- hwnds = []
- win32gui.EnumWindows(find_chrome_windows, hwnds)
- if hwnds:
- for hwnd in hwnds:
- win32gui.SendMessage(hwnd, win32con.WM_CLOSE, 0, 0)
- return True
- else:
- logging.info('Did not find any windows owned by target process')
- return False

Powered by Google App Engine
This is Rietveld 408576698