Automatically start threadpool.

Generated code should automatically start a threadpool
in one of the following scenarios:
  - You pass an asynchronous interface to a remote process
    (so you can receive calls on it).
  - You register a death recipient on an interface
    (so the kernel can notify you on this thread when it dies).

Also, updated tests to use the new configure/joinThreadPool() API.

Bug: 31748996
Test: mma, hidl_test, hidl_test_java
Change-Id: I2262580282c9b25c2e004dfd928b7444f4be78d9
diff --git a/Interface.cpp b/Interface.cpp
index 1e40bd2..7183ba8 100644
--- a/Interface.cpp
+++ b/Interface.cpp
@@ -89,6 +89,7 @@
                 },
                 {IMPL_PROXY,
                     [](auto &out) {
+                        out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
                         out << "::android::hardware::hidl_binder_death_recipient *binder_recipient"
                             << " = new ::android::hardware::hidl_binder_death_recipient(recipient, cookie, this);\n"
                             << "std::unique_lock<std::mutex> lock(_hidl_mMutex);\n"
diff --git a/generateCpp.cpp b/generateCpp.cpp
index 7f3f4cc..bdc59a1 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -1159,8 +1159,12 @@
     out << "::descriptor);\n";
     out << "if (_hidl_err != ::android::OK) { goto _hidl_error; }\n\n";
 
+    bool hasInterfaceArgument;
     // First DFS: write all buffers and resolve pointers for parent
     for (const auto &arg : method->args()) {
+        if (arg->type().isInterface()) {
+            hasInterfaceArgument = true;
+        }
         emitCppReaderWriter(
                 out,
                 "_hidl_data",
@@ -1183,6 +1187,10 @@
                 false /* addPrefixToName */);
     }
 
+    if (hasInterfaceArgument) {
+        // Start binder threadpool to handle incoming transactions
+        out << "::android::hardware::ProcessState::self()->startThreadPool();\n";
+    }
     out << "_hidl_err = remote()->transact("
         << method->getSerialId()
         << " /* "
diff --git a/test/java_test/hidl_test_java_native.cpp b/test/java_test/hidl_test_java_native.cpp
index f86e43f..58a92b8 100644
--- a/test/java_test/hidl_test_java_native.cpp
+++ b/test/java_test/hidl_test_java_native.cpp
@@ -7,12 +7,9 @@
 
 #include <gtest/gtest.h>
 
+#include <hidl/HidlTransportSupport.h>
 #include <hidl/Status.h>
-#include <hwbinder/IPCThreadState.h>
-#include <hwbinder/ProcessState.h>
-
 using ::android::sp;
-using ::android::Thread;
 using ::android::hardware::tests::baz::V1_0::IBase;
 using ::android::hardware::tests::baz::V1_0::IBaz;
 using ::android::hardware::tests::baz::V1_0::IBazCallback;
@@ -20,6 +17,8 @@
 using ::android::hardware::hidl_array;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::hidl_string;
+using ::android::hardware::configureRpcThreadpool;
+using ::android::hardware::joinRpcThreadpool;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
 
@@ -1090,12 +1089,9 @@
         return status;
     } else {
         sp<Baz> baz = new Baz;
-
+        configureRpcThreadpool(1, true /* callerWillJoin */);
         baz->registerAsService("baz");
-
-        ProcessState::self()->startThreadPool();
-        ProcessState::self()->setThreadPoolMaxThreadCount(0);
-        IPCThreadState::self()->joinThreadPool();
+        joinRpcThreadpool();
     }
 
     return 0;
diff --git a/test/main.cpp b/test/main.cpp
index 259563b..0b98d6b 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -53,8 +53,8 @@
 
 #include <hidl/Status.h>
 #include <hidlmemory/mapping.h>
+
 #include <hwbinder/IPCThreadState.h>
-#include <hwbinder/ProcessState.h>
 
 #include <utils/Condition.h>
 #include <utils/Timers.h>
@@ -95,9 +95,10 @@
 using ::android::hardware::tests::pointer::V1_0::IPointer;
 using ::android::hardware::tests::memory::V1_0::IMemoryTest;
 using ::android::hardware::IPCThreadState;
-using ::android::hardware::ProcessState;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
+using ::android::hardware::configureRpcThreadpool;
+using ::android::hardware::joinRpcThreadpool;
 using ::android::hardware::hidl_array;
 using ::android::hardware::hidl_death_recipient;
 using ::android::hardware::hidl_memory;
@@ -279,6 +280,7 @@
     // binderized service.
     if ((pid = fork()) == 0) {
         // in child process
+        configureRpcThreadpool(1, true /*callerWillJoin*/);
         sp<T> server = T::getService(serviceName, true);
         gServiceName = serviceName;
         signal(SIGTERM, signal_handler);
@@ -289,9 +291,7 @@
             exit(-1);
         }
         ALOGD("SERVER starting %s", serviceName.c_str());
-        ProcessState::self()->setThreadPoolMaxThreadCount(0);
-        ProcessState::self()->startThreadPool();
-        IPCThreadState::self()->joinThreadPool();
+        joinRpcThreadpool();
         ALOGD("SERVER %s ends.", serviceName.c_str());
         exit(0);
     }
@@ -338,7 +338,6 @@
     }
 
     void getServices() {
-
         manager = IServiceManager::getService("manager");
 
         // alternatively:
@@ -590,9 +589,6 @@
         std::string instanceName = "test-instance";
         EXPECT_TRUE(ISimple::registerForNotifications(instanceName, notification));
 
-        ProcessState::self()->setThreadPoolMaxThreadCount(0);
-        ProcessState::self()->startThreadPool();
-
         Simple* instance = new Simple(1);
         EXPECT_EQ(::android::OK, instance->registerAsService(instanceName));
 
@@ -623,9 +619,6 @@
         std::string instanceTwo = "test-instance-two";
         EXPECT_TRUE(ISimple::registerForNotifications("", notification));
 
-        ProcessState::self()->setThreadPoolMaxThreadCount(0);
-        ProcessState::self()->startThreadPool();
-
         Simple* instanceA = new Simple(1);
         EXPECT_EQ(::android::OK, instanceA->registerAsService(instanceOne));
         Simple* instanceB = new Simple(2);
@@ -1232,10 +1225,6 @@
 };
 
 TEST_F(HidlTest, DeathRecipientTest) {
-    // Need a threadpool to receive death calls from the kernel
-    ProcessState::self()->setThreadPoolMaxThreadCount(0);
-    ProcessState::self()->startThreadPool();
-
     sp<HidlDeathRecipient> recipient = new HidlDeathRecipient();
     sp<HidlDeathRecipient> recipient2 = new HidlDeathRecipient();