Extra branches for getService.

getService should treat failures differently. Failure check
happens at (for hwbinder):

1. defaultServiceManager() == nullptr
2. defaultServiceManager()->get transaction error
3. get returns null
4. in castFrom, calling interfaceChain transaction error
4.1 DEAD_OBJECT
4.2 other transaction error
5. interfaceChain succeeds but cast fails (mismatch)

Test: boots
Test: screenshot / camera / maps
Test: calling Debug.getMemoryInfo from apps does not hang
Test: kill system_server, audio still works
Test: adb push
$OUT/data/nativetest/VtsHalNfcV1_0TargetTest/VtsHalNfcV1_0TargetTest
/data/local/tmp && adb shell /data/local/tmp/VtsHalNfcV1_0TargetTest

Bug: 36153684
Bug: 36611652

Change-Id: I664f8d1a1ccc0e623f31cc7b3b435acc487298d1
diff --git a/generateCpp.cpp b/generateCpp.cpp
index 51ebdc5..27d843c 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -240,18 +240,35 @@
                     << "break;\n";
             }).endl();
 
-            out << "iface = " << interfaceName << "::castFrom(ret);\n";
-            out.sIf("iface == nullptr", [&] {
-                // 1. race condition. hwservicemanager drops the service
-                //    from waitForHwService to here
-                // 2. service is dead (castFrom cannot call interfaceChain)
-                // 3. returned service isn't of correct type; this is a bug
-                //    to hwservicemanager or to the service itself (interfaceChain
-                //    is not consistent)
-                // In all cases, try again.
+            out << "::android::sp<" << gIBaseFqName.cppName() << "> base = ret;\n";
+            out.sIf("base == nullptr", [&] {
+                // race condition. hwservicemanager drops the service
+                // from waitForHwService to here
                 out << "ALOGW(\"getService: found null hwbinder interface\");\n"
                     << "break;\n";
             }).endl();
+            out << "::android::hardware::Return<::android::sp<" << interfaceName
+                << ">> castRet = " << interfaceName << "::castFrom(base, true /* emitError */);\n";
+            out.sIf("!castRet.isOk()", [&] {
+                out.sIf("castRet.isDeadObject()", [&] {
+                    // service is dead (castFrom cannot call interfaceChain)
+                    out << "ALOGW(\"getService: found dead hwbinder service\");\n"
+                        << "break;\n";
+                }).sElse([&] {
+                    out << "ALOGW(\"getService: cannot call into hwbinder service: %s"
+                        << "; No permission? Check for selinux denials.\", "
+                        << "castRet.description().c_str());\n"
+                        << "break;\n";
+                }).endl();
+            }).endl();
+            out << "iface = castRet;\n";
+            out.sIf("iface == nullptr", [&] {
+                // returned service isn't of correct type; this is a bug
+                // to hwservicemanager or to the service itself (interfaceChain
+                // is not consistent).
+                out << "ALOGW(\"getService: received incompatible service; bug in hwservicemanager?\");\n"
+                    << "break;\n";
+            }).endl();
 
             out << "return iface;\n";
         }).endl();
@@ -473,12 +490,12 @@
         std::string childTypeResult = iface->getCppResultType();
 
         for (const Interface *superType : iface->typeChain()) {
-            out << "static "
+            out << "static ::android::hardware::Return<"
                 << childTypeResult
-                << " castFrom("
+                << "> castFrom("
                 << superType->getCppArgumentType()
                 << " parent"
-                << ");\n";
+                << ", bool emitError = false);\n";
         }
 
         out << "\nstatic const char* descriptor;\n\n";
@@ -1883,13 +1900,15 @@
     }
 
     for (const Interface *superType : iface->typeChain()) {
-        out << "// static \n"
+        out << "// static \n::android::hardware::Return<"
             << childTypeResult
-            << " "
+            << "> "
             << iface->localName()
             << "::castFrom("
             << superType->getCppArgumentType()
-            << " parent) {\n";
+            << " parent, bool "
+            << (iface == superType ? "/* emitError */" : "emitError")
+            << ") {\n";
         out.indent();
         if (iface == superType) {
             out << "return parent;\n";
@@ -1904,7 +1923,7 @@
             out.indent();
             out << "parent, \""
                 << iface->fqName().string()
-                << "\");\n";
+                << "\", emitError);\n";
             out.unindent();
             out.unindent();
         }