Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 """Provides an interface to communicate with the device via the adb command. | 5 """Provides an interface to communicate with the device via the adb command. |
| 6 | 6 |
| 7 Assumes adb binary is currently on system path. | 7 Assumes adb binary is currently on system path. |
| 8 """ | 8 """ |
| 9 # pylint: disable-all | 9 # pylint: disable-all |
| 10 | 10 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 48 # Set the adb shell prompt to be a unique marker that will [hopefully] not | 48 # Set the adb shell prompt to be a unique marker that will [hopefully] not |
| 49 # appear at the start of any line of a command's output. | 49 # appear at the start of any line of a command's output. |
| 50 SHELL_PROMPT = '~+~PQ\x17RS~+~' | 50 SHELL_PROMPT = '~+~PQ\x17RS~+~' |
| 51 | 51 |
| 52 # Java properties file | 52 # Java properties file |
| 53 LOCAL_PROPERTIES_PATH = constants.DEVICE_LOCAL_PROPERTIES_PATH | 53 LOCAL_PROPERTIES_PATH = constants.DEVICE_LOCAL_PROPERTIES_PATH |
| 54 | 54 |
| 55 # Property in /data/local.prop that controls Java assertions. | 55 # Property in /data/local.prop that controls Java assertions. |
| 56 JAVA_ASSERT_PROPERTY = 'dalvik.vm.enableassertions' | 56 JAVA_ASSERT_PROPERTY = 'dalvik.vm.enableassertions' |
| 57 | 57 |
| 58 MEMORY_INFO_RE = re.compile('^(?P<key>\w+):\s+(?P<usage_kb>\d+) kB$') | |
| 59 NVIDIA_MEMORY_INFO_RE = re.compile('^\s*(?P<user>\S+)\s*(?P<name>\S+)\s*' | |
| 60 '(?P<pid>\d+)\s*(?P<usage_bytes>\d+)$') | |
| 61 | |
| 62 # Keycode "enum" suitable for passing to AndroidCommands.SendKey(). | 58 # Keycode "enum" suitable for passing to AndroidCommands.SendKey(). |
| 63 KEYCODE_HOME = 3 | 59 KEYCODE_HOME = 3 |
| 64 KEYCODE_BACK = 4 | 60 KEYCODE_BACK = 4 |
| 65 KEYCODE_DPAD_UP = 19 | 61 KEYCODE_DPAD_UP = 19 |
| 66 KEYCODE_DPAD_DOWN = 20 | 62 KEYCODE_DPAD_DOWN = 20 |
| 67 KEYCODE_DPAD_RIGHT = 22 | 63 KEYCODE_DPAD_RIGHT = 22 |
| 68 KEYCODE_ENTER = 66 | 64 KEYCODE_ENTER = 66 |
| 69 KEYCODE_MENU = 82 | 65 KEYCODE_MENU = 82 |
| 70 | 66 |
| 71 MD5SUM_DEVICE_FOLDER = constants.TEST_EXECUTABLE_DIR + '/md5sum/' | 67 MD5SUM_DEVICE_FOLDER = constants.TEST_EXECUTABLE_DIR + '/md5sum/' |
| (...skipping 1519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1591 """Returns the memory usage for given pid. | 1587 """Returns the memory usage for given pid. |
| 1592 | 1588 |
| 1593 Args: | 1589 Args: |
| 1594 pid: The pid number of the specific process running on device. | 1590 pid: The pid number of the specific process running on device. |
| 1595 | 1591 |
| 1596 Returns: | 1592 Returns: |
| 1597 A tuple containg: | 1593 A tuple containg: |
| 1598 [0]: Dict of {metric:usage_kb}, for the process which has specified pid. | 1594 [0]: Dict of {metric:usage_kb}, for the process which has specified pid. |
| 1599 The metric keys which may be included are: Size, Rss, Pss, Shared_Clean, | 1595 The metric keys which may be included are: Size, Rss, Pss, Shared_Clean, |
| 1600 Shared_Dirty, Private_Clean, Private_Dirty, Referenced, Swap, | 1596 Shared_Dirty, Private_Clean, Private_Dirty, Referenced, Swap, |
| 1601 KernelPageSize, MMUPageSize, Nvidia (tablet only), VmHWM. | 1597 KernelPageSize, MMUPageSize, VmHWM. |
| 1602 [1]: Detailed /proc/[PID]/smaps information. | 1598 [1]: Detailed /proc/[PID]/smaps information. |
| 1603 """ | 1599 """ |
| 1604 usage_dict = collections.defaultdict(int) | 1600 usage_dict = collections.defaultdict(int) |
| 1605 smaps = collections.defaultdict(dict) | 1601 smaps = collections.defaultdict(dict) |
| 1606 current_smap = '' | 1602 current_smap = '' |
| 1607 for line in self.GetProtectedFileContents('/proc/%s/smaps' % pid): | 1603 for line in self.GetProtectedFileContents('/proc/%s/smaps' % pid): |
| 1608 items = line.split() | 1604 items = line.split() |
| 1609 # See man 5 proc for more details. The format is: | 1605 # See man 5 proc for more details. The format is: |
| 1610 # address perms offset dev inode pathname | 1606 # address perms offset dev inode pathname |
| 1611 if len(items) > 5: | 1607 if len(items) > 5: |
| 1612 current_smap = ' '.join(items[5:]) | 1608 current_smap = ' '.join(items[5:]) |
| 1613 elif len(items) > 3: | 1609 elif len(items) > 3: |
| 1614 current_smap = ' '.join(items[3:]) | 1610 current_smap = ' '.join(items[3:]) |
| 1615 match = re.match(MEMORY_INFO_RE, line) | 1611 if line.endswith('kB'): |
| 1616 if match: | 1612 key, value = line.split(':') |
| 1617 key = match.group('key') | 1613 key = key.strip() |
| 1618 usage_kb = int(match.group('usage_kb')) | 1614 usage_kb = int(value.strip().split()[0]) |
| 1619 usage_dict[key] += usage_kb | 1615 usage_dict[key] += usage_kb |
| 1620 if key not in smaps[current_smap]: | 1616 if key not in smaps[current_smap]: |
| 1621 smaps[current_smap][key] = 0 | 1617 smaps[current_smap][key] = 0 |
| 1622 smaps[current_smap][key] += usage_kb | 1618 smaps[current_smap][key] += usage_kb |
| 1623 if not usage_dict or not any(usage_dict.values()): | 1619 if not usage_dict or not any(usage_dict.values()): |
| 1624 # Presumably the process died between ps and calling this method. | 1620 # Presumably the process died between ps and calling this method. |
| 1625 logging.warning('Could not find memory usage for pid ' + str(pid)) | 1621 logging.warning('Could not find memory usage for pid ' + str(pid)) |
| 1626 | 1622 |
| 1627 for line in self.GetProtectedFileContents('/d/nvmap/generic-0/clients'): | |
|
tonyg
2014/05/13 14:37:50
Are you sure we don't care about this any more for
bulach
2014/05/13 14:45:57
well... :)
way up in telemetry, this is not being
| |
| 1628 match = re.match(NVIDIA_MEMORY_INFO_RE, line) | |
| 1629 if match and match.group('pid') == pid: | |
| 1630 usage_bytes = int(match.group('usage_bytes')) | |
| 1631 usage_dict['Nvidia'] = int(round(usage_bytes / 1000.0)) # kB | |
| 1632 break | |
| 1633 | |
| 1634 peak_value_kb = 0 | 1623 peak_value_kb = 0 |
| 1635 for line in self.GetProtectedFileContents('/proc/%s/status' % pid): | 1624 for line in self.GetProtectedFileContents('/proc/%s/status' % pid): |
| 1636 if not line.startswith('VmHWM:'): # Format: 'VmHWM: +[0-9]+ kB' | 1625 if not line.startswith('VmHWM:'): # Format: 'VmHWM: +[0-9]+ kB' |
| 1637 continue | 1626 continue |
| 1638 peak_value_kb = int(line.split(':')[1].strip().split(' ')[0]) | 1627 peak_value_kb = int(line.split(':')[1].strip().split(' ')[0]) |
|
picksi
2014/05/14 16:32:18
It looks like the code to read the peak_value_kb i
bulach
2014/05/14 16:52:56
hehe :) there was another follow up on this:
https
| |
| 1628 break | |
| 1639 usage_dict['VmHWM'] = peak_value_kb | 1629 usage_dict['VmHWM'] = peak_value_kb |
| 1640 if not peak_value_kb: | 1630 if not peak_value_kb: |
| 1641 logging.warning('Could not find memory peak value for pid ' + str(pid)) | 1631 logging.warning('Could not find memory peak value for pid ' + str(pid)) |
|
picksi
2014/05/14 16:32:18
This relies on a zero peak value meaning it couldn
bulach
2014/05/14 16:52:56
yeah, this is a good use for python's "for..else"
| |
| 1642 | 1632 |
| 1643 return (usage_dict, smaps) | 1633 return (usage_dict, smaps) |
| 1644 | 1634 |
| 1645 def GetMemoryUsageForPackage(self, package): | 1635 def GetMemoryUsageForPackage(self, package): |
| 1646 """Returns the memory usage for all processes whose name contains |pacakge|. | 1636 """Returns the memory usage for all processes whose name contains |pacakge|. |
| 1647 | 1637 |
| 1648 Args: | 1638 Args: |
| 1649 package: A string holding process name to lookup pid list for. | 1639 package: A string holding process name to lookup pid list for. |
| 1650 | 1640 |
| 1651 Returns: | 1641 Returns: |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1969 """ | 1959 """ |
| 1970 def __init__(self, output): | 1960 def __init__(self, output): |
| 1971 self._output = output | 1961 self._output = output |
| 1972 | 1962 |
| 1973 def write(self, data): | 1963 def write(self, data): |
| 1974 data = data.replace('\r\r\n', '\n') | 1964 data = data.replace('\r\r\n', '\n') |
| 1975 self._output.write(data) | 1965 self._output.write(data) |
| 1976 | 1966 |
| 1977 def flush(self): | 1967 def flush(self): |
| 1978 self._output.flush() | 1968 self._output.flush() |
| OLD | NEW |