Add tryGetService.

Required for cases where a hal is being used but we want to fail in
cases where the remote HAL is down. This is also required when someone
wants to get a handle on a hidl service from the only hwbinder thread in
a pool.

Test: hidl_test
Bug: 36780273
Change-Id: I6544f534ef2dff0773c645cc9953de6d1340d01d
diff --git a/generateCpp.cpp b/generateCpp.cpp
index b9739ea..8df7b54 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -125,20 +125,28 @@
     }
 }
 
-static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
-    out << "static ::android::sp<" << interfaceName << "> getService("
+static void declareGetService(Formatter &out, const std::string &interfaceName, bool isTry) {
+    const std::string functionName = isTry ? "tryGetService" : "getService";
+
+    out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
         << "const std::string &serviceName=\"default\", bool getStub=false);\n";
-    out << "static ::android::sp<" << interfaceName << "> getService("
+    out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
         << "const char serviceName[], bool getStub=false)"
         << "  { std::string str(serviceName ? serviceName : \"\");"
-        << "      return getService(str, getStub); }\n";
-    out << "static ::android::sp<" << interfaceName << "> getService("
+        << "      return " << functionName << "(str, getStub); }\n";
+    out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
         << "const ::android::hardware::hidl_string& serviceName, bool getStub=false)"
         // without c_str the std::string constructor is ambiguous
         << "  { std::string str(serviceName.c_str());"
-        << "      return getService(str, getStub); }\n";
-    out << "static ::android::sp<" << interfaceName << "> getService("
-        << "bool getStub) { return getService(\"default\", getStub); }\n";
+        << "      return " << functionName << "(str, getStub); }\n";
+    out << "static ::android::sp<" << interfaceName << "> " << functionName << "("
+        << "bool getStub) { return " << functionName << "(\"default\", getStub); }\n";
+}
+
+static void declareServiceManagerInteractions(Formatter &out, const std::string &interfaceName) {
+    declareGetService(out, interfaceName, true /* isTry */);
+    declareGetService(out, interfaceName, false /* isTry */);
+
     out << "::android::status_t registerAsService(const std::string &serviceName=\"default\");\n";
     out << "static bool registerForNotifications(\n";
     out.indent(2, [&] {
@@ -149,13 +157,15 @@
 
 }
 
-static void implementServiceManagerInteractions(Formatter &out,
-        const FQName &fqName, const std::string &package) {
+static void implementGetService(Formatter &out,
+        const FQName &fqName,
+        bool isTry) {
 
     const std::string interfaceName = fqName.getInterfaceName();
+    const std::string functionName = isTry ? "tryGetService" : "getService";
 
     out << "// static\n"
-        << "::android::sp<" << interfaceName << "> " << interfaceName << "::getService("
+        << "::android::sp<" << interfaceName << "> " << interfaceName << "::" << functionName << "("
         << "const std::string &serviceName, const bool getStub) ";
     out.block([&] {
         out << "::android::sp<" << interfaceName << "> iface = nullptr;\n";
@@ -210,10 +220,12 @@
                     << "break;\n";
             }).endl();
 
-            out.sIf("vintfHwbinder", [&] {
-                out << "::android::hardware::details::waitForHwService("
-                    << interfaceName << "::descriptor" << ", serviceName);\n";
-            }).endl();
+            if (!isTry) {
+                out.sIf("vintfHwbinder", [&] {
+                    out << "::android::hardware::details::waitForHwService("
+                        << interfaceName << "::descriptor" << ", serviceName);\n";
+                }).endl();
+            }
 
             out << "::android::hardware::Return<::android::sp<"
                 << gIBaseFqName.cppName() << ">> ret = \n";
@@ -268,6 +280,15 @@
 
         out << "return iface;\n";
     }).endl().endl();
+}
+
+static void implementServiceManagerInteractions(Formatter &out,
+        const FQName &fqName, const std::string &package) {
+
+    const std::string interfaceName = fqName.getInterfaceName();
+
+    implementGetService(out, fqName, true /* isTry */);
+    implementGetService(out, fqName, false /* isTry */);
 
     out << "::android::status_t " << interfaceName << "::registerAsService("
         << "const std::string &serviceName) ";
diff --git a/test/hidl_test_client.cpp b/test/hidl_test_client.cpp
index 755009d..94921b9 100644
--- a/test/hidl_test_client.cpp
+++ b/test/hidl_test_client.cpp
@@ -498,6 +498,14 @@
     EXPECT_OK(manager->ping());
 }
 
+TEST_F(HidlTest, TryGetServiceTest) {
+    sp<IServiceManager> dne = IServiceManager::tryGetService("boss");
+    ASSERT_EQ(dne, nullptr);
+
+    sp<IServiceManager> manager = IServiceManager::tryGetService();
+    ASSERT_NE(manager, nullptr);
+}
+
 TEST_F(HidlTest, ServiceListTest) {
     static const std::set<std::string> binderizedSet = {
         "android.hardware.tests.pointer@1.0::IPointer/pointer",