Merge "Output duration of ftrace as well as total trace duration."
diff --git a/include/perfetto/base/export.h b/include/perfetto/base/export.h
index 9338b36..15497e0 100644
--- a/include/perfetto/base/export.h
+++ b/include/perfetto/base/export.h
@@ -17,14 +17,28 @@
 #ifndef INCLUDE_PERFETTO_BASE_EXPORT_H_
 #define INCLUDE_PERFETTO_BASE_EXPORT_H_
 
+#include "perfetto/base/build_config.h"
+
 #if defined(PERFETTO_SHARED_LIBRARY)
 
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
+#if defined(PERFETTO_IMPLEMENTATION)
+#define PERFETTO_EXPORT __declspec(dllexport)
+#else
+#define PERFETTO_EXPORT __declspec(dllimport)
+#endif
+
+#else  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
 #if defined(PERFETTO_IMPLEMENTATION)
 #define PERFETTO_EXPORT __attribute__((visibility("default")))
 #else
 #define PERFETTO_EXPORT
 #endif
 
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+
 #else  // defined(PERFETTO_SHARED_LIBRARY)
 
 #define PERFETTO_EXPORT
diff --git a/include/perfetto/tracing/core/service.h b/include/perfetto/tracing/core/service.h
index 36bfc9f..e91cba0 100644
--- a/include/perfetto/tracing/core/service.h
+++ b/include/perfetto/tracing/core/service.h
@@ -62,7 +62,7 @@
   //    the ConnectProducer() method.
   // 2. The transport layer (e.g., src/ipc) when the producer and
   //    the service don't talk locally but via some IPC mechanism.
-  class ProducerEndpoint {
+  class PERFETTO_EXPORT ProducerEndpoint {
    public:
     virtual ~ProducerEndpoint();
 
diff --git a/include/perfetto/tracing/core/shared_memory.h b/include/perfetto/tracing/core/shared_memory.h
index 39c98fc..b2ca791 100644
--- a/include/perfetto/tracing/core/shared_memory.h
+++ b/include/perfetto/tracing/core/shared_memory.h
@@ -34,7 +34,7 @@
 // will attach platform specific fields to it (e.g., a unix file descriptor).
 class PERFETTO_EXPORT SharedMemory {
  public:
-  class Factory {
+  class PERFETTO_EXPORT Factory {
    public:
     virtual ~Factory();
     virtual std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) = 0;
diff --git a/ui/bs-config.js b/ui/bs-config.js
new file mode 100644
index 0000000..f328b98
--- /dev/null
+++ b/ui/bs-config.js
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+/**
+ * Configuration file for lite-server. Contains configuration for auto rerunning
+ * ninja on file change.
+ */
+'use strict';
+
+const { spawn } = require('child_process');
+
+// Print without added new line.
+const print = data => process.stdout.write(data);
+const printErr = data => process.stderr.write(data);
+
+const ninjaOutDir = process.env.NINJA_OUT_DIR;
+let ninjaRunning = false;
+
+module.exports = function(bs) {
+  return {
+    files: [
+      {
+        match: ["ui/**", "src/trace_processor/**", "protos/**"],
+        fn: function(event, file) {
+          console.log(`Change detected on ${file}`);
+          if (ninjaRunning) {
+            console.log("Already have a ninja build running. Doing nothing.");
+            return;
+          }
+
+          ninjaRunning = true;
+
+          console.log(`Executing: ninja -C ${ninjaOutDir} ui`);
+          const ninja = spawn('ninja', ['-C', ninjaOutDir, 'ui']);
+          ninja.stdout.on('data', data => print(data.toString()));
+          ninja.stderr.on('data', data => printErr(data.toString()));
+
+          // We can be smarter and load just the file we need. Need to
+          // resolve to the dist/location of the file in that case.
+          // For now, we're reloading the whole page.
+          ninja.on('exit', () => {
+            ninjaRunning = false;
+            bs.reload();
+          });
+        },
+        options: {
+          ignored: ["ui/dist/", "ui/.git/", "ui/node_modules/"],
+          ignoreInitial: true
+        }
+      }
+    ],
+    server: {
+      baseDir: "ui/dist"
+    },
+  };
+};
diff --git a/ui/run-dev-server b/ui/run-dev-server
index bc081e7..465bd76 100755
--- a/ui/run-dev-server
+++ b/ui/run-dev-server
@@ -14,6 +14,8 @@
 # limitations under the License.
 
 CUR_DIR="$(cd -P ${BASH_SOURCE[0]%/*}; pwd)"
+NINJA_OUT_DIR=$(cd $CUR_DIR/$(dirname $(readlink $CUR_DIR/dist)); pwd)
+
 LITE_SERVER="$CUR_DIR/node_modules/.bin/lite-server"
 if [ ! -f "$LITE_SERVER" ]; then
   echo "ERROR: cannot find lite-server. You need to run:"
@@ -27,5 +29,6 @@
 fi
 
 export PATH="$CUR_DIR/../buildtools/nodejs/bin/:$PATH"
-cd "$CUR_DIR/dist"
-exec node node_modules/.bin/lite-server
+cd "$CUR_DIR/../"
+NINJA_OUT_DIR="$NINJA_OUT_DIR" \
+    node ui/node_modules/.bin/lite-server -c ui/bs-config.js