Introduce support for deferred start (fast triggering)

This CL introduces new Setup methods to both the
producer and consumer API. The API changes are designed
to be backwards compatible with the prior versions of
Android.

From the producer viewpoint: each data source now sees a
SetupDataSource() method before the StartDataSource() method.
The data source instance id and config is identical. This
gives the data source a chance to setup itself before actually
starting.

From the consumer viewpoint:
A new "deferred_start" field is added to the TraceConfig.
When deferred_start is true, the EnableTracing method
brings up all the tracing harness and calls the
SetupDataSource() methods on the producers, but doesn't
start them. Data sources are started only when calling
StartDataSource().

Note that in this CL, the ftrace data source doesn't
deal yet with the split Setup/Start phases and starts
directly upon creation. This will be fixed in a separate
CL.

Bug: 116547201
Change-Id: I2ab22c7f8ee2388f8158df733dddeef9dc9c0143
diff --git a/src/tracing/core/service_impl_unittest.cc b/src/tracing/core/service_impl_unittest.cc
index 8787672..5a0ca16 100644
--- a/src/tracing/core/service_impl_unittest.cc
+++ b/src/tracing/core/service_impl_unittest.cc
@@ -154,8 +154,13 @@
   consumer->EnableTracing(trace_config);
 
   producer->WaitForTracingSetup();
+  producer->WaitForDataSourceSetup("data_source");
   producer->WaitForDataSourceStart("data_source");
 
+  // Calling StartTracing() should be a noop (% a DLOG statement) because the
+  // trace config didn't have the |deferred_start| flag set.
+  consumer->StartTracing();
+
   consumer->DisableTracing();
   producer->WaitForDataSourceStop("data_source");
   consumer->WaitForTracingDisabled();
@@ -178,6 +183,7 @@
   consumer->EnableTracing(trace_config);
 
   producer->WaitForTracingSetup();
+  producer->WaitForDataSourceSetup("data_source");
   producer->WaitForDataSourceStart("data_source");
 
   std::unique_ptr<MockProducer> producer_otheruid = CreateMockProducer();
@@ -195,6 +201,7 @@
   trace_config.set_lockdown_mode(
       TraceConfig::LockdownModeOperation::LOCKDOWN_CLEAR);
   consumer->EnableTracing(trace_config);
+  producer->WaitForDataSourceSetup("data_source");
   producer->WaitForDataSourceStart("data_source");
 
   std::unique_ptr<MockProducer> producer_otheruid2 = CreateMockProducer();
@@ -220,6 +227,7 @@
   consumer->EnableTracing(trace_config);
 
   producer->WaitForTracingSetup();
+  producer->WaitForDataSourceSetup("data_source");
   producer->WaitForDataSourceStart("data_source");
 
   // Disconnecting the consumer while tracing should trigger data source
@@ -243,6 +251,7 @@
   consumer->EnableTracing(trace_config);
 
   producer->WaitForTracingSetup();
+  producer->WaitForDataSourceSetup("data_source");
   producer->WaitForDataSourceStart("data_source");
 
   // Disconnecting and reconnecting a producer with a matching data source.
@@ -252,6 +261,7 @@
   producer->Connect(svc.get(), "mock_producer_2");
   producer->RegisterDataSource("data_source");
   producer->WaitForTracingSetup();
+  producer->WaitForDataSourceSetup("data_source");
   producer->WaitForDataSourceStart("data_source");
 }
 
@@ -303,6 +313,7 @@
   consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
 
   producer->WaitForTracingSetup();
+  producer->WaitForDataSourceSetup("data_source");
   producer->WaitForDataSourceStart("data_source");
 
   static const char kPayload[] = "1234567890abcdef-";
@@ -397,12 +408,15 @@
   size_t actual_page_sizes_kb[kNumProducers]{};
   for (size_t i = 0; i < kNumProducers; i++) {
     producer[i]->WaitForTracingSetup();
-    producer[i]->WaitForDataSourceStart("data_source");
+    producer[i]->WaitForDataSourceSetup("data_source");
     actual_shm_sizes_kb[i] =
         producer[i]->endpoint()->shared_memory()->size() / 1024;
     actual_page_sizes_kb[i] =
         producer[i]->endpoint()->shared_buffer_page_size_kb();
   }
+  for (size_t i = 0; i < kNumProducers; i++) {
+    producer[i]->WaitForDataSourceStart("data_source");
+  }
   ASSERT_THAT(actual_page_sizes_kb, ElementsAreArray(kExpectedPageSizesKb));
   ASSERT_THAT(actual_shm_sizes_kb, ElementsAreArray(kExpectedSizesKb));
 }
@@ -422,6 +436,7 @@
 
   consumer->EnableTracing(trace_config);
   producer->WaitForTracingSetup();
+  producer->WaitForDataSourceSetup("data_source");
   producer->WaitForDataSourceStart("data_source");
 
   std::unique_ptr<TraceWriter> writer =
@@ -460,6 +475,7 @@
 
   consumer->EnableTracing(trace_config);
   producer->WaitForTracingSetup();
+  producer->WaitForDataSourceSetup("data_source");
   producer->WaitForDataSourceStart("data_source");
 
   std::unique_ptr<TraceWriter> writer =
@@ -498,6 +514,7 @@
 
   consumer->EnableTracing(trace_config);
   producer->WaitForTracingSetup();
+  producer->WaitForDataSourceSetup("data_source");
   producer->WaitForDataSourceStart("data_source");
 
   std::unique_ptr<TraceWriter> writer =
@@ -564,6 +581,11 @@
 
   consumer->EnableTracing(trace_config);
   producer->WaitForTracingSetup();
+
+  producer->WaitForDataSourceSetup("ds_will_ack_1");
+  producer->WaitForDataSourceSetup("ds_wont_ack");
+  producer->WaitForDataSourceSetup("ds_will_ack_2");
+
   producer->WaitForDataSourceStart("ds_will_ack_1");
   producer->WaitForDataSourceStart("ds_wont_ack");
   producer->WaitForDataSourceStart("ds_will_ack_2");
@@ -636,6 +658,7 @@
 
   consumer->EnableTracing(trace_config);
   producer->WaitForTracingSetup();
+  producer->WaitForDataSourceSetup("data_source");
   producer->WaitForDataSourceStart("data_source");
 
   std::unique_ptr<TraceWriter> writer =
@@ -675,11 +698,15 @@
 
     if (i == 0)
       producer1->WaitForTracingSetup();
-    producer1->WaitForDataSourceStart("ds_1A");
-    producer1->WaitForDataSourceStart("ds_1B");
 
+    producer1->WaitForDataSourceSetup("ds_1A");
+    producer1->WaitForDataSourceSetup("ds_1B");
     if (i == 0)
       producer2->WaitForTracingSetup();
+    producer2->WaitForDataSourceSetup("ds_2A");
+
+    producer1->WaitForDataSourceStart("ds_1A");
+    producer1->WaitForDataSourceStart("ds_1B");
     producer2->WaitForDataSourceStart("ds_2A");
 
     auto* ds1 = producer1->GetDataSourceInstance("ds_1A");
@@ -723,6 +750,7 @@
   base::TempFile tmp_file = base::TempFile::Create();
   consumer->EnableTracing(trace_config, base::ScopedFile(dup(tmp_file.fd())));
   producer->WaitForTracingSetup();
+  producer->WaitForDataSourceSetup("data_source");
   producer->WaitForDataSourceStart("data_source");
 
   // Write some variable length payload, waiting for sync markers every now
@@ -777,4 +805,42 @@
   EXPECT_EQ(whole_trace.SerializeAsString(), merged_trace.SerializeAsString());
 }
 
+// Creates a tracing session with |deferred_start| and checks that data sources
+// are started only after calling StartTracing().
+TEST_F(TracingServiceImplTest, DeferredStart) {
+  std::unique_ptr<MockConsumer> consumer = CreateMockConsumer();
+  consumer->Connect(svc.get());
+
+  std::unique_ptr<MockProducer> producer = CreateMockProducer();
+  producer->Connect(svc.get(), "mock_producer");
+
+  // Create two data sources but enable only one of them.
+  producer->RegisterDataSource("ds_1");
+  producer->RegisterDataSource("ds_2");
+
+  TraceConfig trace_config;
+  trace_config.add_buffers()->set_size_kb(128);
+  trace_config.add_data_sources()->mutable_config()->set_name("ds_1");
+  trace_config.set_deferred_start(true);
+  trace_config.set_duration_ms(1);
+
+  consumer->EnableTracing(trace_config);
+  producer->WaitForTracingSetup();
+
+  producer->WaitForDataSourceSetup("ds_1");
+
+  // Make sure we don't get unexpected DataSourceStart() notifications yet.
+  task_runner.RunUntilIdle();
+
+  consumer->StartTracing();
+
+  producer->WaitForDataSourceStart("ds_1");
+
+  auto writer1 = producer->CreateTraceWriter("ds_1");
+  producer->WaitForFlush(writer1.get());
+
+  producer->WaitForDataSourceStop("ds_1");
+  consumer->WaitForTracingDisabled();
+}
+
 }  // namespace perfetto