Merge "Add API usage example for the Android tree"
diff --git a/Android.bp b/Android.bp
index 320e7af..83da02a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -404,6 +404,149 @@
   ],
 }
 
+// GN target: //:libperfetto_client_experimental
+cc_library_static {
+  name: "libperfetto_client_experimental",
+  srcs: [
+    ":perfetto_protos_perfetto_common_lite_gen",
+    ":perfetto_protos_perfetto_common_zero_gen",
+    ":perfetto_protos_perfetto_config_lite_gen",
+    ":perfetto_protos_perfetto_config_zero_gen",
+    ":perfetto_protos_perfetto_ipc_ipc_gen",
+    ":perfetto_protos_perfetto_trace_android_zero_gen",
+    ":perfetto_protos_perfetto_trace_chrome_zero_gen",
+    ":perfetto_protos_perfetto_trace_filesystem_zero_gen",
+    ":perfetto_protos_perfetto_trace_ftrace_zero_gen",
+    ":perfetto_protos_perfetto_trace_interned_data_zero_gen",
+    ":perfetto_protos_perfetto_trace_minimal_lite_gen",
+    ":perfetto_protos_perfetto_trace_power_zero_gen",
+    ":perfetto_protos_perfetto_trace_profiling_zero_gen",
+    ":perfetto_protos_perfetto_trace_ps_zero_gen",
+    ":perfetto_protos_perfetto_trace_sys_stats_zero_gen",
+    ":perfetto_protos_perfetto_trace_track_event_zero_gen",
+    ":perfetto_protos_perfetto_trace_trusted_lite_gen",
+    ":perfetto_protos_perfetto_trace_zero_gen",
+    ":perfetto_src_ipc_wire_protocol_gen",
+    "src/base/event.cc",
+    "src/base/file_utils.cc",
+    "src/base/metatrace.cc",
+    "src/base/paged_memory.cc",
+    "src/base/pipe.cc",
+    "src/base/string_splitter.cc",
+    "src/base/string_utils.cc",
+    "src/base/string_view.cc",
+    "src/base/temp_file.cc",
+    "src/base/thread_checker.cc",
+    "src/base/thread_task_runner.cc",
+    "src/base/time.cc",
+    "src/base/unix_socket.cc",
+    "src/base/unix_task_runner.cc",
+    "src/base/virtual_destructors.cc",
+    "src/base/watchdog_posix.cc",
+    "src/ipc/buffered_frame_deserializer.cc",
+    "src/ipc/client_impl.cc",
+    "src/ipc/deferred.cc",
+    "src/ipc/host_impl.cc",
+    "src/ipc/service_proxy.cc",
+    "src/ipc/virtual_destructors.cc",
+    "src/protozero/message.cc",
+    "src/protozero/message_handle.cc",
+    "src/protozero/proto_decoder.cc",
+    "src/protozero/scattered_heap_buffer.cc",
+    "src/protozero/scattered_stream_null_delegate.cc",
+    "src/protozero/scattered_stream_writer.cc",
+    "src/tracing/core/chrome_config.cc",
+    "src/tracing/core/commit_data_request.cc",
+    "src/tracing/core/data_source_config.cc",
+    "src/tracing/core/data_source_descriptor.cc",
+    "src/tracing/core/id_allocator.cc",
+    "src/tracing/core/null_trace_writer.cc",
+    "src/tracing/core/observable_events.cc",
+    "src/tracing/core/packet_stream_validator.cc",
+    "src/tracing/core/shared_memory_abi.cc",
+    "src/tracing/core/shared_memory_arbiter_impl.cc",
+    "src/tracing/core/sliced_protobuf_input_stream.cc",
+    "src/tracing/core/startup_trace_writer.cc",
+    "src/tracing/core/startup_trace_writer_registry.cc",
+    "src/tracing/core/test_config.cc",
+    "src/tracing/core/trace_buffer.cc",
+    "src/tracing/core/trace_config.cc",
+    "src/tracing/core/trace_packet.cc",
+    "src/tracing/core/trace_stats.cc",
+    "src/tracing/core/trace_writer_impl.cc",
+    "src/tracing/core/tracing_service_impl.cc",
+    "src/tracing/core/virtual_destructors.cc",
+    "src/tracing/data_source.cc",
+    "src/tracing/internal/in_process_tracing_backend.cc",
+    "src/tracing/internal/system_tracing_backend.cc",
+    "src/tracing/internal/tracing_muxer_impl.cc",
+    "src/tracing/platform.cc",
+    "src/tracing/platform_posix.cc",
+    "src/tracing/trace_writer_base.cc",
+    "src/tracing/tracing.cc",
+    "src/tracing/virtual_destructors.cc",
+  ],
+  shared_libs: [
+    "libprotobuf-cpp-lite",
+  ],
+  static_libs: [
+    "perfetto_src_tracing_ipc",
+  ],
+  export_include_dirs: [
+    "include",
+  ],
+  generated_headers: [
+    "perfetto_protos_perfetto_common_lite_gen_headers",
+    "perfetto_protos_perfetto_common_zero_gen_headers",
+    "perfetto_protos_perfetto_config_lite_gen_headers",
+    "perfetto_protos_perfetto_config_zero_gen_headers",
+    "perfetto_protos_perfetto_ipc_ipc_gen_headers",
+    "perfetto_protos_perfetto_trace_android_zero_gen_headers",
+    "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+    "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
+    "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
+    "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
+    "perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
+    "perfetto_protos_perfetto_trace_power_zero_gen_headers",
+    "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
+    "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+    "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
+    "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
+    "perfetto_protos_perfetto_trace_trusted_lite_gen_headers",
+    "perfetto_protos_perfetto_trace_zero_gen_headers",
+    "perfetto_src_ipc_wire_protocol_gen_headers",
+  ],
+  export_generated_headers: [
+    "perfetto_protos_perfetto_common_lite_gen_headers",
+    "perfetto_protos_perfetto_common_zero_gen_headers",
+    "perfetto_protos_perfetto_config_lite_gen_headers",
+    "perfetto_protos_perfetto_config_zero_gen_headers",
+    "perfetto_protos_perfetto_ipc_ipc_gen_headers",
+    "perfetto_protos_perfetto_trace_android_zero_gen_headers",
+    "perfetto_protos_perfetto_trace_chrome_zero_gen_headers",
+    "perfetto_protos_perfetto_trace_filesystem_zero_gen_headers",
+    "perfetto_protos_perfetto_trace_ftrace_zero_gen_headers",
+    "perfetto_protos_perfetto_trace_interned_data_zero_gen_headers",
+    "perfetto_protos_perfetto_trace_minimal_lite_gen_headers",
+    "perfetto_protos_perfetto_trace_power_zero_gen_headers",
+    "perfetto_protos_perfetto_trace_profiling_zero_gen_headers",
+    "perfetto_protos_perfetto_trace_ps_zero_gen_headers",
+    "perfetto_protos_perfetto_trace_sys_stats_zero_gen_headers",
+    "perfetto_protos_perfetto_trace_track_event_zero_gen_headers",
+    "perfetto_protos_perfetto_trace_trusted_lite_gen_headers",
+    "perfetto_protos_perfetto_trace_zero_gen_headers",
+    "perfetto_src_ipc_wire_protocol_gen_headers",
+  ],
+  defaults: [
+    "perfetto_defaults",
+  ],
+  cflags: [
+    "-DGOOGLE_PROTOBUF_NO_RTTI",
+    "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+    "-DPERFETTO_BUILD_WITH_ANDROID",
+  ],
+}
+
 // GN target: //:perfetto
 cc_binary {
   name: "perfetto",
@@ -3598,4 +3741,30 @@
   srcs: [
     "protos/perfetto/config/perfetto_config.proto",
   ],
+}
+
+// This sample target shows how to use the perfetto client API from within the
+// Android tree.
+cc_binary {
+  name: "libperfetto_client_example",
+  srcs: [
+    "test/android_client_api_example.cc",
+  ],
+  static_libs: [
+    "libperfetto_client_experimental",
+    "perfetto_src_tracing_ipc",
+    "perfetto_trace_protos",
+  ],
+  shared_libs: [
+    "libprotobuf-cpp-lite",
+    "liblog",
+  ],
+  local_include_dirs: [
+    "include",
+  ],
+  cflags: [
+    "-DGOOGLE_PROTOBUF_NO_RTTI",
+    "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+    "-DPERFETTO_BUILD_WITH_ANDROID",
+  ],
 }
\ No newline at end of file
diff --git a/Android.bp.extras b/Android.bp.extras
index 84c0f10..54de0c9 100644
--- a/Android.bp.extras
+++ b/Android.bp.extras
@@ -64,3 +64,29 @@
     "protos/perfetto/config/perfetto_config.proto",
   ],
 }
+
+// This sample target shows how to use the perfetto client API from within the
+// Android tree.
+cc_binary {
+  name: "libperfetto_client_example",
+  srcs: [
+    "test/android_client_api_example.cc",
+  ],
+  static_libs: [
+    "libperfetto_client_experimental",
+    "perfetto_src_tracing_ipc",
+    "perfetto_trace_protos",
+  ],
+  shared_libs: [
+    "libprotobuf-cpp-lite",
+    "liblog",
+  ],
+  local_include_dirs: [
+    "include",
+  ],
+  cflags: [
+    "-DGOOGLE_PROTOBUF_NO_RTTI",
+    "-DGOOGLE_PROTOBUF_NO_STATIC_INITIALIZER",
+    "-DPERFETTO_BUILD_WITH_ANDROID",
+  ],
+}
diff --git a/BUILD.gn b/BUILD.gn
index 54b73b6..e28ab12 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -271,6 +271,19 @@
         "src/android_internal",
       ]
     }
+
+    # Client library target for the Android tree.
+    # Still in experimental stage and not API stable yet.
+    # See "libperfetto_client_example" (in Android.bp.extras) for an example
+    # on how to use the Perfetto Client API from the android tree.
+    static_library("libperfetto_client_experimental") {
+      complete_static_lib = true
+      deps = [
+        "gn:default_deps",
+        "src/tracing:client_api",
+        "src/tracing:platform_posix",
+      ]
+    }
   }  # if (perfetto_build_with_android)
 }  # if (perfetto_build_standalone || perfetto_build_with_android)
 
diff --git a/include/perfetto/tracing.h b/include/perfetto/tracing.h
index 6e0abef..3dfb88a 100644
--- a/include/perfetto/tracing.h
+++ b/include/perfetto/tracing.h
@@ -28,4 +28,9 @@
 #include "perfetto/tracing/tracing.h"
 #include "perfetto/tracing/tracing_backend.h"
 
+// TODO(primiano): move these generated classes from /ext/ into public. Right
+// now these are a layering violation.
+#include "perfetto/ext/tracing/core/data_source_descriptor.h"  // nogncheck
+#include "perfetto/ext/tracing/core/trace_config.h"            // nogncheck
+
 #endif  // INCLUDE_PERFETTO_TRACING_H_
diff --git a/test/android_client_api_example.cc b/test/android_client_api_example.cc
new file mode 100644
index 0000000..459dd5f
--- /dev/null
+++ b/test/android_client_api_example.cc
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2019 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 "perfetto/tracing.h"
+
+#include "perfetto/trace/test_event.pbzero.h"
+#include "perfetto/trace/trace.pb.h"
+#include "perfetto/trace/trace_packet.pbzero.h"
+
+// Deliberately not pulling any non-public perfetto header to spot accidental
+// header public -> non-public dependency while building this file.
+
+class MyDataSource : public perfetto::DataSource<MyDataSource> {
+ public:
+  void OnSetup(const SetupArgs& args) override {
+    // This can be used to access the domain-specific DataSourceConfig, via
+    // args.config->xxx_config_raw().
+    PERFETTO_ILOG("OnSetup called, name: %s", args.config->name().c_str());
+  }
+
+  void OnStart(const StartArgs&) override { PERFETTO_ILOG("OnStart called"); }
+
+  void OnStop(const StopArgs&) override { PERFETTO_ILOG("OnStop called"); }
+};
+
+PERFETTO_DEFINE_DATA_SOURCE_STATIC_MEMBERS(MyDataSource);
+
+int main() {
+  perfetto::TracingInitArgs args;
+  args.backends = perfetto::kSystemBackend;
+  perfetto::Tracing::Initialize(args);
+
+  // DataSourceDescriptor can be used to advertise domain-specific features.
+  perfetto::DataSourceDescriptor dsd;
+  dsd.set_name("com.example.mytrace");
+  MyDataSource::Register(dsd);
+
+  for (;;) {
+    MyDataSource::Trace([](MyDataSource::TraceContext ctx) {
+      PERFETTO_LOG("Tracing lambda called");
+      auto packet = ctx.NewTracePacket();
+      packet->set_timestamp(42);
+      packet->set_for_testing()->set_str("event 1");
+    });
+    sleep(1);
+  }
+}
diff --git a/tools/check_include_violations b/tools/check_include_violations
index 5e05b86..82e36ab 100755
--- a/tools/check_include_violations
+++ b/tools/check_include_violations
@@ -26,16 +26,6 @@
 
 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 
-# TODO(primiano): fix violation from protozero -> base/logging.h .
-WHITELIST = [('include/perfetto/protozero/.*', 'perfetto/ext/base/logging.h')]
-
-
-def whitelisted(rel_path, incl):
-  for path_regex, incl_regex in WHITELIST:
-    if re.match(path_regex, rel_path) and re.match(incl_regex, incl):
-      return True
-  return False
-
 
 def main():
   errors = 0
@@ -69,10 +59,13 @@
             errors += 1
             continue
 
+          # Ignore lines marked with nogncheck.
+          if '// nogncheck' in line:
+            continue
+
           # Public (non-/ext/) headers cannot include /ext/ headers.
           if (not rel_path.startswith('include/perfetto/ext/') and
-                  incl.startswith('perfetto/ext/') and
-                  not whitelisted(rel_path, incl)):
+                  incl.startswith('perfetto/ext/')):
             sys.stderr.write(('Public header %s cannot include the non-public' +
                               '/ext/ header %s.\n') % (rel_path, incl))
             errors += 1
diff --git a/tools/gen_android_bp b/tools/gen_android_bp
index 4118f94..45b7ff3 100755
--- a/tools/gen_android_bp
+++ b/tools/gen_android_bp
@@ -36,6 +36,7 @@
 # Default targets to translate to the blueprint file.
 default_targets = [
     '//:libperfetto',
+    '//:libperfetto_client_experimental',
     '//:libperfetto_android_internal',
     '//:perfetto_integrationtests',
     '//:perfetto_trace_protos',