Home | History | Annotate | Download | only in adb_profile_chrome
      1 # Copyright 2014 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 gzip
      6 import json
      7 import os
      8 import shutil
      9 import sys
     10 import zipfile
     11 
     12 from adb_profile_chrome import util
     13 
     14 from pylib import constants
     15 
     16 sys.path.append(os.path.join(constants.DIR_SOURCE_ROOT,
     17                              'third_party',
     18                              'trace-viewer'))
     19 # pylint: disable=F0401
     20 from trace_viewer.build import trace2html
     21 
     22 
     23 def _PackageTracesAsHtml(trace_files, html_file):
     24   with open(html_file, 'w') as f:
     25     trace2html.WriteHTMLForTracesToFile(trace_files, f)
     26   for trace_file in trace_files:
     27     os.unlink(trace_file)
     28 
     29 
     30 def _CompressFile(host_file, output):
     31   with gzip.open(output, 'wb') as out, \
     32       open(host_file, 'rb') as input_file:
     33     out.write(input_file.read())
     34   os.unlink(host_file)
     35 
     36 
     37 def _ArchiveFiles(host_files, output):
     38   with zipfile.ZipFile(output, 'w', zipfile.ZIP_DEFLATED) as z:
     39     for host_file in host_files:
     40       z.write(host_file)
     41       os.unlink(host_file)
     42 
     43 
     44 def _MergeTracesIfNeeded(trace_files):
     45   if len(trace_files) <= 1:
     46     return trace_files
     47   merge_candidates = []
     48   for trace_file in trace_files:
     49     with open(trace_file) as f:
     50       # Try to detect a JSON file cheaply since that's all we can merge.
     51       if f.read(1) != '{':
     52         continue
     53       f.seek(0)
     54       try:
     55         json_data = json.load(f)
     56       except ValueError:
     57         continue
     58       merge_candidates.append((trace_file, json_data))
     59   if len(merge_candidates) <= 1:
     60     return trace_files
     61 
     62   other_files = [f for f in trace_files
     63                  if not f in [c[0] for c in merge_candidates]]
     64   merged_file, merged_data = merge_candidates[0]
     65   for trace_file, json_data in merge_candidates[1:]:
     66     for key, value in json_data.items():
     67       if not merged_data.get(key) or json_data[key]:
     68         merged_data[key] = value
     69     os.unlink(trace_file)
     70 
     71   with open(merged_file, 'w') as f:
     72     json.dump(merged_data, f)
     73   return [merged_file] + other_files
     74 
     75 
     76 def PackageTraces(trace_files, output=None, compress=False, write_json=False):
     77   trace_files = _MergeTracesIfNeeded(trace_files)
     78   if not write_json:
     79     html_file = os.path.splitext(trace_files[0])[0] + '.html'
     80     _PackageTracesAsHtml(trace_files, html_file)
     81     trace_files = [html_file]
     82 
     83   if compress and len(trace_files) == 1:
     84     result = output or trace_files[0] + '.gz'
     85     _CompressFile(trace_files[0], result)
     86   elif len(trace_files) > 1:
     87     result = output or 'chrome-combined-trace-%s.zip' % util.GetTraceTimestamp()
     88     _ArchiveFiles(trace_files, result)
     89   elif output:
     90     result = output
     91     shutil.move(trace_files[0], result)
     92   else:
     93     result = trace_files[0]
     94   return result
     95