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