Add (un)linkToDeath to generated interfaces.

(un)linkToDeath is now a part of IBase, and can be
called on any generated HIDL interface. The implementation
is a no-op, except in proxy objects, which are by
definition a different process than the interface they point
to.

Since clients are not aware of the transport implementation, we must
wrap the transport-independent callback in a transport-specific
callback object. In case of binder, that object is a
hidl_binder_death_recipient.

The binder proxy object contains a list of registered death
recipients, as well as a mutex to protect access to the list.
The list is required to allow us to map back transport-independent
callbacks to transport-dependent callbacks in unlinkToDeath().

Bug: 31632518
Test: mma, hidl_test
Change-Id: I5083a8789dd706a886a8a09f8c733031a351a36a
diff --git a/generateCpp.cpp b/generateCpp.cpp
index 7ae94b0..04e8f0b 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -392,7 +392,7 @@
                 }
                 out << " {\n";
                 out.indent();
-                method->cppImpl(out);
+                method->cppImpl(IMPL_HEADER, out);
                 out.unindent();
                 out << "\n}\n";
             } else {
@@ -829,6 +829,8 @@
     out << "#ifndef " << guard << "\n";
     out << "#define " << guard << "\n\n";
 
+    out << "#include <hidl/HidlTransportSupport.h>\n\n";
+
     std::vector<std::string> packageComponents;
     getPackageAndVersionComponents(
             &packageComponents, false /* cpp_compatible */);
@@ -866,6 +868,12 @@
     }
 
     out.unindent();
+    out << "private:\n";
+    out.indent();
+    out << "std::mutex _hidl_mMutex;\n"
+        << "std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>>"
+        << " _hidl_mDeathRecipients;\n";
+    out.unindent();
     out << "};\n\n";
 
     enterLeaveNamespace(out, false /* enter */);
@@ -1117,6 +1125,13 @@
 
     out.indent();
 
+    if (method->isHidlReserved() && method->overridesCppImpl(IMPL_PROXY)) {
+        method->cppImpl(IMPL_PROXY, out);
+        out.unindent();
+        out << "}\n\n";
+        return OK;
+    }
+
     if (returnsValue && elidedReturn == nullptr) {
         generateCheckNonNull(out, "_hidl_cb");
     }
@@ -1431,6 +1446,12 @@
 
 status_t AST::generateStubSourceForMethod(
         Formatter &out, const Interface *iface, const Method *method) const {
+    if (method->isHidlReserved() && method->overridesCppImpl(IMPL_STUB)) {
+        method->cppImpl(IMPL_STUB, out);
+        out << "break;\n";
+        return OK;
+    }
+
     out << "if (!_hidl_data.enforceInterface(";
 
     out << iface->fqName().cppNamespace()