<!DOCTYPE html>
<!--
Copyright (c) 2015 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.
-->

<link rel="import" href="/extras/importer/linux_perf/parser.html">

<script>
'use strict';

/**
 * @fileoverview Parses Binder events
 */
tr.exportTo('tr.e.importer.linux_perf', function() {
  var Parser = tr.e.importer.linux_perf.Parser;

  // Matches binder transactions:
  // transaction=%d dest_node=%d dest_proc=%d dest_thread=%d reply=%d flags=0x%x
  // code=0x%x
  var binderTransRE = new RegExp('transaction=(\\d+) dest_node=(\\d+) ' +
                                 'dest_proc=(\\d+) dest_thread=(\\d+) ' +
                                 'reply=(\\d+) flags=(0x[0-9a-fA-F]+) ' +
                                 'code=(0x[0-9a-fA-F]+)');

  var binderTransReceivedRE = /transaction=(\d+)/;

  function isBinderThread(name) {
    return (name.indexOf('Binder') > -1);
  }

  // Taken from kernel source: include/uapi/linux/android/binder.h.
  var TF_ONE_WAY = 0x01;
  var TF_ROOT_OBJECT = 0x04;
  var TF_STATUS_CODE = 0x08;
  var TF_ACCEPT_FDS = 0x10;
  var NO_FLAGS = 0;

  function binderFlagsToHuman(num) {
    var flag = parseInt(num, 16);
    var str = '';

    if (flag & TF_ONE_WAY)
      str += 'this is a one-way call: async, no return; ';
    if (flag & TF_ROOT_OBJECT)
      str += 'contents are the components root object; ';
    if (flag & TF_STATUS_CODE)
      str += 'contents are a 32-bit status code; ';
    if (flag & TF_ACCEPT_FDS)
      str += 'allow replies with file descriptors; ';
    if (flag === NO_FLAGS)
      str += 'No Flags Set';

    return str;
  }

  function isReplyToOrigin(calling, called) {
    return (called.dest_proc === calling.calling_pid ||
            called.dest_thread === calling.calling_pid);
  }

  function binderCodeToHuman(code) {
    return 'Java Layer Dependent';
  }

  function doInternalSlice(trans, slice, ts) {
    if (slice.subSlices.length !== 0) {
      /* We want to make sure we keep moving the small slice to the end of
         the big slice or else the arrows will not point to the end.
      */
      slice.subSlices[0].start = ts;
      return slice.subSlices[0];
    }
    var kthread = trans.calling_kthread.thread;
    var internal_slice = kthread.sliceGroup.pushCompleteSlice('binder',
                             slice.title,
                             ts, .001, 0, 0,
                             slice.args);

    internal_slice.title = slice.title;
    internal_slice.id = slice.id;
    internal_slice.colorId = slice.colorId;
    slice.subSlices.push(internal_slice);
    return internal_slice;
  }

  function generateBinderArgsForSlice(trans, c_threadName) {
    return {
      'Transaction Id': trans.transaction_key,
      'Destination Node': trans.dest_node,
      'Destination Process': trans.dest_proc,
      'Destination Thread': trans.dest_thread,
      'Destination Name': c_threadName,
      'Reply transaction?': trans.is_reply_transaction,
      'Flags': trans.flags + ' ' +
           binderFlagsToHuman(trans.flags),

      'Code': trans.code + ' ' +
           binderCodeToHuman(trans.code),

      'Calling PID': trans.calling_pid,
      'Calling tgid': trans.calling_kthread.thread.parent.pid
    };
  }

  /** @constructor */
  function BinderTransaction(events, calling_pid, calling_ts, calling_kthread) {
    this.transaction_key = parseInt(events[1]);
    this.dest_node = parseInt(events[2]);
    this.dest_proc = parseInt(events[3]);
    this.dest_thread = parseInt(events[4]);
    this.is_reply_transaction = parseInt(events[5]) === 1 ? true : false;
    this.expect_reply = ((this.is_reply_transaction === false) &&
        (parseInt(events[6], 16) & TF_ONE_WAY) === 0);

    this.flags = events[6];
    this.code = events[7];
    this.calling_pid = calling_pid;
    this.calling_ts = calling_ts;
    this.calling_kthread = calling_kthread;
  }


  /** @constructor */
  function BinderParser(importer) {
    Parser.call(this, importer);
    importer.registerEventHandler('binder_locked',
        BinderParser.prototype.
        binderLocked.bind(this));
    importer.registerEventHandler('binder_unlock',
        BinderParser.prototype.
        binderUnlock.bind(this));
    importer.registerEventHandler('binder_lock',
        BinderParser.prototype.binderLock.bind(this));
    importer.registerEventHandler('binder_transaction',
        BinderParser.prototype.
        binderTransaction.bind(this));
    importer.registerEventHandler('binder_transaction_received',
        BinderParser.prototype.
        binderTransactionReceived.bind(this));

    this.model_ = importer.model;
    this.kthreadlookup = {};
    this.importer_ = importer;
    this.transWaitingRecv = {};
    this.syncTransWaitingCompletion = {};
    this.recursiveSyncTransWaitingCompletion_ByPID = {};
    this.receivedTransWaitingConversion = {};
  }

  BinderParser.prototype = {
    __proto__: Parser.prototype,

    binderLock: function(eventName, cpuNumber, pid, ts, eventBase) {
      var tgid = parseInt(eventBase.tgid);
      this.doNameMappings(pid, tgid, eventName.threadName);

      var kthread = this.importer_.
          getOrCreateBinderKernelThread(eventBase.threadName, tgid, pid);

      kthread.binderAttemptLockTS = ts;
      kthread.binderOpenTsA = ts;
      return true;
    },

    binderLocked: function(eventName, cpuNumber, pid, ts, eventBase) {
      var binder_thread = isBinderThread(eventBase.threadName);
      var tgid, name;
      var as_slice;
      var need_push = false;
      var kthread, rthread;

      tgid = parseInt(eventBase.tgid);
      name = eventBase.threadName;

      kthread = this.importer_.
          getOrCreateBinderKernelThread(eventBase.threadName, tgid, pid);

      this.doNameMappings(pid, tgid, name);

      rthread = kthread.thread;
      kthread.binderLockAquiredTS = ts;

      if (kthread.binderAttemptLockTS === undefined)
        return false;

      var args = this.generateArgsForSlice(tgid, pid, name, kthread);
      rthread.sliceGroup.pushCompleteSlice('binder', 'binder lock waiting',
          kthread.binderAttemptLockTS,
          ts - kthread.binderAttemptLockTS,
          0, 0, args);

      kthread.binderAttemptLockTS = undefined;
      return true;
    },

    binderUnlock: function(eventName, cpuNumber, pid, ts, eventBase) {
      var tgid = parseInt(eventBase.tgid);
      var kthread = this.importer_.
          getOrCreateBinderKernelThread(
          eventBase.threadName, tgid, pid);

      if (kthread.binderLockAquiredTS === undefined)
        return false;

      args = this.generateArgsForSlice(tgid, pid, eventBase.threadName,
          kthread);
      kthread.thread.sliceGroup.pushCompleteSlice(
          'binder',
          'binder lock held',
           kthread.binderLockAquiredTS,
           ts - kthread.binderLockAquiredTS,
           0, 0, args);

      kthread.binderLockAquiredTS = undefined;
      return true;
    },

    /** There are a few transaction status changes that signify
     *  progress through a binder transaction:
     *
     * Case One: Sync transaction.
     *  Thread A calls a blocking function on Thread B. We receive a
     *  binder_transaction msg From thread A stating that it is going to Call
     *  thread B. We create a slice and a binder object for this transaction and
     *  add it to addTransactionWaitingForRecv(transaction key, binder object)
     *  This notifies thread B and passes the slice, binder object and time
     *  stamp.
     *
     * Case Two: Async transaction.
     *  Thread A calls an async function on Thread B. Like above we receive a
     *  binder_transaction message, but the flags differ from above. The
     *  TF_ONEWAY flags are set so we know that when Thread B gets the
     *  binder_transaction_received with the same transaciton key the total
     *  transaction is complete.
     *
     * Case Three: 'Prior_receive'
     *  Prior_receive occurs when the thread being called (think A calls B),
     *  receives a binder_transaction_received message, but cannot correlate it
     *  to any current outstanding recursive transactions. That means the
     *  message it just received is the start of some communication, not some
     *  ongoing communication.
     *  Once the execution flow has been passed to thread B, from A:
     *  Thread B enters binder_transaction_received() we see that Thread A
     *  had notified us that it sent us a message by calling
     *  getTransactionWaitingForRecv(transaction key);
     *  What can happen now is either this was a simple Call reply,
     *  or this is a call -> recursion -> reply. We call modelPriorReceive()
     *  which sets up the slices accordingly.
     *  If this is a call -> recursion -> reply
     *  we will go to case 4 by calling addRecursiveSyncTransNeedingCompletion()
     *  The function takes B's PID, the binder object from A and the current
     *  binder object from B. This function adds outstanding non-complete
     *  transactions to a stack on thread B.
     *
     * Case Four: 'recursive_trans'
     *  This case follows Like above:
     *  A sent binder_transaction
     *  B got binder_transaction_received
     *  B instead of replying to A can Call C or call 'into' A, ie recursion
     *  Case four also deals with setting up a large slice to 'contain'
     *  all the recursive transactions that happen until B finally replies to
     *  A.
     *
     *
     * An example: A-> B-> C-> B-> A
     *
     * (1) A starts a synchronous transaction to B.
     * (2) A enters binderTransaction() event handler, hits the else statement
     * (3) A calls addTransactionWaitingForRecv(trans key, object) to notify
     *     Thread B.
     * (4) B Enters binderTransactionReceived().
     * (5) B hits the second if after calling
     *     getTransactionWaitingForRecv(trans key)
     *     This function returns us the object set up in step (3).
     * (6) This is not an async transaction, B calls
     *      setCurrentReceiveOnPID(B's PID, [ts for (4), object from (3)]).
     *
     * (7) B enters binderTransaction() event handler, first if triggers after
     *     calling getPriorReceiveOnPID(B's PID) the tuple from (6) is returned.
     *
     * (8) Execution enters modelPriorReceive().
     * (8a) A slice is setup for this binder transaction in B's timeline.
     * (9) This is not a reply to thread A, B is going to call Thread C.
     * (10) else statement is hit.
     * (11) We set the tile from (8a) to be binder_reply this is the
     *     'containg slice' for the recursion
     * (12) We create a new slice 'binder_transaction' this slice is the
     *      recursive slice that will have arrows to Thread C's slice.
     * (13) addRecursiveSyncTransNeedingCompletion(B's PID,
     *                                            [obj from (3), obj from 7])
     *      this sets up notification that B's pid has outstanding recursive
     *      transactions that need to be completed.
     * (14) B notifies C that a transaction is waiting for it by calling
     *      addTransactionWaitingForRecv like in step (3).
     * (15) C enters binderTransactionReceived() step 5 6 7 8 8a happen, but in
     *      the context of Thread C.
     * (16) C is in modelPriorReceive(), it hits the first if statement,
     *      this transaction _IS_ a reply, and it is a reply to B.
     * (17) C calls addSyncTransNeedingCompletion(trans key,
     *                                       [object from(3), object from 15-5])
     * (18) B enters binderTransactionReceived() hits the first if after calling
     *      getSyncTransNeedingCompletion(trans key from (17)) the tuple from
     *     (17) gets returned.
     *
     * (19) B scales up the slice created in (12) and sets up flows from 15-8a
     *      slice.
     * (20) B enters BinderTransaction() event handler and the second if is hit
     *      after calling getRecursiveTransactionNeedingCompletion(B's pid).
     * (21) modelRecursiveTransactions() gets called, first if executes.
     * (22) slice durations are fixed up.
     * (23) B notifies A via
     *      addSyncTransNeedingCompletion(trans key, binder obj from 8a).
     * (24) B deletes the outstanding asynctrans via
     (      removeRecursiveTransaction(B's pid).
     * (25) A enters binderTransactionReceived() event handler and finishes up
     *      some flows, and slices.
     */
    binderTransaction: function(eventName, cpuNumber, pid, ts, eventBase) {
      var event = binderTransRE.exec(eventBase.details);
      if (event === undefined)
        return false;

      var tgid = parseInt(eventBase.tgid);

      this.doNameMappings(pid, tgid, eventBase.threadName);

      var kthread;
      kthread = this.importer_.
          getOrCreateBinderKernelThread(eventBase.threadName, tgid, pid);

      var trans = new BinderTransaction(event, pid, ts, kthread);
      var args = generateBinderArgsForSlice(trans, eventBase.threadName);
      /**
       * This thread previously ack'd the transaction with a
       * transaction_received. That means someone sent us a message we processed
       * it and are now sending a transaction.
       * The transaction could be a response, or it could be recursive.
       */
      var prior_receive = this.getPriorReceiveOnPID(pid);

      if (prior_receive !== false) {
        return this.modelPriorReceive(prior_receive, ts, pid, tgid, kthread,
            trans, args, event);
      }
      /**
       * This Thread has an already established recursive slice. We will now
       * either complete the entire transaction, OR do more recursive calls.
       */
      var recursive_trans = this.getRecursiveTransactionNeedingCompletion(pid);

      if (recursive_trans !== false)
        return this.modelRecursiveTransactions(recursive_trans, ts, pid,
            kthread, trans, args);

      /**
       * Start of a Transaction. This thread is the initiator of either a call
       * response, an async call -> ack, or a call -> recursion -> response.
       * Note, we put a fake duration into this slice and patch it up later.
       */
      var slice = kthread.thread.sliceGroup.pushCompleteSlice('binder',
          '', ts, .03, 0, 0, args);

      slice.colorId = tr.ui.b.
          getColorIdForGeneralPurposeString(ts.toString());
      trans.slice = slice;

      if (trans.expect_reply)
        slice.title = 'binder transaction';
      else
        slice.title = 'binder transaction async';

      this.addTransactionWaitingForRecv(trans.transaction_key, trans);

      return true;
    },

    binderTransactionReceived: function(eventName, cpuNumber, pid, ts,
                                        eventBase) {
      var event = binderTransReceivedRE.exec(eventBase.details);

      if (event === undefined)
        return false;

      var transactionkey = parseInt(event[1]);
      var tgid = parseInt(eventBase.tgid);
      var kthread;
      kthread = this.importer_.
          getOrCreateBinderKernelThread(eventBase.threadName, tgid, pid);

      var syncComplete = this.getSyncTransNeedsCompletion(transactionkey);

      if (syncComplete !== false) {
        /* This recv is the completion of a synchronous transaction.
         * We need to scale the slice up to the current ts and finish
         * creating some flows.
         */
        var sync_trans = syncComplete[0];
        var sync_slice = sync_trans.slice;
        var response_trans = syncComplete[1];
        var response_slice = response_trans.slice;

        sync_slice.duration = ts - sync_slice.start;
        /** These calls are a little hack that places a very small slice at
         *  the end of the sync slice and the response slice. This allows us
         *  to hook flow events (arrows) from the start to the end of the
         *  slices.
         */
        var sync_internal = doInternalSlice(sync_trans, sync_slice, ts);
        var response_ts = response_slice.start + response_slice.duration;
        var response_internal = doInternalSlice(response_trans,
            response_slice, response_ts);

        if (response_slice.outFlowEvents.length === 0 ||
            sync_slice.inFlowEvents.length === 0) {
          var flow = this.generateFlow(response_internal, sync_internal,
              response_trans, sync_trans);

          sync_slice.inFlowEvents.push(flow);
          response_slice.outFlowEvents.push(flow);
          this.model_.flowEvents.push(flow);
        }
        // Move flow arrows -- but not the first one.
        for (var i = 1; i < sync_slice.inFlowEvents.length; i++) {
          sync_slice.inFlowEvents[i].duration =
              ts - sync_slice.inFlowEvents[i].start;
        }
        return true;
      }

      var tr_for_recv = this.getTransactionWaitingForRecv(transactionkey);

      if (tr_for_recv !== false) {
        if (!tr_for_recv.expect_reply) {
          // This is an async call place an Async slice.
          var args = generateBinderArgsForSlice(tr_for_recv,
              eventBase.threadName);
          var slice = kthread.thread.sliceGroup.
              pushCompleteSlice('binder',
              'binder Async recv',
              ts, .03, 0, 0,
              args);

          var fake_event = [0, 0, 0, 0, 0, 0, 0];
          var fake_trans = new BinderTransaction(fake_event, pid, ts, kthread);
          var flow = this.generateFlow(tr_for_recv.slice, slice,
              tr_for_recv, fake_trans);

          this.model_.flowEvents.push(flow);
          tr_for_recv.slice.title = 'binder transaction async';
          tr_for_recv.slice.duration = .03;
          return true;
        }
        // Setup prior receive.
        tr_for_recv.slice.title = 'binder transaction';
        this.setCurrentReceiveOnPID(pid, [ts, tr_for_recv]);
        return true;
      }
      /** This case is when we received an ack for a transaction we have
       *  never seen before. This usually happens at the start of a trace.
       *  We will get incomplete transactions that started before started
       *  tracing. Just discard them.
       */
      return false;
    },

    // helper functions
    modelRecursiveTransactions: function(recursive_trans, ts, pid, kthread,
                                         trans, args) {

      var recursive_slice = recursive_trans[1].slice;
      var orig_slice = recursive_trans[0].slice;
      recursive_slice.duration = ts - recursive_slice.start;
      trans.slice = recursive_slice;

      if (trans.is_reply_transaction) {
        /* Case one:
         * This transaction is finally the reply of the recursion.
         */
        orig_slice.duration = ts - orig_slice.start;
        this.addSyncTransNeedingCompletion(trans.transaction_key,
             recursive_trans);

        if (isReplyToOrigin(recursive_trans[0], trans))
          this.removeRecursiveTransaction(pid);
      } else {
        /**
         *  Case two:
         *  This transaction is more recursive calls.
         *  This is a nested call within an already started transaction,
         *  it can either be a async or a normal sync transaction.
         */
        var slice = kthread.thread.sliceGroup.pushCompleteSlice('binder',
            '' , ts, .03, 0,
            0, args);

        trans.slice = slice;
        this.addTransactionWaitingForRecv(trans.transaction_key, trans);
      }
      return true;
    },

    modelPriorReceive: function(prior_receive, ts, pid, tgid, kthread, trans,
                                args, event) {
      var callee_slice = prior_receive[1].slice;
      var callee_trans = prior_receive[1];
      var recv_ts = prior_receive[0];
      var slice = kthread.thread.sliceGroup.pushCompleteSlice('binder',
          '', recv_ts, ts - recv_ts, 0, 0, args);

      var flow = this.generateFlow(callee_slice, slice, callee_trans, trans);
      this.model_.flowEvents.push(flow);
      trans.slice = slice;

      if (trans.is_reply_transaction) {
        /* This is a response to a synchronous or a recursive sync
         * transaction.
         */
        slice.title = 'binder reply';
        /* Notify this transaction key that when it recv's it is completing
         * a sync transaction.
         */
        this.addSyncTransNeedingCompletion(trans.transaction_key,
            [callee_trans, trans]);
      } else {
        /**
         * Recursive calls and or calls around, either way it's not
         * going to complete a transaction.
         */
          slice.title = 'binder reply';
          /* Since this is a recursive transaction we want to create the main
           * large slice which will contain all these recursive transactions.
           * For that we created the main slice above and this is a recursive
           * transaction that will be placed right below it. Note, that this
           * is only for the first recursive transaction. If more come they will
           * be handled below in the getRecursiveTransactionNeedingCompletion
           */
          var trans1 = new BinderTransaction(event, pid, ts, kthread);

          slice = kthread.thread.sliceGroup.
          pushCompleteSlice('binder',
              'binder transaction',
              recv_ts,
              (ts - recv_ts), 0,
              0, args);

          /* could be a async trans if so set the length to be a small one */
          if (!trans.expect_reply) {
            slice.title = 'binder transaction async';
            slice.duration = .03;
          } else {
            /* stupid hack to stop merging of AIDL slices and
             * this slice. This is currently disabled, if AIDL tracing is on we
             * will see merging of this slice and the AIDL slice. Once upstream
             * has a solution for flow events to be placed in the middle of
             * slices this part can be fixed.
             *
             * This is commented out because AIDL tracing doesn't exit yet.
             */
            //slice.start += .15;
          }
          trans1.slice = slice;
          this.addRecursiveSyncTransNeedingCompletion(pid,
              [callee_trans, trans]);
          this.addTransactionWaitingForRecv(trans.transaction_key, trans1);
      }
      return true;
    },

    getRecursiveTransactionNeedingCompletion: function(pid) {
      if (this.recursiveSyncTransWaitingCompletion_ByPID[pid] === undefined)
        return false;

      var len = this.recursiveSyncTransWaitingCompletion_ByPID[pid].length;
      if (len === 0)
        return false;

      return this.recursiveSyncTransWaitingCompletion_ByPID[pid][len - 1];
    },

    addRecursiveSyncTransNeedingCompletion: function(pid, tuple) {
      if (this.recursiveSyncTransWaitingCompletion_ByPID[pid] === undefined)
        this.recursiveSyncTransWaitingCompletion_ByPID[pid] = [];

      this.recursiveSyncTransWaitingCompletion_ByPID[pid].push(tuple);
    },

    removeRecursiveTransaction: function(pid) {
      var len = this.recursiveSyncTransWaitingCompletion_ByPID[pid].length;
      if (len === 0) {
        delete this.recursiveSyncTransWaitingCompletion_ByPID[pid];
        return;
      }

      this.recursiveSyncTransWaitingCompletion_ByPID[pid].splice(len - 1, 1);
    },

    setCurrentReceiveOnPID: function(pid, tuple) {
      if (this.receivedTransWaitingConversion[pid] === undefined) {
        this.receivedTransWaitingConversion[pid] = [];
      }
      this.receivedTransWaitingConversion[pid].push(tuple);
    },

    getPriorReceiveOnPID: function(pid) {
      if (this.receivedTransWaitingConversion[pid] === undefined)
        return false;

      var len = this.receivedTransWaitingConversion[pid].length;
      if (len === 0)
        return false;

      return this.receivedTransWaitingConversion[pid].splice(len - 1, 1)[0];
    },

    addSyncTransNeedingCompletion: function(transactionkey, tuple) {
      var dict = this.syncTransWaitingCompletion;
      dict[transactionkey] = tuple;
    },

    getSyncTransNeedsCompletion: function(transactionkey) {
      var ret = this.syncTransWaitingCompletion[transactionkey];
      if (ret === undefined)
        return false;

      delete this.syncTransWaitingCompletion[transactionkey];
      return ret;
    },

    getTransactionWaitingForRecv: function(transactionkey) {
      var ret = this.transWaitingRecv[transactionkey];
      if (ret === undefined)
        return false;

      delete this.transWaitingRecv[transactionkey];
      return ret;
    },

    addTransactionWaitingForRecv: function(transactionkey, transaction) {
      this.transWaitingRecv[transactionkey] = transaction;
    },

    generateFlow: function(from, to, from_trans, to_trans) {
      var title = 'Transaction from : ' +
        this.pid2name(from_trans.calling_pid) +
        ' From PID: ' + from_trans.calling_pid + ' to pid: ' +
        to_trans.calling_pid +
        ' Thread Name: ' + this.pid2name(to_trans.calling_pid);

      var ts = from.start;
      var flow = new tr.model.FlowEvent('binder', ts, title, 1, ts, []);
      flow.startSlice = from;
      flow.endSlice = to;
      flow.start = from.start;
      flow.duration = to.start - ts;
      flow.colorId = 1;

      from.outFlowEvents.push(flow);
      to.inFlowEvents.push(flow);

      return flow;
    },

    generateArgsForSlice: function(tgid, pid, name, kthread) {
      return {
        'Thread Name': name,
        'pid': pid,
        'gid': tgid
      };
    },

    pid2name: function(pid) {
      return this.kthreadlookup[pid];
    },

    doNameMappings: function(pid, tgid, name) {
      this.registerPidName(pid, name);
      this.registerPidName(tgid, name);
    },

    registerPidName: function(pid, name) {
      if (this.pid2name(pid) === undefined)
        this.kthreadlookup[pid] = name;
    }
  };

  Parser.register(BinderParser);
  return {
    BinderParser: BinderParser
  };
});
</script>
