Javascript  |  129行  |  3.77 KB

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @fileoverview Parses trace_marker events that were inserted in the trace by
 * userland.
 */
base.require('importer.linux_perf.parser');
base.exportTo('tracing.importer.linux_perf', function() {

  var Parser = tracing.importer.linux_perf.Parser;

  /**
   * Parses linux trace mark events that were inserted in the trace by userland.
   * @constructor
   */
  function AndroidParser(importer) {
    Parser.call(this, importer);

    importer.registerEventHandler('tracing_mark_write:android',
        AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this));
    importer.registerEventHandler('0:android',
        AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this));

    this.model_ = importer.model_;
    this.ppids_ = {};
  }

  function parseArgs(argsString) {
    var args = {};
    if (argsString) {
      var argsArray = argsString.split(';');
      for (var i = 0; i < argsArray.length; ++i) {
        var parts = argsArray[i].split('=');
        if (parts[0])
          args[parts.shift()] = parts.join('=');
      }
    }
    return args;
  }

  AndroidParser.prototype = {
    __proto__: Parser.prototype,

    traceMarkWriteAndroidEvent: function(eventName, cpuNumber, pid, ts,
                                  eventBase) {
      var eventData = eventBase.details.split('|');
      switch (eventData[0]) {
        case 'B':
          var ppid = parseInt(eventData[1]);
          var category = eventData[4];
          var title = eventData[2];
          var thread = this.model_.getOrCreateProcess(ppid)
            .getOrCreateThread(pid);
          thread.name = eventBase.threadName;
          if (!thread.isTimestampValidForBeginOrEnd(ts)) {
            this.model_.importErrors.push(
                'Timestamps are moving backward.');
            return false;
          }

          this.ppids_[pid] = ppid;
          thread.beginSlice(category, title, ts, parseArgs(eventData[3]));

          break;
        case 'E':
          var ppid = this.ppids_[pid];
          if (ppid === undefined) {
            // Silently ignore unmatched E events.
            break;
          }

          var thread = this.model_.getOrCreateProcess(ppid)
            .getOrCreateThread(pid);
          if (!thread.openSliceCount) {
            // Silently ignore unmatched E events.
            break;
          }

          var slice = thread.endSlice(ts);

          var args = parseArgs(eventData[3]);
          for (var arg in args) {
            if (slice.args[arg] !== undefined) {
              this.model_.importErrors.push(
                  'Both the B and E events of ' + slice.title +
                  'provided values for argument ' + arg + '. ' +
                  'The value of the E event will be used.');
            }
            slice.args[arg] = args[arg];
          }

          break;
        case 'C':
          var ppid = parseInt(eventData[1]);
          var name = eventData[2];
          var value = parseInt(eventData[3]);
          var category = eventData[4];

          var ctr = this.model_.getOrCreateProcess(ppid)
              .getOrCreateCounter(category, name);
          // Initialize the counter's series fields if needed.
          if (ctr.numSeries == 0) {
            ctr.seriesNames.push('value');
            ctr.seriesColors.push(
                tracing.getStringColorId(ctr.name + '.' + 'value'));
          }

          // Add the sample value.
          ctr.timestamps.push(ts);
          ctr.samples.push(value);

          break;
        default:
          return false;
      }

      return true;
    },
  };

  Parser.registerSubtype(AndroidParser);

  return {
    AndroidParser: AndroidParser
  };
});