Add IServiceManager addWithChain.
am: bb9eb2aa86

Change-Id: Iaf245c3672aa82f5860eb6544903f7ca372a82aa
diff --git a/base/Status.cpp b/base/Status.cpp
index 7161bc0..5a4c918 100644
--- a/base/Status.cpp
+++ b/base/Status.cpp
@@ -82,11 +82,17 @@
 }
 
 Status Status::fromExceptionCode(int32_t exceptionCode) {
+    if (exceptionCode == EX_TRANSACTION_FAILED) {
+        return Status(exceptionCode, FAILED_TRANSACTION);
+    }
     return Status(exceptionCode, OK);
 }
 
 Status Status::fromExceptionCode(int32_t exceptionCode,
                                  const char *message) {
+    if (exceptionCode == EX_TRANSACTION_FAILED) {
+        return Status(exceptionCode, FAILED_TRANSACTION, message);
+    }
     return Status(exceptionCode, OK, message);
 }
 
@@ -107,7 +113,7 @@
 
 void Status::setException(int32_t ex, const char *message) {
     mException = ex;
-    mErrorCode = NO_ERROR;  // an exception, not a transaction failure.
+    mErrorCode = ex == EX_TRANSACTION_FAILED ? FAILED_TRANSACTION : NO_ERROR;
     mMessage = message;
 }
 
diff --git a/transport/HidlBinderSupport.cpp b/transport/HidlBinderSupport.cpp
index a96050c..caf7cf8 100644
--- a/transport/HidlBinderSupport.cpp
+++ b/transport/HidlBinderSupport.cpp
@@ -23,6 +23,7 @@
 #include <hwbinder/IPCThreadState.h>
 
 // C includes
+#include <inttypes.h>
 #include <unistd.h>
 
 // C++ includes
@@ -95,6 +96,15 @@
                 parentOffset + hidl_memory::kOffsetOfName);
     }
 
+    // hidl_memory's size is stored in uint64_t, but mapMemory's mmap will map
+    // size in size_t. If size is over SIZE_MAX, mapMemory could succeed
+    // but the mapped memory's actual size will be smaller than the reported size.
+    if (memory.size() > SIZE_MAX) {
+        ALOGE("Cannot use memory with %" PRId64 " bytes because it is too large.", memory.size());
+        android_errorWriteLog(0x534e4554, "79376389");
+        return BAD_VALUE;
+    }
+
     return _hidl_err;
 }
 
@@ -213,8 +223,7 @@
     // Something really bad has happened, and we're not going to even
     // try returning rich error data.
     if (s.exceptionCode() == Status::EX_TRANSACTION_FAILED) {
-        status_t status = s.transactionError();
-        return status == OK ? FAILED_TRANSACTION : status;
+        return s.transactionError();
     }
 
     status_t status = parcel->writeInt32(s.exceptionCode());
diff --git a/transport/token/1.0/utils/include/hidl/HybridInterface.h b/transport/token/1.0/utils/include/hidl/HybridInterface.h
index 984555e..595c2e3 100644
--- a/transport/token/1.0/utils/include/hidl/HybridInterface.h
+++ b/transport/token/1.0/utils/include/hidl/HybridInterface.h
@@ -240,6 +240,10 @@
         onTransact(
         uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
     if (code == GET_HAL_TOKEN) {
+        if (!data.enforceInterface(BaseInterface::getInterfaceDescriptor())) {
+            return BAD_TYPE;
+        }
+
         HalToken token;
         bool result;
         result = createHalToken(mBase, &token);