diff --git a/vts/performance/Android.mk b/vts/performance/Android.mk
index 826468d..80c9377 100644
--- a/vts/performance/Android.mk
+++ b/vts/performance/Android.mk
@@ -76,3 +76,24 @@
 
 LOCAL_MULTILIB := both
 include $(BUILD_NATIVE_TEST)
+
+# build for latency benchmark test for hwbinder.
+include $(CLEAR_VARS)
+LOCAL_MODULE := libhwbinder_latency
+
+LOCAL_MODULE_TAGS := eng tests
+
+LOCAL_SRC_FILES := Latency.cpp
+LOCAL_SHARED_LIBRARIES := \
+    libhwbinder \
+    libhidlbase \
+    libhidltransport \
+    liblog \
+    libutils \
+    android.hardware.tests.libhwbinder@1.0
+
+LOCAL_REQUIRED_MODULES := android.hardware.tests.libhwbinder@1.0-impl
+LOCAL_C_INCLUDES := system/libhwbinder/include
+
+LOCAL_MULTILIB := both
+include $(BUILD_NATIVE_TEST)
diff --git a/vts/performance/Latency.cpp b/vts/performance/Latency.cpp
new file mode 100644
index 0000000..c8edbca
--- /dev/null
+++ b/vts/performance/Latency.cpp
@@ -0,0 +1,488 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <android/hardware/tests/libhwbinder/1.0/IScheduleTest.h>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <string>
+#include <tuple>
+#include <vector>
+
+#include <pthread.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+using namespace std;
+using namespace android;
+using namespace android::hardware;
+
+using android::hardware::tests::libhwbinder::V1_0::IScheduleTest;
+
+#define ASSERT(cond)                                                \
+  do {                                                              \
+    if (!(cond)) {                                                  \
+      cerr << __func__ << ":" << __LINE__ << " condition:" << #cond \
+           << " failed\n"                                           \
+           << endl;                                                 \
+      exit(EXIT_FAILURE);                                           \
+    }                                                               \
+  } while (0)
+
+vector<sp<IScheduleTest> > services;
+
+// the ratio that the service is synced on the same cpu beyond
+// GOOD_SYNC_MIN is considered as good
+#define GOOD_SYNC_MIN (0.6)
+
+#define DUMP_PRICISION 2
+
+string trace_path = "/sys/kernel/debug/tracing";
+
+// the default value
+int no_pair = 1;
+int iterations = 100;
+int no_inherent = 0;
+int no_sync = 0;
+int verbose = 0;
+int trace;
+bool pass_through = false;
+
+static bool traceIsOn() {
+  fstream file;
+  file.open(trace_path + "/tracing_on", ios::in);
+  char on;
+  file >> on;
+  file.close();
+  return on == '1';
+}
+
+static void traceStop() {
+  ofstream file;
+  file.open(trace_path + "/tracing_on", ios::out | ios::trunc);
+  file << '0' << endl;
+  file.close();
+}
+
+// the deadline latency that we are interested in
+uint64_t deadline_us = 2500;
+
+static int threadPri() {
+  struct sched_param param;
+  int policy;
+  ASSERT(!pthread_getschedparam(pthread_self(), &policy, &param));
+  return param.sched_priority;
+}
+
+static void threadDump(const char* prefix) {
+  struct sched_param param;
+  int policy;
+  if (!verbose) return;
+  cout << "--------------------------------------------------" << endl;
+  cout << setw(12) << left << prefix << " pid: " << getpid()
+       << " tid: " << gettid() << " cpu: " << sched_getcpu() << endl;
+  ASSERT(!pthread_getschedparam(pthread_self(), &policy, &param));
+  string s = (policy == SCHED_OTHER)
+                 ? "SCHED_OTHER"
+                 : (policy == SCHED_FIFO)
+                       ? "SCHED_FIFO"
+                       : (policy == SCHED_RR) ? "SCHED_RR" : "???";
+  cout << setw(12) << left << s << param.sched_priority << endl;
+  return;
+}
+
+// This IPC class is widely used in binder/hwbinder tests.
+// The common usage is the main process to create the Pipe and forks.
+// Both parent and child hold a object and each wait() on parent
+// needs a signal() on the child to wake up and vice versa.
+class Pipe {
+  int m_readFd;
+  int m_writeFd;
+  Pipe(int readFd, int writeFd) : m_readFd{readFd}, m_writeFd{writeFd} {}
+  Pipe(const Pipe&) = delete;
+  Pipe& operator=(const Pipe&) = delete;
+  Pipe& operator=(const Pipe&&) = delete;
+
+ public:
+  Pipe(Pipe&& rval) noexcept {
+    m_readFd = rval.m_readFd;
+    m_writeFd = rval.m_writeFd;
+    rval.m_readFd = 0;
+    rval.m_writeFd = 0;
+  }
+  ~Pipe() {
+    if (m_readFd) close(m_readFd);
+    if (m_writeFd) close(m_writeFd);
+  }
+  void signal() {
+    bool val = true;
+    int error = write(m_writeFd, &val, sizeof(val));
+    ASSERT(error >= 0);
+  };
+  void wait() {
+    bool val = false;
+    int error = read(m_readFd, &val, sizeof(val));
+    ASSERT(error >= 0);
+  }
+  template <typename T>
+  void send(const T& v) {
+    int error = write(m_writeFd, &v, sizeof(T));
+    ASSERT(error >= 0);
+  }
+  template <typename T>
+  void recv(T& v) {
+    int error = read(m_readFd, &v, sizeof(T));
+    ASSERT(error >= 0);
+  }
+  static tuple<Pipe, Pipe> createPipePair() {
+    int a[2];
+    int b[2];
+
+    int error1 = pipe(a);
+    int error2 = pipe(b);
+    ASSERT(error1 >= 0);
+    ASSERT(error2 >= 0);
+
+    return make_tuple(Pipe(a[0], b[1]), Pipe(b[0], a[1]));
+  }
+};
+
+typedef chrono::time_point<chrono::high_resolution_clock> Tick;
+
+static inline Tick tickNow() { return chrono::high_resolution_clock::now(); }
+
+static inline uint64_t tickNano(Tick& sta, Tick& end) {
+  return uint64_t(
+      chrono::duration_cast<chrono::nanoseconds>(end - sta).count());
+}
+
+struct Results {
+  uint64_t m_best = 0xffffffffffffffffULL;
+  uint64_t m_worst = 0;
+  uint64_t m_transactions = 0;
+  uint64_t m_total_time = 0;
+  uint64_t m_miss = 0;
+  bool tracing;
+  Results(bool _tracing) : tracing(_tracing) {}
+  inline bool miss_deadline(uint64_t nano) { return nano > deadline_us * 1000; }
+  void add_time(uint64_t nano) {
+    m_best = min(nano, m_best);
+    m_worst = max(nano, m_worst);
+    m_transactions += 1;
+    m_total_time += nano;
+    if (miss_deadline(nano)) m_miss++;
+    if (miss_deadline(nano) && tracing) {
+      // There might be multiple process pair running the test concurrently
+      // each may execute following statements and only the first one actually
+      // stop the trace and any traceStop() afterthen has no effect.
+      traceStop();
+      cout << endl;
+      cout << "deadline triggered: halt & stop trace" << endl;
+      cout << "log:" + trace_path + "/trace" << endl;
+      cout << endl;
+      exit(1);
+    }
+  }
+  void dump() {
+    double best = (double)m_best / 1.0E6;
+    double worst = (double)m_worst / 1.0E6;
+    double average = (double)m_total_time / m_transactions / 1.0E6;
+    int W = DUMP_PRICISION + 2;
+    cout << std::setprecision(DUMP_PRICISION) << "{ \"avg\":" << setw(W) << left
+         << average << ", \"wst\":" << setw(W) << left << worst
+         << ", \"bst\":" << setw(W) << left << best << ", \"miss\":" << left
+         << m_miss << ", \"meetR\":" << setprecision(DUMP_PRICISION + 3) << left
+         << (1.0 - (double)m_miss / m_transactions) << "}";
+  }
+};
+
+static string generateServiceName(int num) {
+  string serviceName = "hwbinderService" + to_string(num);
+  return serviceName;
+}
+
+// This private struct is used to pass the argument to threadStart
+// result: a pointer to Results
+// target: the terget service number
+typedef struct {
+  void* result;
+  int target;
+} thread_priv_t;
+
+static void* threadStart(void* p) {
+  thread_priv_t* priv = (thread_priv_t*)p;
+  int target = priv->target;
+  Results* results_fifo = (Results*)priv->result;
+  Tick sta, end;
+
+  threadDump("fifo-caller");
+  uint32_t call_sta = (threadPri() << 16) | sched_getcpu();
+  sp<IScheduleTest> service = services[target];
+  sta = tickNow();
+  uint32_t ret = service->send(verbose, call_sta);
+  end = tickNow();
+  results_fifo->add_time(tickNano(sta, end));
+
+  no_inherent += (ret >> 16) & 0xffff;
+  no_sync += ret & 0xffff;
+  return 0;
+}
+
+// create a fifo thread to transact and wait it to finished
+static void threadTransaction(int target, Results* results_fifo) {
+  thread_priv_t thread_priv;
+
+  void* dummy;
+  pthread_t thread;
+  pthread_attr_t attr;
+  struct sched_param param;
+  thread_priv.target = target;
+  thread_priv.result = results_fifo;
+  ASSERT(!pthread_attr_init(&attr));
+  ASSERT(!pthread_attr_setschedpolicy(&attr, SCHED_FIFO));
+  param.sched_priority = sched_get_priority_max(SCHED_FIFO);
+  ASSERT(!pthread_attr_setschedparam(&attr, &param));
+  ASSERT(!pthread_create(&thread, &attr, threadStart, &thread_priv));
+  ASSERT(!pthread_join(thread, &dummy));
+}
+
+static void serviceFx(const string& serviceName, Pipe p) {
+  // Start service.
+  sp<IScheduleTest> server = IScheduleTest::getService(serviceName, true);
+  status_t status = server->registerAsService(serviceName);
+  if (status != ::android::OK) {
+    cout << "Failed to register service " << serviceName.c_str() << endl;
+    exit(EXIT_FAILURE);
+  }
+  // tell main I'm init-ed
+  p.signal();
+  // wait for kill
+  p.wait();
+  exit(EXIT_SUCCESS);
+}
+
+static Pipe makeServiceProces(string service_name) {
+  auto pipe_pair = Pipe::createPipePair();
+  pid_t pid = fork();
+  if (pid) {
+    // parent
+    return move(get<0>(pipe_pair));
+  } else {
+    threadDump("service");
+    // child
+    serviceFx(service_name, move(get<1>(pipe_pair)));
+    // never get here
+    ASSERT(0);
+    return move(get<0>(pipe_pair));
+  }
+}
+
+static void clientFx(int num, int server_count, int iterations, Pipe p) {
+  Results results_other(false), results_fifo(trace);
+
+  for (int i = 0; i < server_count; i++) {
+    sp<IScheduleTest> service =
+        IScheduleTest::getService(generateServiceName(i), pass_through);
+    ASSERT(service != nullptr);
+    if (pass_through) {
+      ASSERT(!service->isRemote());
+    } else {
+      ASSERT(service->isRemote());
+    }
+    services.push_back(service);
+  }
+  // tell main I'm init-ed
+  p.signal();
+  // wait for kick-off
+  p.wait();
+
+  // Client for each pair iterates here
+  // each iterations contains exatcly 2 transactions
+  for (int i = 0; i < iterations; i++) {
+    Tick sta, end;
+    // the target is paired to make it easier to diagnose
+    int target = num;
+
+    // 1. transaction by fifo thread
+    threadTransaction(target, &results_fifo);
+    threadDump("other-caller");
+
+    uint32_t call_sta = (threadPri() << 16) | sched_getcpu();
+    sp<IScheduleTest> service = services[target];
+    // 2. transaction by other thread
+    sta = tickNow();
+    uint32_t ret = service->send(verbose, call_sta);
+    end = tickNow();
+    results_other.add_time(tickNano(sta, end));
+    no_inherent += (ret >> 16) & 0xffff;
+    no_sync += ret & 0xffff;
+  }
+  // tell main i'm done
+  p.signal();
+  // wait for kill
+  p.wait();
+  // Client for each pair dump here
+  int no_trans = iterations * 2;
+  double sync_ratio = (1.0 - (double)no_sync / no_trans);
+  cout << "\"P" << num << "\":{\"SYNC\":\""
+       << ((sync_ratio > GOOD_SYNC_MIN) ? "GOOD" : "POOR") << "\","
+       << "\"S\":" << (no_trans - no_sync) << ",\"I\":" << no_trans << ","
+       << "\"R\":" << sync_ratio << "," << endl;
+
+  cout << "  \"other_ms\":";
+  results_other.dump();
+  cout << "," << endl;
+  cout << "  \"fifo_ms\": ";
+  results_fifo.dump();
+  cout << endl;
+  cout << "}," << endl;
+  exit(no_inherent);
+}
+
+static Pipe makeClientProcess(int num, int iterations, int no_pair) {
+  auto pipe_pair = Pipe::createPipePair();
+  pid_t pid = fork();
+  if (pid) {
+    // parent
+    return move(get<0>(pipe_pair));
+  } else {
+    // child
+    threadDump("client");
+    clientFx(num, no_pair, iterations, move(get<1>(pipe_pair)));
+    // never get here
+    ASSERT(0);
+    return move(get<0>(pipe_pair));
+  }
+}
+
+static void waitAll(vector<Pipe>& v) {
+  for (size_t i = 0; i < v.size(); i++) {
+    v[i].wait();
+  }
+}
+
+static void signalAll(vector<Pipe>& v) {
+  for (size_t i = 0; i < v.size(); i++) {
+    v[i].signal();
+  }
+}
+
+// This test is modified from frameworks/native/libs/binder/tests/sch-dbg.cpp
+// The difference is sch-dbg tests binder transaction and this one test
+// HwBinder transaction.
+int main(int argc, char** argv) {
+  vector<Pipe> client_pipes;
+  vector<Pipe> service_pipes;
+
+  for (int i = 1; i < argc; i++) {
+    if (string(argv[i]) == "-passthrough") {
+      pass_through = true;
+    }
+    if (string(argv[i]) == "-i") {
+      iterations = atoi(argv[i + 1]);
+      i++;
+      continue;
+    }
+    if (string(argv[i]) == "-pair") {
+      no_pair = atoi(argv[i + 1]);
+      i++;
+      continue;
+    }
+    if (string(argv[i]) == "-deadline_us") {
+      deadline_us = atoi(argv[i + 1]);
+      i++;
+      continue;
+    }
+    if (string(argv[i]) == "-v") {
+      verbose = 1;
+    }
+    // The -trace argument is used like that:
+    //
+    // First start trace with atrace command as usual
+    // >atrace --async_start sched freq
+    //
+    // then use the -trace arguments like
+    // -trace -deadline_us 2500
+    //
+    // This makes the program to stop trace once it detects a transaction
+    // duration over the deadline. By writing '0' to
+    // /sys/kernel/debug/tracing and halt the process. The tracelog is
+    // then available on /sys/kernel/debug/trace
+    if (string(argv[i]) == "-trace") {
+      trace = 1;
+    }
+  }
+  if (!pass_through) {
+    // Create services.
+    for (int i = 0; i < no_pair; i++) {
+      string serviceName = generateServiceName(i);
+      service_pipes.push_back(makeServiceProces(serviceName));
+    }
+    // Wait until all services are up.
+    waitAll(service_pipes);
+  }
+  if (trace && !traceIsOn()) {
+    cout << "trace is not running" << endl;
+    cout << "check " << trace_path + "/tracing_on" << endl;
+    cout << "use atrace --async_start first" << endl;
+    exit(-1);
+  }
+  threadDump("main");
+  cout << "{" << endl;
+  cout << "\"cfg\":{\"pair\":" << (no_pair) << ",\"iterations\":" << iterations
+       << ",\"deadline_us\":" << deadline_us << "}," << endl;
+
+  // the main process fork 2 processes for each pairs
+  // 1 server + 1 client
+  // each has a pipe to communicate with
+  for (int i = 0; i < no_pair; i++) {
+    client_pipes.push_back(makeClientProcess(i, iterations, no_pair));
+  }
+  // wait client to init
+  waitAll(client_pipes);
+
+  // kick off clients
+  signalAll(client_pipes);
+
+  // wait client to finished
+  waitAll(client_pipes);
+
+  if (!pass_through) {
+    // Kill all the services.
+    for (int i = 0; i < no_pair; i++) {
+      int status;
+      service_pipes[i].signal();
+      wait(&status);
+      if (status != 0) {
+        cout << "nonzero child status" << status << endl;
+      }
+    }
+  }
+  for (int i = 0; i < no_pair; i++) {
+    int status;
+    client_pipes[i].signal();
+    wait(&status);
+    // the exit status is number of transactions without priority inheritance
+    // detected in the child process
+    no_inherent += status;
+  }
+  cout << "\"inheritance\": " << (no_inherent == 0 ? "\"PASS\"" : "\"FAIL\"")
+       << endl;
+  cout << "}" << endl;
+  return -no_inherent;
+}
