perfetto: fix several problems with CTS

The problems:
1) Previously, we were creating a new thread with a producer on every
resume of the activity. As resumes do not necessarily correspond to
process death, we were ending up with n producers (where n is the number
of tests which ran before the activity test).
2) We were not cleaning up producers correctly and were instead relying
on process death. However, it's very possible that an activity gets
recreated without process death (as we have foreground services).
3) When we refactored CTS deps to not have to repeat tests, we
accidentally stopped running integration tests in CTS.

Solutions:
1) Setup "proper" producer lifecycle handling (this is still pretty
hacky but significantly better than it was before) by tying the
lifecycle of the producer to the lifecycle of the containing Java Android
owner.
2) Reintroduce the integration tests source set into the CTS tests.

Bug: 146984689
Change-Id: I2b0bed6f9f451057e93cb2d380962f6af0117efc
diff --git a/Android.bp b/Android.bp
index 5ed362b..a1f9332 100644
--- a/Android.bp
+++ b/Android.bp
@@ -772,6 +772,7 @@
     ":perfetto_src_tracing_common",
     ":perfetto_src_tracing_ipc",
     ":perfetto_src_tracing_tracing",
+    ":perfetto_test_end_to_end_integrationtests",
     ":perfetto_test_task_runner_thread",
     ":perfetto_test_task_runner_thread_delegates",
     ":perfetto_test_test_helper",
diff --git a/test/cts/BUILD.gn b/test/cts/BUILD.gn
index 4ecb26c..f7868d8 100644
--- a/test/cts/BUILD.gn
+++ b/test/cts/BUILD.gn
@@ -20,6 +20,7 @@
   complete_static_lib = true
   testonly = true
   deps = [
+    "..:end_to_end_integrationtests",
     "../..:libperfetto_client_experimental",
     "../../gn:default_deps",
     "../../gn:gtest_and_gmock",
diff --git a/test/cts/producer/jni/fake_producer_jni.cc b/test/cts/producer/jni/fake_producer_jni.cc
index 47d4356..ab587a8 100644
--- a/test/cts/producer/jni/fake_producer_jni.cc
+++ b/test/cts/producer/jni/fake_producer_jni.cc
@@ -19,33 +19,99 @@
 #include "perfetto/ext/traced/traced.h"
 #include "perfetto/ext/tracing/ipc/default_socket.h"
 
-#include "src/base/test/test_task_runner.h"
+#include "perfetto/ext/base/unix_task_runner.h"
 
 #include "test/fake_producer.h"
 
+namespace {
+
+static std::mutex g_mutex;
+
+// These variables are guarded by the above mutex.
+static perfetto::base::UnixTaskRunner* g_activity_tr = nullptr;
+static perfetto::base::UnixTaskRunner* g_service_tr = nullptr;
+static perfetto::base::UnixTaskRunner* g_isolated_service_tr = nullptr;
+
+}  // namespace
+
 namespace perfetto {
 namespace {
-void ListenAndRespond(const std::string& name) {
-  base::TestTaskRunner task_runner;
+
+void ListenAndRespond(const std::string& name, base::UnixTaskRunner** tr) {
+  // Note that this lock is unlocked by a post task in the middle of the
+  // function instead of at the end of this function.
+  std::unique_lock<std::mutex> lock(g_mutex);
+
+  // Ensure that we don't create multiple instances of the same producer.
+  // If the passed task runner is non-null, that means it's still running
+  // so we don't need to create another instance.
+  if (*tr)
+    return;
+
+  // Post a task to unlock the mutex when the runner has started executing
+  // tasks.
+  base::UnixTaskRunner task_runner;
+  task_runner.PostTask([tr, &lock, &task_runner]() {
+    *tr = &task_runner;
+    lock.unlock();
+  });
+
   FakeProducer producer(name);
   producer.Connect(GetProducerSocket(), &task_runner, [] {}, [] {});
   task_runner.Run();
+
+  // Cleanup the task runner again to remove outside visibilty so we can
+  // create new instances of the producer.
+  {
+    std::lock_guard<std::mutex> guard(g_mutex);
+    *tr = nullptr;
+  }
 }
+
 }  // namespace
 }  // namespace perfetto
 
 extern "C" JNIEXPORT void JNICALL
+Java_android_perfetto_producer_ProducerActivity_quitTaskRunner(JNIEnv*,
+                                                               jclass) {
+  std::lock_guard<std::mutex> guard(g_mutex);
+  if (g_activity_tr) {
+    g_activity_tr->Quit();
+  }
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_android_perfetto_producer_ProducerIsolatedService_quitTaskRunner(JNIEnv*,
+                                                                      jclass) {
+  std::lock_guard<std::mutex> guard(g_mutex);
+  if (g_isolated_service_tr) {
+    g_isolated_service_tr->Quit();
+  }
+}
+
+extern "C" JNIEXPORT void JNICALL
+Java_android_perfetto_producer_ProducerService_quitTaskRunner(JNIEnv*, jclass) {
+  std::lock_guard<std::mutex> guard(g_mutex);
+  if (g_service_tr) {
+    g_service_tr->Quit();
+  }
+}
+
+extern "C" JNIEXPORT void JNICALL
 Java_android_perfetto_producer_ProducerActivity_setupProducer(JNIEnv*, jclass) {
-  perfetto::ListenAndRespond("android.perfetto.cts.ProducerActivity");
+  perfetto::ListenAndRespond("android.perfetto.cts.ProducerActivity",
+                             &g_activity_tr);
 }
 
 extern "C" JNIEXPORT void JNICALL
 Java_android_perfetto_producer_ProducerIsolatedService_setupProducer(JNIEnv*,
                                                                      jclass) {
-  perfetto::ListenAndRespond("android.perfetto.cts.ProducerIsolatedService");
+  perfetto::ListenAndRespond("android.perfetto.cts.ProducerIsolatedService",
+                             &g_isolated_service_tr);
 }
 
 extern "C" JNIEXPORT void JNICALL
 Java_android_perfetto_producer_ProducerService_setupProducer(JNIEnv*, jclass) {
-  perfetto::ListenAndRespond("android.perfetto.cts.ProducerService");
+  perfetto::ListenAndRespond("android.perfetto.cts.ProducerService",
+                             &g_service_tr);
 }
diff --git a/test/cts/producer/src/android/perfetto/producer/ProducerActivity.java b/test/cts/producer/src/android/perfetto/producer/ProducerActivity.java
index 1eedfe3..5a8e0c9 100644
--- a/test/cts/producer/src/android/perfetto/producer/ProducerActivity.java
+++ b/test/cts/producer/src/android/perfetto/producer/ProducerActivity.java
@@ -50,6 +50,9 @@
         startForegroundService(new Intent(ProducerActivity.this, ProducerIsolatedService.class));
 
         System.loadLibrary("perfettocts_jni");
+
+        // We make sure at the C++ level that we don't setup multiple producers in the same
+        // process.
         new Thread(new Runnable() {
             public void run() {
                 try {
@@ -58,9 +61,17 @@
                     ex.printStackTrace();
                 }
             }
-        })
-                .start();
+        }).start();
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+
+        quitTaskRunner();
     }
 
     private static native void setupProducer();
+
+    private static native void quitTaskRunner();
 }
diff --git a/test/cts/producer/src/android/perfetto/producer/ProducerIsolatedService.java b/test/cts/producer/src/android/perfetto/producer/ProducerIsolatedService.java
index 9f26f54..943cab9 100644
--- a/test/cts/producer/src/android/perfetto/producer/ProducerIsolatedService.java
+++ b/test/cts/producer/src/android/perfetto/producer/ProducerIsolatedService.java
@@ -58,7 +58,11 @@
     }
 
     @Override
-    public void onDestroy() {}
+    public void onDestroy() {
+        quitTaskRunner();
+    }
 
     private static native void setupProducer();
+
+    private static native void quitTaskRunner();
 }
diff --git a/test/cts/producer/src/android/perfetto/producer/ProducerService.java b/test/cts/producer/src/android/perfetto/producer/ProducerService.java
index a86267a..3b1c3cf 100644
--- a/test/cts/producer/src/android/perfetto/producer/ProducerService.java
+++ b/test/cts/producer/src/android/perfetto/producer/ProducerService.java
@@ -57,7 +57,11 @@
     }
 
     @Override
-    public void onDestroy() {}
+    public void onDestroy() {
+        quitTaskRunner();
+    }
 
     private static native void setupProducer();
+
+    private static native void quitTaskRunner();
 }