Snap for 9564107 from cc7aef8488eeee5f8effe4846332c46e5d3b7de2 to mainline-media-swcodec-release

Change-Id: Ibacc5535bd6db39ff48d8ce31b78b89516e177e7
diff --git a/CHANGELOG b/CHANGELOG
index 99e6c4b..4b35e38 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -8,8 +8,8 @@
   UI:
     *
   SDK:
-    *
-
+    * Added TracingInitArgs::enable_system_consumer configuration option, that
+      allows the linker to discard the consumer IPC, if not required.
 
 v25.0 - 2022-04-01:
   Tracing service and probes:
diff --git a/include/perfetto/tracing/internal/system_tracing_backend.h b/include/perfetto/tracing/internal/system_tracing_backend.h
index 69a1cad..7617109 100644
--- a/include/perfetto/tracing/internal/system_tracing_backend.h
+++ b/include/perfetto/tracing/internal/system_tracing_backend.h
@@ -35,6 +35,8 @@
 // together with system traces, useful to correlate on the timeline system
 // events (e.g. scheduling slices from the kernel) with in-app events.
 namespace internal {
+
+// Full backend (with producer and consumer)
 class PERFETTO_EXPORT SystemTracingBackend : public TracingBackend {
  public:
   static TracingBackend* GetInstance();
@@ -49,6 +51,21 @@
   SystemTracingBackend();
 };
 
+// Producer only backend.
+class PERFETTO_EXPORT SystemTracingProducerOnlyBackend : public TracingBackend {
+ public:
+  static TracingBackend* GetInstance();
+
+  // TracingBackend implementation.
+  std::unique_ptr<ProducerEndpoint> ConnectProducer(
+      const ConnectProducerArgs&) override;
+  std::unique_ptr<ConsumerEndpoint> ConnectConsumer(
+      const ConnectConsumerArgs&) override;
+
+ private:
+  SystemTracingProducerOnlyBackend();
+};
+
 }  // namespace internal
 }  // namespace perfetto
 
diff --git a/include/perfetto/tracing/tracing.h b/include/perfetto/tracing/tracing.h
index 9aae9e8..01d4851 100644
--- a/include/perfetto/tracing/tracing.h
+++ b/include/perfetto/tracing/tracing.h
@@ -115,6 +115,13 @@
   // callback instead of being logged directly.
   LogMessageCallback log_message_callback = nullptr;
 
+  // This flag can be set to false in order to avoid enabling the system
+  // consumer in Tracing::Initialize(), so that the linker can remove the unused
+  // consumer IPC implementation to reduce binary size. When this option is
+  // false, calling Tracing::NewTrace() on the system backend will fail. This
+  // setting only has an effect if kSystemBackend is specified in |backends|.
+  bool enable_system_consumer = true;
+
  protected:
   friend class Tracing;
   friend class internal::TracingMuxerImpl;
@@ -124,11 +131,13 @@
   bool operator==(const TracingInitArgs& other) const {
     return std::tie(backends, custom_backend, platform, shmem_size_hint_kb,
                     shmem_page_size_hint_kb, in_process_backend_factory_,
-                    system_backend_factory_, dcheck_is_on_) ==
+                    system_backend_factory_, dcheck_is_on_,
+                    enable_system_consumer) ==
            std::tie(other.backends, other.custom_backend, other.platform,
                     other.shmem_size_hint_kb, other.shmem_page_size_hint_kb,
                     other.in_process_backend_factory_,
-                    other.system_backend_factory_, other.dcheck_is_on_);
+                    other.system_backend_factory_, other.dcheck_is_on_,
+                    other.enable_system_consumer);
   }
 
   using BackendFactoryFunction = TracingBackend* (*)();
@@ -161,8 +170,13 @@
           &internal::InProcessTracingBackend::GetInstance;
     }
     if (args.backends & kSystemBackend) {
-      args_copy.system_backend_factory_ =
-          &internal::SystemTracingBackend::GetInstance;
+      if (args.enable_system_consumer) {
+        args_copy.system_backend_factory_ =
+            &internal::SystemTracingBackend::GetInstance;
+      } else {
+        args_copy.system_backend_factory_ =
+            &internal::SystemTracingProducerOnlyBackend::GetInstance;
+      }
     }
     InitializeInternal(args_copy);
   }
@@ -172,8 +186,6 @@
 
   // Start a new tracing session using the given tracing backend. Use
   // |kUnspecifiedBackend| to select an available backend automatically.
-  // For the moment this can be used only when initializing tracing in
-  // kInProcess mode. For the system mode use the 'bin/perfetto' cmdline client.
   static std::unique_ptr<TracingSession> NewTrace(
       BackendType = kUnspecifiedBackend);
 
diff --git a/src/tracing/internal/system_tracing_backend.cc b/src/tracing/internal/system_tracing_backend.cc
index 5aa3493..5562421 100644
--- a/src/tracing/internal/system_tracing_backend.cc
+++ b/src/tracing/internal/system_tracing_backend.cc
@@ -25,17 +25,10 @@
 
 namespace perfetto {
 namespace internal {
+namespace {
 
-// static
-TracingBackend* SystemTracingBackend::GetInstance() {
-  static auto* instance = new SystemTracingBackend();
-  return instance;
-}
-
-SystemTracingBackend::SystemTracingBackend() {}
-
-std::unique_ptr<ProducerEndpoint> SystemTracingBackend::ConnectProducer(
-    const ConnectProducerArgs& args) {
+std::unique_ptr<ProducerEndpoint> CreateProducerEndpoint(
+    const TracingBackend::ConnectProducerArgs& args) {
   PERFETTO_DCHECK(args.task_runner->RunsTasksOnCurrentThread());
 
   auto endpoint = ProducerIPCClient::Connect(
@@ -47,6 +40,21 @@
   return endpoint;
 }
 
+}  // namespace
+
+// static
+TracingBackend* SystemTracingBackend::GetInstance() {
+  static auto* instance = new SystemTracingBackend();
+  return instance;
+}
+
+SystemTracingBackend::SystemTracingBackend() {}
+
+std::unique_ptr<ProducerEndpoint> SystemTracingBackend::ConnectProducer(
+    const ConnectProducerArgs& args) {
+  return CreateProducerEndpoint(args);
+}
+
 std::unique_ptr<ConsumerEndpoint> SystemTracingBackend::ConnectConsumer(
     const ConnectConsumerArgs& args) {
   auto endpoint = ConsumerIPCClient::Connect(GetConsumerSocket(), args.consumer,
@@ -55,5 +63,29 @@
   return endpoint;
 }
 
+// static
+TracingBackend* SystemTracingProducerOnlyBackend::GetInstance() {
+  static auto* instance = new SystemTracingProducerOnlyBackend();
+  return instance;
+}
+
+SystemTracingProducerOnlyBackend::SystemTracingProducerOnlyBackend() {}
+
+std::unique_ptr<ProducerEndpoint>
+SystemTracingProducerOnlyBackend::ConnectProducer(
+    const ConnectProducerArgs& args) {
+  return CreateProducerEndpoint(args);
+}
+
+std::unique_ptr<ConsumerEndpoint>
+SystemTracingProducerOnlyBackend::ConnectConsumer(
+    const ConnectConsumerArgs& args) {
+  base::ignore_result(args);
+  PERFETTO_FATAL(
+      "System backend consumer support disabled. "
+      "TracingInitArgs::enable_system_consumer was false");
+  return nullptr;
+}
+
 }  // namespace internal
 }  // namespace perfetto
diff --git a/src/tracing/internal/system_tracing_backend_fake.cc b/src/tracing/internal/system_tracing_backend_fake.cc
index 9ca90d0..ea992a1 100644
--- a/src/tracing/internal/system_tracing_backend_fake.cc
+++ b/src/tracing/internal/system_tracing_backend_fake.cc
@@ -27,5 +27,11 @@
   return nullptr;
 }
 
+// static
+TracingBackend* SystemTracingProducerOnlyBackend::GetInstance() {
+  PERFETTO_FATAL("System tracing not implemented");
+  return nullptr;
+}
+
 }  // namespace internal
 }  // namespace perfetto
diff --git a/src/tracing/internal/tracing_muxer_impl.cc b/src/tracing/internal/tracing_muxer_impl.cc
index dd34ca4..876b90b 100644
--- a/src/tracing/internal/tracing_muxer_impl.cc
+++ b/src/tracing/internal/tracing_muxer_impl.cc
@@ -761,6 +761,7 @@
     rb.backend = backend;
     rb.id = backend_id;
     rb.type = type;
+    rb.consumer_enabled = type != kSystemBackend || args.enable_system_consumer;
     rb.producer.reset(new ProducerImpl(this, backend_id,
                                        args.shmem_batch_commits_duration_ms));
     rb.producer_conn_args.producer = rb.producer.get();
@@ -1645,6 +1646,10 @@
         continue;
       }
 
+      if (!backend.consumer_enabled) {
+        continue;
+      }
+
       TracingBackendId backend_id = backend.id;
 
       // Create the consumer now, even if we have to ask the embedder below, so
diff --git a/src/tracing/internal/tracing_muxer_impl.h b/src/tracing/internal/tracing_muxer_impl.h
index 1841cd4..c545a0b 100644
--- a/src/tracing/internal/tracing_muxer_impl.h
+++ b/src/tracing/internal/tracing_muxer_impl.h
@@ -380,6 +380,8 @@
     // The calling code can request more than one concurrently active tracing
     // session for the same backend. We need to create one consumer per session.
     std::vector<std::unique_ptr<ConsumerImpl>> consumers;
+
+    bool consumer_enabled = true;
   };
 
   void UpdateDataSourceOnAllBackends(RegisteredDataSource& rds,
diff --git a/src/tracing/test/api_integrationtest.cc b/src/tracing/test/api_integrationtest.cc
index 0604d09..98963fc 100644
--- a/src/tracing/test/api_integrationtest.cc
+++ b/src/tracing/test/api_integrationtest.cc
@@ -4952,6 +4952,44 @@
   EXPECT_EQ(it, trace.packet().end());
 }
 
+TEST(PerfettoApiInitTest, DisableSystemConsumer) {
+  g_test_tracing_policy->should_allow_consumer_connection = true;
+
+  if (!perfetto::test::StartSystemService()) {
+    GTEST_SKIP();
+  }
+
+  EXPECT_FALSE(perfetto::Tracing::IsInitialized());
+  TracingInitArgs args;
+  args.backends = perfetto::kSystemBackend;
+  args.tracing_policy = g_test_tracing_policy;
+  args.enable_system_consumer = false;
+  perfetto::Tracing::Initialize(args);
+
+  // If this wasn't the first test to run in this process, any producers
+  // connected to the old system service will have been disconnected by the
+  // service restarting above. Wait for all producers to connect again before
+  // proceeding with the test.
+  perfetto::test::SyncProducers();
+
+  perfetto::test::DisableReconnectLimit();
+
+  std::unique_ptr<perfetto::TracingSession> ts =
+      perfetto::Tracing::NewTrace(perfetto::kSystemBackend);
+
+  // Creating the consumer should cause an asynchronous disconnect error.
+  WaitableTestEvent got_error;
+  ts->SetOnErrorCallback([&](perfetto::TracingError error) {
+    EXPECT_EQ(perfetto::TracingError::kDisconnected, error.code);
+    EXPECT_FALSE(error.message.empty());
+    got_error.Notify();
+  });
+  got_error.Wait();
+  ts.reset();
+
+  perfetto::Tracing::ResetForTesting();
+}
+
 struct BackendTypeAsString {
   std::string operator()(
       const ::testing::TestParamInfo<perfetto::BackendType>& info) const {