Merge "TraceWriterImpl: Fix a DCHECK in drop_packets_ mode."
diff --git a/docs/concepts/clock-sync.md b/docs/concepts/clock-sync.md
index 95a200f..4afb1b7 100644
--- a/docs/concepts/clock-sync.md
+++ b/docs/concepts/clock-sync.md
@@ -120,7 +120,7 @@
 
 * Chose a fully qualified name for the clock domain
   (e.g. `com.example.my_subsystem`)
-* Chose the clock ID as `(HASH("com.example.my_subsystem") + 128) & 0xFFFFFFF`
+* Chose the clock ID as `HASH("com.example.my_subsystem") | 0x80000000`
   where `HASH(x)` is the FNV-1a hash of the fully qualified clock domain name.
 
 ### {#clock_snapshot} The ClockSnapshot trace packet
diff --git a/include/perfetto/ext/base/thread_utils.h b/include/perfetto/ext/base/thread_utils.h
index fb47d3d..2e9c4e5 100644
--- a/include/perfetto/ext/base/thread_utils.h
+++ b/include/perfetto/ext/base/thread_utils.h
@@ -70,7 +70,9 @@
 }
 
 #else
-inline void MaybeSetThreadName(const std::string&) {}
+inline bool MaybeSetThreadName(const std::string&) {
+  return false;
+}
 inline bool GetThreadName(std::string&) {
   return false;
 }
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..45b1767
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,44 @@
+# Copyright (C) 2021 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.
+
+# This meson project only supports the Perfetto SDK
+# available from release branches.
+# https://perfetto.dev/docs/instrumentation/tracing-sdk
+
+project(
+    'perfetto',
+    ['c','cpp'],
+    default_options: ['c_std=c99', 'cpp_std=c++11']
+)
+
+fs = import('fs')
+
+if not fs.is_dir('sdk')
+    error('sdk dir not found, please checkout a release tag, e.g. v13.0')
+endif
+
+dep_threads = dependency('threads')
+
+lib_perfetto = static_library(
+    'perfetto',
+    sources: 'sdk/perfetto.cc',
+    dependencies: dep_threads,
+)
+
+inc_perfetto = include_directories('sdk')
+
+dep_perfetto = declare_dependency(
+    link_with: lib_perfetto,
+    include_directories: inc_perfetto,
+)
diff --git a/src/android_internal/power_stats.cc b/src/android_internal/power_stats.cc
index 7dff16c..34da342 100644
--- a/src/android_internal/power_stats.cc
+++ b/src/android_internal/power_stats.cc
@@ -16,6 +16,8 @@
 
 #include "src/android_internal/power_stats.h"
 
+#include "perfetto/ext/base/utils.h"
+
 #include <string.h>
 
 #include <algorithm>
@@ -47,6 +49,8 @@
   virtual bool GetRailEnergyData(RailEnergyData*, size_t* size_of_arr) = 0;
 
   // Available from Android S+.
+  virtual bool GetEnergyConsumerInfo(EnergyConsumerInfo* consumers,
+                                     size_t* size_of_arr) = 0;
   virtual bool GetEnergyConsumed(EnergyEstimationBreakdown* breakdown,
                                  size_t* size_of_arr) = 0;
   virtual ~PowerStatsDataProvider() = default;
@@ -56,6 +60,8 @@
  public:
   bool GetAvailableRails(RailDescriptor*, size_t* size_of_arr) override;
   bool GetRailEnergyData(RailEnergyData*, size_t* size_of_arr) override;
+  bool GetEnergyConsumerInfo(EnergyConsumerInfo* consumers,
+                             size_t* size_of_arr) override;
   bool GetEnergyConsumed(EnergyEstimationBreakdown* breakdown,
                          size_t* size_of_arr) override;
 
@@ -74,6 +80,8 @@
 
   bool GetAvailableRails(RailDescriptor*, size_t* size_of_arr) override;
   bool GetRailEnergyData(RailEnergyData*, size_t* size_of_arr) override;
+  bool GetEnergyConsumerInfo(EnergyConsumerInfo* consumers,
+                             size_t* size_of_arr) override;
   bool GetEnergyConsumed(EnergyEstimationBreakdown* breakdown,
                          size_t* size_of_arr) override;
 
@@ -112,6 +120,10 @@
   return GetDataProvider()->GetRailEnergyData(data, size_of_arr);
 }
 
+bool GetEnergyConsumerInfo(EnergyConsumerInfo* consumers, size_t* size_of_arr) {
+  return GetDataProvider()->GetEnergyConsumerInfo(consumers, size_of_arr);
+}
+
 bool GetEnergyConsumed(EnergyEstimationBreakdown* breakdown,
                        size_t* size_of_arr) {
   return GetDataProvider()->GetEnergyConsumed(breakdown, size_of_arr);
@@ -198,6 +210,11 @@
   return status == hal::Status::SUCCESS;
 }
 
+bool PowerStatsHalDataProvider::GetEnergyConsumerInfo(EnergyConsumerInfo*,
+                                                      size_t*) {
+  return false;
+}
+
 bool PowerStatsHalDataProvider::GetEnergyConsumed(EnergyEstimationBreakdown*,
                                                   size_t*) {
   return false;
@@ -288,6 +305,41 @@
   return true;
 }
 
+bool PowerStatsAidlDataProvider::GetEnergyConsumerInfo(
+    EnergyConsumerInfo* consumers,
+    size_t* size_of_arr) {
+  const size_t in_array_size = *size_of_arr;
+  *size_of_arr = 0;
+
+  aidl::IPowerStats* svc = MaybeGetService();
+  if (svc == nullptr) {
+    return false;
+  }
+  std::vector<aidl::EnergyConsumer> results;
+  android::binder::Status status = svc->getEnergyConsumerInfo(&results);
+
+  if (!status.isOk()) {
+    if (status.transactionError() == android::DEAD_OBJECT) {
+      // Service has died.  Reset it to attempt to acquire a new one next time.
+      ResetService();
+    }
+    return false;
+  }
+  size_t max_size = std::min(in_array_size, results.size());
+  for (const auto& result : results) {
+    if (*size_of_arr >= max_size) {
+      break;
+    }
+    auto& cur = consumers[(*size_of_arr)++];
+    cur.energy_consumer_id = result.id;
+    cur.ordinal = result.ordinal;
+    strncpy(cur.type, aidl::toString(result.type).c_str(), sizeof(cur.type));
+    cur.type[sizeof(cur.type) - 1] = '\0';
+    strncpy(cur.name, result.name.c_str(), sizeof(cur.name));
+    cur.name[sizeof(cur.name) - 1] = '\0';
+  }
+  return true;
+}
 bool PowerStatsAidlDataProvider::GetEnergyConsumed(
     EnergyEstimationBreakdown* breakdown,
     size_t* size_of_arr) {
diff --git a/src/android_internal/power_stats.h b/src/android_internal/power_stats.h
index c7693f9..3225d29 100644
--- a/src/android_internal/power_stats.h
+++ b/src/android_internal/power_stats.h
@@ -51,6 +51,24 @@
   uint64_t energy;
 };
 
+struct EnergyConsumerInfo {
+  // Unique ID of this energy consumer.  Matches the ID in a
+  // EnergyEstimationBreakdown.
+  int32_t energy_consumer_id;
+
+  // For a group of energy consumers of the same logical type, sorting by
+  // ordinal gives their physical order. Ordinals must be consecutive integers
+  // starting from 0.
+  int32_t ordinal;
+
+  // Type of this energy consumer.
+  char type[64];
+
+  // Unique name of this energy consumer. Vendor/device specific. Opaque to
+  // framework.
+  char name[64];
+};
+
 struct EnergyEstimationBreakdown {
   // Energy consumer ID.
   int32_t energy_consumer_id;
@@ -73,6 +91,9 @@
 bool __attribute__((visibility("default")))
 GetRailEnergyData(RailEnergyData*, size_t* size_of_arr);
 
+bool __attribute__((visibility("default")))
+GetEnergyConsumerInfo(EnergyConsumerInfo* consumers, size_t* size_of_arr);
+
 // Retrieve the energy estimation breakdown for all energy consumer.  For each
 // consumer, there will be an entry with a uid of ALL_UIDS_FOR_CONSUMER,
 // followed by the energy breakdown for each process contributing to that
diff --git a/src/profiling/memory/heapprofd_producer.cc b/src/profiling/memory/heapprofd_producer.cc
index f45e348..fa1527d 100644
--- a/src/profiling/memory/heapprofd_producer.cc
+++ b/src/profiling/memory/heapprofd_producer.cc
@@ -75,7 +75,8 @@
                                                   size_t n) {
   std::vector<UnwindingWorker> ret;
   for (size_t i = 0; i < n; ++i) {
-    ret.emplace_back(delegate, base::ThreadTaskRunner::CreateAndStart());
+    ret.emplace_back(delegate,
+                     base::ThreadTaskRunner::CreateAndStart("heapprofdunwind"));
   }
   return ret;
 }
diff --git a/src/traced/probes/power/BUILD.gn b/src/traced/probes/power/BUILD.gn
index 7b75c6a..fc28f67 100644
--- a/src/traced/probes/power/BUILD.gn
+++ b/src/traced/probes/power/BUILD.gn
@@ -18,6 +18,7 @@
     "..:data_source",
     "../../../../gn:default_deps",
     "../../../../include/perfetto/ext/traced",
+    "../../../../protos/perfetto/common:zero",
     "../../../../protos/perfetto/config/power:zero",
     "../../../../protos/perfetto/trace:zero",
     "../../../../protos/perfetto/trace/power:zero",
diff --git a/src/traced/probes/power/android_power_data_source.cc b/src/traced/probes/power/android_power_data_source.cc
index 85a0daa..0034453 100644
--- a/src/traced/probes/power/android_power_data_source.cc
+++ b/src/traced/probes/power/android_power_data_source.cc
@@ -30,6 +30,7 @@
 #include "src/android_internal/lazy_library_loader.h"
 #include "src/android_internal/power_stats.h"
 
+#include "protos/perfetto/common/android_energy_consumer_descriptor.pbzero.h"
 #include "protos/perfetto/config/power/android_power_config.pbzero.h"
 #include "protos/perfetto/trace/power/android_energy_estimation_breakdown.pbzero.h"
 #include "protos/perfetto/trace/power/battery_counters.pbzero.h"
@@ -41,6 +42,7 @@
 namespace {
 constexpr uint32_t kMinPollIntervalMs = 100;
 constexpr size_t kMaxNumRails = 32;
+constexpr size_t kMaxNumEnergyConsumer = 32;
 constexpr size_t kMaxNumPowerEntities = 256;
 }  // namespace
 
@@ -57,6 +59,8 @@
   PERFETTO_LAZY_LOAD(android_internal::GetAvailableRails, get_available_rails_);
   PERFETTO_LAZY_LOAD(android_internal::GetRailEnergyData,
                      get_rail_energy_data_);
+  PERFETTO_LAZY_LOAD(android_internal::GetEnergyConsumerInfo,
+                     get_energy_consumer_info_);
   PERFETTO_LAZY_LOAD(android_internal::GetEnergyConsumed, get_energy_consumed_);
 
   base::Optional<int64_t> GetCounter(android_internal::BatteryCounter counter) {
@@ -97,6 +101,21 @@
     return energy_data;
   }
 
+  std::vector<android_internal::EnergyConsumerInfo> GetEnergyConsumerInfo() {
+    if (!get_energy_consumer_info_)
+      return std::vector<android_internal::EnergyConsumerInfo>();
+
+    std::vector<android_internal::EnergyConsumerInfo> consumers(
+        kMaxNumEnergyConsumer);
+    size_t num_power_entities = consumers.size();
+    if (!get_energy_consumer_info_(&consumers[0], &num_power_entities)) {
+      PERFETTO_ELOG("Failed to retrieve energy consumer info.");
+      num_power_entities = 0;
+    }
+    consumers.resize(num_power_entities);
+    return consumers;
+  }
+
   std::vector<android_internal::EnergyEstimationBreakdown> GetEnergyConsumed() {
     if (!get_energy_consumed_)
       return std::vector<android_internal::EnergyEstimationBreakdown>();
@@ -121,6 +140,7 @@
     : ProbesDataSource(session_id, &descriptor),
       task_runner_(task_runner),
       rail_descriptors_logged_(false),
+      energy_consumer_loggged_(false),
       writer_(std::move(writer)),
       weak_factory_(this) {
   using protos::pbzero::AndroidPowerConfig;
@@ -261,12 +281,29 @@
 void AndroidPowerDataSource::WriteEnergyEstimationBreakdown() {
   if (!energy_breakdown_collection_enabled_)
     return;
-  auto energy_breakdowns = lib_->GetEnergyConsumed();
   auto timestamp = static_cast<uint64_t>(base::GetBootTimeNs().count());
 
   TraceWriter::TracePacketHandle packet;
   protos::pbzero::AndroidEnergyEstimationBreakdown* energy_estimation_proto =
       nullptr;
+
+  if (!energy_consumer_loggged_) {
+    energy_consumer_loggged_ = true;
+    packet = writer_->NewTracePacket();
+    energy_estimation_proto = packet->set_android_energy_estimation_breakdown();
+    auto* descriptor_proto =
+        energy_estimation_proto->set_energy_consumer_descriptor();
+    auto consumers = lib_->GetEnergyConsumerInfo();
+    for (const auto& consumer : consumers) {
+      auto* desc_proto = descriptor_proto->add_energy_consumers();
+      desc_proto->set_energy_consumer_id(consumer.energy_consumer_id);
+      desc_proto->set_ordinal(consumer.ordinal);
+      desc_proto->set_type(consumer.type);
+      desc_proto->set_name(consumer.name);
+    }
+  }
+
+  auto energy_breakdowns = lib_->GetEnergyConsumed();
   for (const auto& breakdown : energy_breakdowns) {
     if (breakdown.uid == android_internal::ALL_UIDS_FOR_CONSUMER) {
       // Finalize packet before calling NewTracePacket.
diff --git a/src/traced/probes/power/android_power_data_source.h b/src/traced/probes/power/android_power_data_source.h
index 9841fa8..4fecfda 100644
--- a/src/traced/probes/power/android_power_data_source.h
+++ b/src/traced/probes/power/android_power_data_source.h
@@ -62,6 +62,7 @@
   std::bitset<8> counters_enabled_;
   bool rails_collection_enabled_;
   bool rail_descriptors_logged_;
+  bool energy_consumer_loggged_;
   bool energy_breakdown_collection_enabled_;
   std::unique_ptr<TraceWriter> writer_;
   std::unique_ptr<DynamicLibLoader> lib_;