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

Side by Side Diff: systrace/systrace/agents/battor_trace_agent.py

Issue 1822893002: Example of how to figure out which BattOr maps to which port [DO NOT SUBMIT] (Closed) Base URL: git@github.com:catapult-project/catapult@master
Patch Set: Created 4 years, 9 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright (c) 2016 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 import subprocess
6 import threading
7
8 from systrace.tracing_agents import TracingAgent, TraceResults, usb_hubs
9
10 from devil.utils import find_usb_devices
11 from devil.android import battery_utils, device_utils
12 from py_trace_event import trace_time
13
14
15 def try_create_agent(options, categories, disable=False):
16 if disable:
17 return False
18 if options.from_file is not None:
19 return False
20 return BattorTraceAgent(options, categories)
21
22 class BattorError(Exception):
23 pass
24
25 class BattorTraceAgent(TracingAgent):
26 # Class representing tracing agent that gets data from a BattOr.
27 def __init__(self, options, categories):
28 """Initialize a BattOr tracing agent.
29
30 Args:
31 options: The command-line options.
32 categories: The trace categories to capture.
33 """
34 super(BattorTraceAgent, self).__init__()
35 self._trace_result = ''
36 self._devstring = ''
37 self._options = options
38 self._categories = categories
39 self._collection_process = None
40 self._battor_process = None
41 self._recording_error = None
42 self._device_utils = device_utils.DeviceUtils(self._options.device_serial)
43 self._battery_utils = battery_utils.BatteryUtils(self._device_utils)
44 self._devstring = self._GetDeviceString()
45
46 def _GetDeviceString(self):
47 """Gets the device string to communicate with device.
48
49 Returns:
50 Device string used to communicate with device.
51
52 Raises:
53 ValueError: If serial number is not given.
54 BattorError: If BattOr not found or unexpected USB topology.
55 """
56 # If there's only one BattOr connected to the system, just use that one.
57 # This allows for use on, e.g., a developer's workstation with no hubs.
58 serial = self._options.device_serial
59 devtree = find_usb_devices.GetBusNumberToDeviceTreeMap(fast=True)
60 all_battors = find_usb_devices.GetBattorList(devtree)
61 hub_types = [usb_hubs.GetHubType(x) for x in self._options.hub_types]
62 if len(all_battors) == 1:
63 return '/dev/' + all_battors[0]
64 if serial:
65 p2serial = find_usb_devices.GetAllPhysicalPortToSerialMaps(
66 hub_types, device_tree_map=devtree)
67 p2tty = find_usb_devices.GetAllPhysicalPortToTTYMaps(
68 hub_types, device_tree_map=devtree)
69
70 # get the port number of this device
71 port_num = -1
72 for hub in p2serial:
73 for (port, s) in hub.iteritems():
74 if serial == s:
75 if port_num != -1:
76 raise BattorError('Two devices with same serial number.')
77 else:
78 port_num = port
79 if port_num == -1:
80 raise BattorError('Device with given serial number not found.')
81
82 # get the tty for this port number
83 tty_string = None
84 for hub in p2tty:
85 if port_num in hub:
86 if tty_string:
87 raise BattorError('Two TTY devices with matching port number.')
88 else:
89 tty_string = hub[port_num]
90 if not tty_string:
91 raise BattorError('No BattOr detected on corresponding port.')
92 if find_usb_devices.IsBattor(tty_string, devtree):
93 return '/dev/' + tty_string
94 else:
95 raise BattorError('Device connected to matching port is not BattOr.')
96 else:
97 raise BattorError('Two or more BattOrs connected, no serial provided')
98
99 def StartAgentTracing(self):
100 """Start tracing.
101
102 Raises:
103 RuntimeError: If trace already in progress.
104 """
105 if self._battor_process is not None:
106 raise RuntimeError('Trace already in progress')
107 self._battery_utils.SetCharging(False)
108 try:
109 self._battor_process = subprocess.Popen(
110 ['battor_agent',
111 '--battor-path='+self._devstring],
112 stdin=subprocess.PIPE,
113 stdout=subprocess.PIPE,
114 shell=False)
115 except OSError:
116 raise RuntimeError('Error executing battor_agent command.'
117 'Make sure that battor_agent is on PATH.')
118 self._battor_process.stdin.write('StartTracing\n')
119 status = self._battor_process.stdout.readline()
120 if 'Done.' not in status:
121 raise RuntimeError('battor_agent failed to start (%s)' % status)
122 return True
123
124 def _record_trace_result(self):
125 result = self._battor_process.communicate('StopTracing\n')[0]
126 self._battor_process = None
127 self._battery_utils.SetCharging(True)
128 if not result:
129 self._recording_error = 'battor_agent failed to stop - no output'
130 elif result[-6:-1] != 'Done.':
131 self._recording_error = 'battor_agent failed to stop'
132 else:
133 self._recording_error = None
134 self._trace_result = result
135
136 def StopAgentTracing(self):
137 """Collect the result of tracing.
138 """
139 if self._battor_process is not None:
140 self._collection_process = threading.Thread(
141 target = self._record_trace_result)
142 self._collection_process.start()
143 return True
144 else:
145 return False
146
147 def SupportsExplicitClockSync(self):
148 """Returns whether this function supports explicit clock sync."""
149 self._battor_process.stdin.write('SupportsExplicitClockSync\n')
150 result = self._battor_process.stdout.readline()
151 return int(result) != 0
152
153 def RecordClockSyncMarker(self, sync_id, did_record_sync_marker_callback):
154 """Records a clock sync marker.
155
156 Args:
157 sync_id: ID string for clock sync marker.
158 """
159 t1 = trace_time.Now()
160 self._battor_process.stdin.write('RecordClockSyncMarker %s\n' % sync_id)
161 status = self._battor_process.stdout.readline()
162 did_record_sync_marker_callback(t1, sync_id)
163 if 'Done.' not in status:
164 raise RuntimeError('battor_agent failed to record sync marker (%s)'
165 % status)
166
167 def GetResults(self):
168 """Get the trace data.
169
170 Returns:
171 The trace data.
172 """
173 if self._collection_process is None:
174 raise RuntimeError('Must call StopAgentTracing before GetResults')
175 self._collection_process.join()
176 self._collection_process = None
177 if self._recording_error:
178 raise RuntimeError(self._recording_error)
179 else:
180 return TraceResults('powerTraceAsString', self._trace_result, True)
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698