Reland: Reland: Add statsd logging to perfetto_cmd

This reverts commit 64f2e052525af1d1c06eb5eea7348346db6c0819.

Reason for revert: Required code is present in aosp as of aosp/1181211

Change-Id: I3747992a319cdd7a0b8c225fa2c916fe60e06c1f
diff --git a/Android.bp b/Android.bp
index 635cfab..30779ac 100644
--- a/Android.bp
+++ b/Android.bp
@@ -299,6 +299,7 @@
     ":perfetto_src_base_base",
     ":perfetto_src_base_unix_socket",
     ":perfetto_src_ipc_ipc",
+    ":perfetto_src_perfetto_cmd_perfetto_atoms",
     ":perfetto_src_protozero_protozero",
     ":perfetto_src_traced_probes_android_log_android_log",
     ":perfetto_src_traced_probes_data_source",
@@ -380,6 +381,7 @@
   srcs: [
     ":perfetto_src_android_internal_android_internal",
     ":perfetto_src_android_internal_headers",
+    ":perfetto_src_perfetto_cmd_perfetto_atoms",
   ],
   shared_libs: [
     "android.hardware.atrace@1.0",
@@ -387,14 +389,17 @@
     "android.hardware.power.stats@1.0",
     "libbase",
     "libbinder",
+    "libcutils",
     "libhidlbase",
     "libincident",
     "liblog",
     "libservices",
+    "libstatssocket",
     "libutils",
   ],
   static_libs: [
     "libhealthhalutils",
+    "libstatslog_perfetto",
   ],
   export_include_dirs: [
     "include",
@@ -617,6 +622,7 @@
     ":perfetto_src_base_base",
     ":perfetto_src_base_unix_socket",
     ":perfetto_src_ipc_ipc",
+    ":perfetto_src_perfetto_cmd_perfetto_atoms",
     ":perfetto_src_perfetto_cmd_perfetto_cmd",
     ":perfetto_src_perfetto_cmd_protos_gen",
     ":perfetto_src_perfetto_cmd_trigger_producer",
@@ -883,6 +889,7 @@
     ":perfetto_src_base_test_support",
     ":perfetto_src_base_unix_socket",
     ":perfetto_src_ipc_ipc",
+    ":perfetto_src_perfetto_cmd_perfetto_atoms",
     ":perfetto_src_profiling_memory_client",
     ":perfetto_src_profiling_memory_daemon",
     ":perfetto_src_profiling_memory_end_to_end_tests",
@@ -4024,6 +4031,7 @@
     "src/android_internal/health_hal.cc",
     "src/android_internal/incident_service.cc",
     "src/android_internal/power_stats_hal.cc",
+    "src/android_internal/statsd_logging.cc",
   ],
 }
 
@@ -4222,6 +4230,11 @@
   ],
 }
 
+// GN: //src/perfetto_cmd:perfetto_atoms
+filegroup {
+  name: "perfetto_src_perfetto_cmd_perfetto_atoms",
+}
+
 // GN: //src/perfetto_cmd:perfetto_cmd
 filegroup {
   name: "perfetto_src_perfetto_cmd_perfetto_cmd",
@@ -5539,6 +5552,7 @@
     ":perfetto_src_ipc_test_messages_cpp_gen",
     ":perfetto_src_ipc_test_messages_ipc_gen",
     ":perfetto_src_ipc_unittests",
+    ":perfetto_src_perfetto_cmd_perfetto_atoms",
     ":perfetto_src_perfetto_cmd_perfetto_cmd",
     ":perfetto_src_perfetto_cmd_protos_gen",
     ":perfetto_src_perfetto_cmd_trigger_producer",
@@ -6299,4 +6313,39 @@
   defaults: [
     "perfetto_defaults",
   ],
+}
+
+cc_library_static {
+    name: "libstatslog_perfetto",
+    generated_sources: ["statslog_perfetto.cpp"],
+    generated_headers: ["statslog_perfetto.h"],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    export_generated_headers: ["statslog_perfetto.h"],
+    shared_libs: [
+        "libcutils",
+        "liblog",
+        "libstatssocket",
+        "libutils",
+    ],
+}
+
+genrule {
+    name: "statslog_perfetto.h",
+    tools: ["stats-log-api-gen"],
+    cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_perfetto.h --module perfetto --namespace perfetto,android_internal",
+    out: [
+        "statslog_perfetto.h",
+    ],
+}
+
+genrule {
+    name: "statslog_perfetto.cpp",
+    tools: ["stats-log-api-gen"],
+    cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog_perfetto.cpp --module perfetto --namespace perfetto,android_internal --importHeader statslog_perfetto.h",
+    out: [
+        "statslog_perfetto.cpp",
+    ],
 }
\ No newline at end of file
diff --git a/Android.bp.extras b/Android.bp.extras
index ef14e45..6011886 100644
--- a/Android.bp.extras
+++ b/Android.bp.extras
@@ -83,3 +83,38 @@
     "perfetto_defaults",
   ],
 }
+
+cc_library_static {
+    name: "libstatslog_perfetto",
+    generated_sources: ["statslog_perfetto.cpp"],
+    generated_headers: ["statslog_perfetto.h"],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    export_generated_headers: ["statslog_perfetto.h"],
+    shared_libs: [
+        "libcutils",
+        "liblog",
+        "libstatssocket",
+        "libutils",
+    ],
+}
+
+genrule {
+    name: "statslog_perfetto.h",
+    tools: ["stats-log-api-gen"],
+    cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_perfetto.h --module perfetto --namespace perfetto,android_internal",
+    out: [
+        "statslog_perfetto.h",
+    ],
+}
+
+genrule {
+    name: "statslog_perfetto.cpp",
+    tools: ["stats-log-api-gen"],
+    cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog_perfetto.cpp --module perfetto --namespace perfetto,android_internal --importHeader statslog_perfetto.h",
+    out: [
+        "statslog_perfetto.cpp",
+    ],
+}
diff --git a/BUILD b/BUILD
index 9f05570..36dd0f9 100644
--- a/BUILD
+++ b/BUILD
@@ -119,6 +119,7 @@
         ":src_base_base",
         ":src_base_unix_socket",
         ":src_ipc_ipc",
+        ":src_perfetto_cmd_perfetto_atoms",
         ":src_protozero_protozero",
         ":src_traced_probes_android_log_android_log",
         ":src_traced_probes_data_source",
@@ -447,6 +448,7 @@
         "src/android_internal/health_hal.h",
         "src/android_internal/incident_service.h",
         "src/android_internal/power_stats_hal.h",
+        "src/android_internal/statsd_logging.h",
     ],
 )
 
@@ -507,6 +509,14 @@
     ],
 )
 
+# GN target: //src/perfetto_cmd:perfetto_atoms
+filegroup(
+    name = "src_perfetto_cmd_perfetto_atoms",
+    srcs = [
+        "src/perfetto_cmd/perfetto_atoms.h",
+    ],
+)
+
 # GN target: //src/perfetto_cmd:perfetto_cmd
 filegroup(
     name = "src_perfetto_cmd_perfetto_cmd",
@@ -2430,6 +2440,7 @@
         ":src_base_base",
         ":src_base_unix_socket",
         ":src_ipc_ipc",
+        ":src_perfetto_cmd_perfetto_atoms",
         ":src_perfetto_cmd_perfetto_cmd",
         ":src_perfetto_cmd_trigger_producer",
         ":src_protozero_protozero",
diff --git a/include/perfetto/base/time.h b/include/perfetto/base/time.h
index b58c0ed..8c81faa 100644
--- a/include/perfetto/base/time.h
+++ b/include/perfetto/base/time.h
@@ -142,6 +142,10 @@
 
 #endif
 
+inline TimeSeconds GetBootTimeS() {
+  return std::chrono::duration_cast<TimeSeconds>(GetBootTimeNs());
+}
+
 inline TimeMillis GetWallTimeMs() {
   return std::chrono::duration_cast<TimeMillis>(GetWallTimeNs());
 }
diff --git a/src/android_internal/BUILD.gn b/src/android_internal/BUILD.gn
index 819532a..4306b16 100644
--- a/src/android_internal/BUILD.gn
+++ b/src/android_internal/BUILD.gn
@@ -26,6 +26,7 @@
 source_set("headers") {
   deps = [
     "../../gn:default_deps",
+    "../../src/perfetto_cmd:perfetto_atoms",
   ]
   sources = [
     "atrace_hal.h",
@@ -33,6 +34,7 @@
     "health_hal.h",
     "incident_service.h",
     "power_stats_hal.h",
+    "statsd_logging.h",
   ]
 }
 
@@ -66,11 +68,15 @@
       "health_hal.cc",
       "incident_service.cc",
       "power_stats_hal.cc",
+      "statsd_logging.cc",
     ]
     libs = [
       "android.hardware.health@2.0",
       "android.hardware.power.stats@1.0",
       "android.hardware.atrace@1.0",
+      "statslog_perfetto",
+      "statssocket",
+      "cutils",
       "base",
       "binder",
       "log",
diff --git a/src/android_internal/statsd_logging.cc b/src/android_internal/statsd_logging.cc
new file mode 100644
index 0000000..aa7b24b
--- /dev/null
+++ b/src/android_internal/statsd_logging.cc
@@ -0,0 +1,34 @@
+/*
+ * 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 "src/android_internal/statsd_logging.h"
+
+#include <string.h>
+
+#include <statslog_perfetto.h>
+
+namespace perfetto {
+namespace android_internal {
+
+void StatsdLogEvent(PerfettoStatsdAtom atom,
+                    int64_t uuid_lsb,
+                    int64_t uuid_msb) {
+  stats_write(PERFETTO_UPLOADED, static_cast<int32_t>(atom), uuid_lsb,
+              uuid_msb);
+}
+
+}  // namespace android_internal
+}  // namespace perfetto
diff --git a/src/android_internal/statsd_logging.h b/src/android_internal/statsd_logging.h
new file mode 100644
index 0000000..e1f9c76
--- /dev/null
+++ b/src/android_internal/statsd_logging.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#ifndef SRC_ANDROID_INTERNAL_STATSD_LOGGING_H_
+#define SRC_ANDROID_INTERNAL_STATSD_LOGGING_H_
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "src/perfetto_cmd/perfetto_atoms.h"
+
+namespace perfetto {
+namespace android_internal {
+
+extern "C" {
+
+void __attribute__((visibility("default")))
+StatsdLogEvent(PerfettoStatsdAtom atom, int64_t uuid_lsb, int64_t uuid_msb);
+
+}  // extern "C"
+
+}  // namespace android_internal
+}  // namespace perfetto
+
+#endif  // SRC_ANDROID_INTERNAL_STATSD_LOGGING_H_
diff --git a/src/perfetto_cmd/BUILD.gn b/src/perfetto_cmd/BUILD.gn
index b695f09..534cdd9 100644
--- a/src/perfetto_cmd/BUILD.gn
+++ b/src/perfetto_cmd/BUILD.gn
@@ -44,6 +44,12 @@
   ]
 }
 
+source_set("perfetto_atoms") {
+  sources = [
+    "perfetto_atoms.h",
+  ]
+}
+
 # Contains all the implementation but not the main() entry point. This target
 # is shared both by the executable and tests.
 source_set("perfetto_cmd") {
@@ -52,6 +58,7 @@
     "../../include/perfetto/ext/traced",
   ]
   deps = [
+    ":perfetto_atoms",
     ":trigger_producer",
     "../../gn:default_deps",
     "../../gn:zlib",
diff --git a/src/perfetto_cmd/perfetto_atoms.h b/src/perfetto_cmd/perfetto_atoms.h
new file mode 100644
index 0000000..35903ea
--- /dev/null
+++ b/src/perfetto_cmd/perfetto_atoms.h
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#ifndef SRC_PERFETTO_CMD_PERFETTO_ATOMS_H_
+#define SRC_PERFETTO_CMD_PERFETTO_ATOMS_H_
+
+namespace perfetto {
+
+// This must match the values of the PerfettoUploadEvent enum in:
+// frameworks/base/cmds/statsd/src/atoms.proto
+enum class PerfettoStatsdAtom {
+  kUndefined = 0,
+
+  kTraceBegin = 1,
+  kBackgroundTraceBegin = 2,
+
+  kOnConnect = 3,
+  kOnTracingDisabled = 4,
+
+  kUploadDropboxBegin = 5,
+  kUploadDropboxSuccess = 6,
+  kUploadDropboxFailure = 7,
+
+  kUploadIncidentBegin = 8,
+  kUploadIncidentSuccess = 9,
+  kUploadIncidentFailure = 10,
+
+  kFinalizeTraceAndExit = 11,
+
+  kTriggerBegin = 12,
+  kTriggerSuccess = 13,
+  kTriggerFailure = 14,
+
+  kHitGuardrails = 15,
+  kOnTimeout = 16,
+  kNotUploadingEmptyTrace = 17,
+};
+
+}  // namespace perfetto
+
+#endif  // SRC_PERFETTO_CMD_PERFETTO_ATOMS_H_
diff --git a/src/perfetto_cmd/perfetto_cmd.cc b/src/perfetto_cmd/perfetto_cmd.cc
index e504e39..614c6d5 100644
--- a/src/perfetto_cmd/perfetto_cmd.cc
+++ b/src/perfetto_cmd/perfetto_cmd.cc
@@ -33,11 +33,13 @@
 #include <iterator>
 #include <sstream>
 
+#include "perfetto/base/compiler.h"
 #include "perfetto/base/logging.h"
 #include "perfetto/base/time.h"
 #include "perfetto/ext/base/file_utils.h"
 #include "perfetto/ext/base/string_view.h"
 #include "perfetto/ext/base/utils.h"
+#include "perfetto/ext/base/uuid.h"
 #include "perfetto/ext/traced/traced.h"
 #include "perfetto/ext/tracing/core/basic_types.h"
 #include "perfetto/ext/tracing/core/trace_packet.h"
@@ -570,6 +572,7 @@
   // connect as a consumer or run the trace. So bail out after processing all
   // the options.
   if (!triggers_to_activate.empty()) {
+    LogUploadEvent(PerfettoStatsdAtom::kTriggerBegin);
     bool finished_with_success = false;
     TriggerProducer producer(
         &task_runner_,
@@ -579,6 +582,11 @@
         },
         &triggers_to_activate);
     task_runner_.Run();
+    if (finished_with_success) {
+      LogUploadEvent(PerfettoStatsdAtom::kTriggerSuccess);
+    } else {
+      LogUploadEvent(PerfettoStatsdAtom::kTriggerFailure);
+    }
     return finished_with_success ? 0 : 1;
   }
 
@@ -627,8 +635,16 @@
     expected_duration_ms_ = timeout_ms + max_stop_delay_ms;
   }
 
-  if (!limiter.ShouldTrace(args))
+  if (trace_config_->trigger_config().trigger_timeout_ms() == 0) {
+    LogUploadEvent(PerfettoStatsdAtom::kTraceBegin);
+  } else {
+    LogUploadEvent(PerfettoStatsdAtom::kBackgroundTraceBegin);
+  }
+
+  if (!limiter.ShouldTrace(args)) {
+    LogUploadEvent(PerfettoStatsdAtom::kHitGuardrails);
     return 1;
+  }
 
   consumer_endpoint_ =
       ConsumerIPCClient::Connect(GetConsumerSocket(), this, &task_runner_);
@@ -640,6 +656,7 @@
 }
 
 void PerfettoCmd::OnConnect() {
+  LogUploadEvent(PerfettoStatsdAtom::kOnConnect);
   if (query_service_) {
     consumer_endpoint_->QueryServiceState(
         [this](bool success, const TracingServiceState& svc_state) {
@@ -692,6 +709,7 @@
 
 void PerfettoCmd::OnTimeout() {
   PERFETTO_ELOG("Timed out while waiting for trace from the service, aborting");
+  LogUploadEvent(PerfettoStatsdAtom::kOnTimeout);
   task_runner_.Quit();
 }
 
@@ -719,6 +737,8 @@
 }
 
 void PerfettoCmd::OnTracingDisabled() {
+  LogUploadEvent(PerfettoStatsdAtom::kOnTracingDisabled);
+
   if (trace_config_->write_into_file()) {
     // If write_into_file == true, at this point the passed file contains
     // already all the packets.
@@ -734,6 +754,7 @@
 }
 
 void PerfettoCmd::FinalizeTraceAndExit() {
+  LogUploadEvent(PerfettoStatsdAtom::kFinalizeTraceAndExit);
   packet_writer_.reset();
 
   if (trace_out_stream_) {
@@ -893,6 +914,14 @@
 void PerfettoCmd::OnObservableEvents(
     const ObservableEvents& /*observable_events*/) {}
 
+void PerfettoCmd::LogUploadEvent(PerfettoStatsdAtom atom) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+  LogUploadEventAndroid(atom);
+#else
+  base::ignore_result(atom);
+#endif
+}
+
 int __attribute__((visibility("default")))
 PerfettoCmdMain(int argc, char** argv) {
   g_consumer_cmd = new perfetto::PerfettoCmd();
diff --git a/src/perfetto_cmd/perfetto_cmd.h b/src/perfetto_cmd/perfetto_cmd.h
index 8f1a721..b017708 100644
--- a/src/perfetto_cmd/perfetto_cmd.h
+++ b/src/perfetto_cmd/perfetto_cmd.h
@@ -28,9 +28,9 @@
 #include "perfetto/ext/base/optional.h"
 #include "perfetto/ext/base/scoped_file.h"
 #include "perfetto/ext/base/unix_task_runner.h"
-#include "perfetto/ext/base/uuid.h"
 #include "perfetto/ext/tracing/core/consumer.h"
 #include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
+#include "src/perfetto_cmd/perfetto_atoms.h"
 #include "src/perfetto_cmd/rate_limiter.h"
 
 namespace perfetto {
@@ -80,7 +80,9 @@
   void SaveTraceIntoDropboxAndIncidentOrCrash();
   void SaveOutputToDropboxOrCrash();
   void SaveOutputToIncidentTraceOrCrash();
+  void LogUploadEventAndroid(PerfettoStatsdAtom atom);
 #endif
+  void LogUploadEvent(PerfettoStatsdAtom atom);
 
   base::UnixTaskRunner task_runner_;
 
diff --git a/src/perfetto_cmd/perfetto_cmd_android.cc b/src/perfetto_cmd/perfetto_cmd_android.cc
index ee131d9..f332073 100644
--- a/src/perfetto_cmd/perfetto_cmd_android.cc
+++ b/src/perfetto_cmd/perfetto_cmd_android.cc
@@ -21,46 +21,55 @@
 
 #include "perfetto/base/build_config.h"
 #include "perfetto/base/logging.h"
+#include "perfetto/ext/base/uuid.h"
 #include "perfetto/tracing/core/trace_config.h"
 #include "src/android_internal/dropbox_service.h"
 #include "src/android_internal/incident_service.h"
 #include "src/android_internal/lazy_library_loader.h"
+#include "src/android_internal/statsd_logging.h"
 
 namespace perfetto {
 
 void PerfettoCmd::SaveTraceIntoDropboxAndIncidentOrCrash() {
   PERFETTO_CHECK(!dropbox_tag_.empty());
 
+  bool use_dropbox = !trace_config_->incident_report_config().skip_dropbox();
+  bool use_incident =
+      !trace_config_->incident_report_config().destination_package().empty();
+
+  if (bytes_written_ == 0) {
+    LogUploadEvent(PerfettoStatsdAtom::kNotUploadingEmptyTrace);
+    if (use_dropbox)
+      PERFETTO_LOG("Skipping write to dropbox. Empty trace.");
+    if (use_incident)
+      PERFETTO_LOG("Skipping write to incident. Empty trace.");
+    return;
+  }
+
   // Otherwise, write to Dropbox unless there's a special override in the
   // incident report config.
-  if (!trace_config_->incident_report_config().skip_dropbox()) {
-    if (bytes_written_ == 0) {
-      PERFETTO_LOG("Skipping write to dropbox. Empty trace.");
-    } else {
-      SaveOutputToDropboxOrCrash();
-    }
+  if (use_dropbox) {
+    SaveOutputToDropboxOrCrash();
   }
 
   // Optionally save the trace as an incident. This is either in addition to, or
   // instead of, the Dropbox write.
-  if (!trace_config_->incident_report_config().destination_package().empty()) {
-    if (bytes_written_ == 0) {
-      PERFETTO_LOG("Skipping incident report. Empty trace.");
-    } else {
-      SaveOutputToIncidentTraceOrCrash();
+  if (use_incident) {
+    SaveOutputToIncidentTraceOrCrash();
 
-      // Ask incidentd to create a report, which will read the file we just
-      // wrote.
-      const auto& cfg = trace_config_->incident_report_config();
-      PERFETTO_LAZY_LOAD(android_internal::StartIncidentReport, incident_fn);
-      PERFETTO_CHECK(incident_fn(cfg.destination_package().c_str(),
-                                 cfg.destination_class().c_str(),
-                                 cfg.privacy_level()));
-    }
+    // Ask incidentd to create a report, which will read the file we just
+    // wrote.
+    const auto& cfg = trace_config_->incident_report_config();
+    PERFETTO_LAZY_LOAD(android_internal::StartIncidentReport, incident_fn);
+    PERFETTO_CHECK(incident_fn(cfg.destination_package().c_str(),
+                               cfg.destination_class().c_str(),
+                               cfg.privacy_level()));
   }
 }
 
 void PerfettoCmd::SaveOutputToDropboxOrCrash() {
+  LogUploadEvent(PerfettoStatsdAtom::kUploadDropboxBegin);
+
   PERFETTO_CHECK(fseek(*trace_out_stream_, 0, SEEK_SET) == 0);
 
   // DropBox takes ownership of the file descriptor, so give it a duplicate.
@@ -73,10 +82,12 @@
 
   PERFETTO_LAZY_LOAD(android_internal::SaveIntoDropbox, dropbox_fn);
   if (dropbox_fn(dropbox_tag_.c_str(), read_only_fd.release())) {
+    LogUploadEvent(PerfettoStatsdAtom::kUploadDropboxSuccess);
     PERFETTO_LOG("Wrote %" PRIu64
                  " bytes (before compression) into DropBox with tag %s",
                  bytes_written_, dropbox_tag_.c_str());
   } else {
+    LogUploadEvent(PerfettoStatsdAtom::kUploadDropboxFailure);
     PERFETTO_FATAL("DropBox upload failed");
   }
 }
@@ -87,6 +98,7 @@
 // unique filenames to avoid creating an unbounded amount of files in case of
 // errors.
 void PerfettoCmd::SaveOutputToIncidentTraceOrCrash() {
+  LogUploadEvent(PerfettoStatsdAtom::kUploadIncidentBegin);
   char kIncidentTracePath[256];
   sprintf(kIncidentTracePath, "%s/incident-trace", kStateDir);
 
@@ -107,6 +119,7 @@
   PERFETTO_CHECK(rename(kTempIncidentTracePath, kIncidentTracePath) == 0);
   // Note: not calling fsync(2), as we're not interested in the file being
   // consistent in case of a crash.
+  LogUploadEvent(PerfettoStatsdAtom::kUploadIncidentSuccess);
 }
 
 // static
@@ -119,4 +132,12 @@
   return fd;
 }
 
+void PerfettoCmd::LogUploadEventAndroid(PerfettoStatsdAtom atom) {
+  if (dropbox_tag_.empty())
+    return;
+  PERFETTO_LAZY_LOAD(android_internal::StatsdLogEvent, log_event_fn);
+  base::Uuid uuid(uuid_);
+  log_event_fn(atom, uuid.lsb(), uuid.msb());
+}
+
 }  // namespace perfetto
diff --git a/tools/gen_android_bp b/tools/gen_android_bp
index fa38f37..fa689ca 100755
--- a/tools/gen_android_bp
+++ b/tools/gen_android_bp
@@ -93,22 +93,29 @@
 module_prefix = 'perfetto_'
 
 # Shared libraries which are directly translated to Android system equivalents.
-library_whitelist = [
-    "android.hardware.atrace@1.0",
-    'android.hardware.health@2.0',
-    "android.hardware.power.stats@1.0",
+shared_library_whitelist = [
     'android',
+    'android.hardware.atrace@1.0',
+    'android.hardware.health@2.0',
+    'android.hardware.power.stats@1.0',
     'base',
     'binder',
+    'cutils',
     'hidlbase',
     'hidltransport',
     'hwbinder',
     'incident',
     'log',
     'services',
+    'statssocket',
     'utils',
 ]
 
+# Static libraries which are directly translated to Android system equivalents.
+static_library_whitelist = [
+    'statslog_perfetto',
+]
+
 # Name of the module which settings such as compiler flags for all other
 # modules.
 defaults_module = module_prefix + 'defaults'
@@ -628,8 +635,10 @@
       # Generally library names should be mangled as 'libXXX', unless they
       # are HAL libraries (e.g., android.hardware.health@2.0).
       android_lib = lib if '@' in lib else 'lib' + lib
-      if lib in library_whitelist:
+      if lib in shared_library_whitelist:
         module.shared_libs.add(android_lib)
+      if lib in static_library_whitelist:
+        module.static_libs.add(android_lib)
 
   # If the module is a static library, export all the generated headers.
   if module.type == 'cc_library_static':