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 |