1664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis#!/usr/bin/env python
2664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
3664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis# Copyright (c) 2011 The Chromium Authors. All rights reserved.
4664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis# Use of this source code is governed by a BSD-style license that can be
5664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis# found in the LICENSE file.
6664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
7664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis"""Android system-wide tracing utility.
8664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
9664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie GennisThis is a tool for capturing a trace that includes data from both userland and
10664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennisthe kernel.  It creates an HTML file for visualizing the trace.
11664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis"""
12664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
13664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennisimport errno, optparse, os, select, subprocess, sys, time, zlib
14664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
15664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis# This list is based on the tags in frameworks/native/include/utils/Trace.h.
16664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennistrace_tag_bits = {
17664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  'gfx':      1<<1,
18664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  'input':    1<<2,
19664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  'view':     1<<3,
20664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  'webview':  1<<4,
21664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  'wm':       1<<5,
22664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  'am':       1<<6,
23664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  'sync':     1<<7,
24664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  'audio':    1<<8,
25664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  'video':    1<<9,
26664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  'camera':   1<<10,
27664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis}
28664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
29664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennisflattened_css_file = 'style.css'
30664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennisflattened_js_file = 'script.js'
31664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
32664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennisdef add_adb_serial(command, serial):
33664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  if serial != None:
34664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    command.insert(1, serial)
35664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    command.insert(1, '-s')
36664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
37664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennisdef main():
38664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  parser = optparse.OptionParser()
39664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  parser.add_option('-o', dest='output_file', help='write HTML to FILE',
40664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    default='trace.html', metavar='FILE')
41664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  parser.add_option('-t', '--time', dest='trace_time', type='int',
42664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    help='trace for N seconds', metavar='N')
43664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  parser.add_option('-b', '--buf-size', dest='trace_buf_size', type='int',
44664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    help='use a trace buffer size of N KB', metavar='N')
45664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  parser.add_option('-d', '--disk', dest='trace_disk', default=False,
46664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    action='store_true', help='trace disk I/O (requires root)')
47664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  parser.add_option('-f', '--cpu-freq', dest='trace_cpu_freq', default=False,
48664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    action='store_true', help='trace CPU frequency changes')
49664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  parser.add_option('-i', '--cpu-idle', dest='trace_cpu_idle', default=False,
50664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    action='store_true', help='trace CPU idle events')
51664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  parser.add_option('-l', '--cpu-load', dest='trace_cpu_load', default=False,
52664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    action='store_true', help='trace CPU load')
53664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  parser.add_option('-s', '--no-cpu-sched', dest='trace_cpu_sched', default=True,
54664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    action='store_false', help='inhibit tracing CPU ' +
55664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    'scheduler (allows longer trace times by reducing data ' +
56664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    'rate into buffer)')
57664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  parser.add_option('-u', '--bus-utilization', dest='trace_bus_utilization',
58664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    default=False, action='store_true',
59664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    help='trace bus utilization (requires root)')
60664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  parser.add_option('-w', '--workqueue', dest='trace_workqueue', default=False,
61664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    action='store_true', help='trace the kernel workqueues ' +
62664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    '(requires root)')
63664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  parser.add_option('--set-tags', dest='set_tags', action='store',
64664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    help='set the enabled trace tags and exit; set to a ' +
65664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    'comma separated list of: ' +
66664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    ', '.join(trace_tag_bits.iterkeys()))
67664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  parser.add_option('--link-assets', dest='link_assets', default=False,
68664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    action='store_true', help='link to original CSS or JS resources '
69664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    'instead of embedding them')
70664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  parser.add_option('--from-file', dest='from_file', action='store',
71664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    help='read the trace from a file rather than running a live trace')
72664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  parser.add_option('--asset-dir', dest='asset_dir', default='trace-viewer',
73664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    type='string', help='')
74664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  parser.add_option('-e', '--serial', dest='device_serial', type='string',
75664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                    help='adb device serial number')
76664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  options, args = parser.parse_args()
77664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
78664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  if options.set_tags:
79664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    flags = 0
80664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    tags = options.set_tags.split(',')
81664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    for tag in tags:
82664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      try:
83664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis        flags |= trace_tag_bits[tag]
84664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      except KeyError:
85664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis        parser.error('unrecognized tag: %s\nknown tags are: %s' %
86664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                     (tag, ', '.join(trace_tag_bits.iterkeys())))
87664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    atrace_args = ['adb', 'shell', 'setprop', 'debug.atrace.tags.enableflags', hex(flags)]
88664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    add_adb_serial(atrace_args, options.device_serial)
89664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    try:
90664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      subprocess.check_call(atrace_args)
91664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    except subprocess.CalledProcessError, e:
92664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      print >> sys.stderr, 'unable to set tags: %s' % e
93664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    print '\nSet enabled tags to: %s\n' % ', '.join(tags)
94664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    print ('You will likely need to restart the Android framework for this to ' +
95664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis          'take effect:\n\n    adb shell stop\n    adb shell ' +
96664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis          'start\n')
97664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    return
98664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
99664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  atrace_args = ['adb', 'shell', 'atrace', '-z']
100664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  add_adb_serial(atrace_args, options.device_serial)
101664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
102664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  if options.trace_disk:
103664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    atrace_args.append('-d')
104664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  if options.trace_cpu_freq:
105664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    atrace_args.append('-f')
106664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  if options.trace_cpu_idle:
107664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    atrace_args.append('-i')
108664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  if options.trace_cpu_load:
109664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    atrace_args.append('-l')
110664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  if options.trace_cpu_sched:
111664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    atrace_args.append('-s')
112664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  if options.trace_bus_utilization:
113664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    atrace_args.append('-u')
114664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  if options.trace_workqueue:
115664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    atrace_args.append('-w')
116664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  if options.trace_time is not None:
117664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    if options.trace_time > 0:
118664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      atrace_args.extend(['-t', str(options.trace_time)])
119664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    else:
120664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      parser.error('the trace time must be a positive number')
121664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  if options.trace_buf_size is not None:
122664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    if options.trace_buf_size > 0:
123664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      atrace_args.extend(['-b', str(options.trace_buf_size)])
124664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    else:
125664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      parser.error('the trace buffer size must be a positive number')
126664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
127664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  if options.from_file is not None:
128664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    atrace_args = ['cat', options.from_file]
129664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
130664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  script_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
131664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
132664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  if options.link_assets:
133664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    src_dir = os.path.join(script_dir, options.asset_dir, 'src')
134664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    build_dir = os.path.join(script_dir, options.asset_dir, 'build')
135664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
13666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    js_files, js_flattenizer, css_files, templates = get_assets(src_dir, build_dir)
137664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
138664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    css = '\n'.join(linked_css_tag % (os.path.join(src_dir, f)) for f in css_files)
139664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    js = '<script language="javascript">\n%s</script>\n' % js_flattenizer
140664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    js += '\n'.join(linked_js_tag % (os.path.join(src_dir, f)) for f in js_files)
14166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
142664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  else:
143664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    css_filename = os.path.join(script_dir, flattened_css_file)
144664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    js_filename = os.path.join(script_dir, flattened_js_file)
145664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    css = compiled_css_tag % (open(css_filename).read())
146664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    js = compiled_js_tag % (open(js_filename).read())
14766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    templates = ''
148664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
149664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  html_filename = options.output_file
150664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
151664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  trace_started = False
152664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  leftovers = ''
153664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  adb = subprocess.Popen(atrace_args, stdout=subprocess.PIPE,
154664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis                         stderr=subprocess.PIPE)
155664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  dec = zlib.decompressobj()
156664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  while True:
157664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    ready = select.select([adb.stdout, adb.stderr], [], [adb.stdout, adb.stderr])
158664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    if adb.stderr in ready[0]:
159664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      err = os.read(adb.stderr.fileno(), 4096)
160664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      sys.stderr.write(err)
161664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      sys.stderr.flush()
162664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    if adb.stdout in ready[0]:
163664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      out = leftovers + os.read(adb.stdout.fileno(), 4096)
164664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      if options.from_file is None:
165664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis        out = out.replace('\r\n', '\n')
166664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      if out.endswith('\r'):
167664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis        out = out[:-1]
168664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis        leftovers = '\r'
169664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      else:
170664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis        leftovers = ''
171664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      if not trace_started:
172664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis        lines = out.splitlines(True)
173664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis        out = ''
174664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis        for i, line in enumerate(lines):
175664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis          if line == 'TRACE:\n':
176664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis            sys.stdout.write("downloading trace...")
177664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis            sys.stdout.flush()
178664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis            out = ''.join(lines[i+1:])
1799c39c34a196b50aaaa2dd897b7844e2e0508e522Siva Velusamy            html_prefix = read_asset(script_dir, 'prefix.html')
180664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis            html_file = open(html_filename, 'w')
18166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis            html_file.write(html_prefix % (css, js, templates))
182664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis            trace_started = True
183664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis            break
184664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis          elif 'TRACE:'.startswith(line) and i == len(lines) - 1:
185664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis            leftovers = line + leftovers
186664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis          else:
187664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis            sys.stdout.write(line)
188664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis            sys.stdout.flush()
189664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      if len(out) > 0:
190664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis        out = dec.decompress(out)
191664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      html_out = out.replace('\n', '\\n\\\n')
192664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      if len(html_out) > 0:
193664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis        html_file.write(html_out)
194664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    result = adb.poll()
195664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    if result is not None:
196664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      break
197664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  if result != 0:
198664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    print >> sys.stderr, 'adb returned error code %d' % result
199664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  elif trace_started:
200664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    html_out = dec.flush().replace('\n', '\\n\\\n').replace('\r', '')
201664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    if len(html_out) > 0:
202664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      html_file.write(html_out)
2039c39c34a196b50aaaa2dd897b7844e2e0508e522Siva Velusamy    html_suffix = read_asset(script_dir, 'suffix.html')
204664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    html_file.write(html_suffix)
205664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    html_file.close()
20666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    print " done\n\n    wrote file://%s\n" % (os.path.abspath(options.output_file))
207664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  else:
208664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    print >> sys.stderr, ('An error occured while capturing the trace.  Output ' +
209664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      'file was not written.')
210664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
2119c39c34a196b50aaaa2dd897b7844e2e0508e522Siva Velusamydef read_asset(src_dir, filename):
2129c39c34a196b50aaaa2dd897b7844e2e0508e522Siva Velusamy  return open(os.path.join(src_dir, filename)).read()
2139c39c34a196b50aaaa2dd897b7844e2e0508e522Siva Velusamy
214664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennisdef get_assets(src_dir, build_dir):
215664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  sys.path.append(build_dir)
216664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  gen = __import__('generate_standalone_timeline_view', {}, {})
217664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  parse_deps = __import__('parse_deps', {}, {})
21866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis  gen_templates = __import__('generate_template_contents', {}, {})
219664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  filenames = gen._get_input_filenames()
22066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis  load_sequence = parse_deps.calc_load_sequence(filenames, src_dir)
221664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
222664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  js_files = []
223664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  js_flattenizer = "window.FLATTENED = {};\n"
22466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis  js_flattenizer += "window.FLATTENED_RAW_SCRIPTS = {};\n"
225664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  css_files = []
226664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
227664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  for module in load_sequence:
228664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    js_files.append(os.path.relpath(module.filename, src_dir))
229664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    js_flattenizer += "window.FLATTENED['%s'] = true;\n" % module.name
23066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis    for dependent_raw_script_name in module.dependent_raw_script_names:
23166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis      js_flattenizer += (
23266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        "window.FLATTENED_RAW_SCRIPTS['%s'] = true;\n" %
23366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis        dependent_raw_script_name)
23466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
235664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis    for style_sheet in module.style_sheets:
236664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis      css_files.append(os.path.relpath(style_sheet.filename, src_dir))
237664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
23866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis  templates = gen_templates.generate_templates()
23966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis
240664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  sys.path.pop()
241664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
24266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis  return (js_files, js_flattenizer, css_files, templates)
243664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
244664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Genniscompiled_css_tag = """<style type="text/css">%s</style>"""
245664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Genniscompiled_js_tag = """<script language="javascript">%s</script>"""
246664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
247664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennislinked_css_tag = """<link rel="stylesheet" href="%s"></link>"""
248664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennislinked_js_tag = """<script language="javascript" src="%s"></script>"""
249664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis
250664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennisif __name__ == '__main__':
251664f21bcaf14044e5e9b09cb7beb8724d18fb851Jamie Gennis  main()
252