resolve merge conflicts of 8d92561 to oc-mr1-dev

Test: I solemnly swear I tested this conflict resolution.
Change-Id: I316f817cdf5e828fe3230cd472d448e96639544c
diff --git a/base/include/hidl/HidlSupport.h b/base/include/hidl/HidlSupport.h
index 6807860..f25cdc4 100644
--- a/base/include/hidl/HidlSupport.h
+++ b/base/include/hidl/HidlSupport.h
@@ -316,6 +316,27 @@
         *this = other;
     }
 
+    template <typename InputIterator,
+              typename = typename std::enable_if<std::is_convertible<
+                  typename std::iterator_traits<InputIterator>::iterator_category,
+                  std::input_iterator_tag>::value>::type>
+    hidl_vec(InputIterator first, InputIterator last) : mOwnsBuffer(true) {
+        auto size = std::distance(first, last);
+        if (size > static_cast<int64_t>(UINT32_MAX)) {
+            details::logAlwaysFatal("hidl_vec can't hold more than 2^32 elements.");
+        }
+        if (size < 0) {
+            details::logAlwaysFatal("size can't be negative.");
+        }
+        mSize = static_cast<uint32_t>(size);
+        mBuffer = new T[mSize];
+
+        size_t idx = 0;
+        for (; first != last; ++first) {
+            mBuffer[idx++] = static_cast<T>(*first);
+        }
+    }
+
     ~hidl_vec() {
         if (mOwnsBuffer) {
             delete[] mBuffer;
diff --git a/base/include/hidl/Status.h b/base/include/hidl/Status.h
index 7c716c7..f812ebb 100644
--- a/base/include/hidl/Status.h
+++ b/base/include/hidl/Status.h
@@ -161,9 +161,17 @@
         }
 
         // Check if underlying error is DEAD_OBJECT.
-        // Does not set mCheckedStatus.
+        // Check mCheckedStatus only if this method returns true.
         bool isDeadObject() const {
-            return mStatus.transactionError() == DEAD_OBJECT;
+            bool dead = mStatus.transactionError() == DEAD_OBJECT;
+
+            // This way, if you only check isDeadObject your process will
+            // only be killed for more serious unchecked errors
+            if (dead) {
+                mCheckedStatus = true;
+            }
+
+            return dead;
         }
 
         // For debugging purposes only
diff --git a/test_main.cpp b/test_main.cpp
index bce9294..1f2f845 100644
--- a/test_main.cpp
+++ b/test_main.cpp
@@ -262,6 +262,30 @@
     EXPECT_TRUE(hv1 != hv3);
 }
 
+TEST_F(LibHidlTest, VecRangeCtorTest) {
+    struct ConvertibleType {
+        int val;
+
+        explicit ConvertibleType(int val) : val(val) {}
+        explicit operator int() const { return val; }
+        bool operator==(const int& other) const { return val == other; }
+    };
+
+    std::vector<ConvertibleType> input{
+        ConvertibleType(1), ConvertibleType(2), ConvertibleType(3),
+    };
+
+    android::hardware::hidl_vec<int> hv(input.begin(), input.end());
+
+    EXPECT_EQ(input.size(), hv.size());
+    int sum = 0;
+    for (unsigned i = 0; i < input.size(); i++) {
+        EXPECT_EQ(input[i], hv[i]);
+        sum += hv[i];
+    }
+    EXPECT_EQ(sum, 1 + 2 + 3);
+}
+
 TEST_F(LibHidlTest, ArrayTest) {
     using android::hardware::hidl_array;
     int32_t array[] = {5, 6, 7};
diff --git a/transport/Static.cpp b/transport/Static.cpp
index 18cb475..784b835 100644
--- a/transport/Static.cpp
+++ b/transport/Static.cpp
@@ -32,6 +32,9 @@
 ConcurrentMap<std::string, std::function<sp<IBinder>(void *)>>
         gBnConstructorMap{};
 
+ConcurrentMap<const ::android::hidl::base::V1_0::IBase*, wp<::android::hardware::BHwBinder>>
+    gBnMap{};
+
 ConcurrentMap<wp<::android::hidl::base::V1_0::IBase>, SchedPrio> gServicePrioMap{};
 
 ConcurrentMap<std::string, std::function<sp<::android::hidl::base::V1_0::IBase>(void *)>>
diff --git a/transport/include/hidl/ConcurrentMap.h b/transport/include/hidl/ConcurrentMap.h
index 18881f1..cd55ad4 100644
--- a/transport/include/hidl/ConcurrentMap.h
+++ b/transport/include/hidl/ConcurrentMap.h
@@ -50,7 +50,19 @@
         return mMap.erase(k);
     }
 
-private:
+    std::unique_lock<std::mutex> lock() { return std::unique_lock<std::mutex>(mMutex); }
+
+    void setLocked(K&& k, V&& v) { mMap[std::forward<K>(k)] = std::forward<V>(v); }
+
+    const V& getLocked(const K& k, const V& def) const {
+        const_iterator iter = mMap.find(k);
+        if (iter == mMap.end()) {
+            return def;
+        }
+        return iter->second;
+    }
+
+   private:
     mutable std::mutex mMutex;
     std::map<K, V> mMap;
 };
diff --git a/transport/include/hidl/HidlBinderSupport.h b/transport/include/hidl/HidlBinderSupport.h
index 6f82dbc..47ff581 100644
--- a/transport/include/hidl/HidlBinderSupport.h
+++ b/transport/include/hidl/HidlBinderSupport.h
@@ -306,25 +306,42 @@
 // Otherwise, the smallest possible BnChild is found where IChild is a subclass of IType
 // and iface is of class IChild. BnChild will be used to wrapped the given iface.
 // Return nullptr if iface is null or any failure.
-template <typename IType, typename ProxyType>
+template <typename IType>
 sp<IBinder> toBinder(sp<IType> iface) {
     IType *ifacePtr = iface.get();
     if (ifacePtr == nullptr) {
         return nullptr;
     }
     if (ifacePtr->isRemote()) {
-        return ::android::hardware::IInterface::asBinder(static_cast<ProxyType *>(ifacePtr));
+        return ::android::hardware::IInterface::asBinder(
+            static_cast<BpInterface<IType>*>(ifacePtr));
     } else {
         std::string myDescriptor = details::getDescriptor(ifacePtr);
         if (myDescriptor.empty()) {
             // interfaceDescriptor fails
             return nullptr;
         }
-        auto func = details::gBnConstructorMap.get(myDescriptor, nullptr);
-        if (!func) {
-            return nullptr;
+
+        // for get + set
+        std::unique_lock<std::mutex> _lock = details::gBnMap.lock();
+
+        wp<BHwBinder> wBnObj = details::gBnMap.getLocked(ifacePtr, nullptr);
+        sp<IBinder> sBnObj = wBnObj.promote();
+
+        if (sBnObj == nullptr) {
+            auto func = details::gBnConstructorMap.get(myDescriptor, nullptr);
+            if (!func) {
+                return nullptr;
+            }
+
+            sBnObj = sp<IBinder>(func(static_cast<void*>(ifacePtr)));
+
+            if (sBnObj != nullptr) {
+                details::gBnMap.setLocked(ifacePtr, static_cast<BHwBinder*>(sBnObj.get()));
+            }
         }
-        return sp<IBinder>(func(static_cast<void *>(ifacePtr)));
+
+        return sBnObj;
     }
 }
 
diff --git a/transport/include/hidl/HidlTransportSupport.h b/transport/include/hidl/HidlTransportSupport.h
index 0c174f7..d116598 100644
--- a/transport/include/hidl/HidlTransportSupport.h
+++ b/transport/include/hidl/HidlTransportSupport.h
@@ -62,6 +62,15 @@
 bool setMinSchedulerPolicy(const sp<::android::hidl::base::V1_0::IBase>& service,
                            int policy, int priority);
 
+template <typename ILeft, typename IRight>
+bool interfacesEqual(sp<ILeft> left, sp<IRight> right) {
+    if (left == nullptr || right == nullptr || !left->isRemote() || !right->isRemote()) {
+        return left == right;
+    }
+
+    return toBinder<ILeft>(left) == toBinder<IRight>(right);
+}
+
 namespace details {
 
 // cast the interface IParent to IChild.
@@ -72,8 +81,8 @@
 // 3. !emitError, calling into parent fails.
 // Return an error Return object if:
 // 1. emitError, calling into parent fails.
-template<typename IChild, typename IParent, typename BpChild, typename BpParent>
-Return<sp<IChild>> castInterface(sp<IParent> parent, const char *childIndicator, bool emitError) {
+template <typename IChild, typename IParent, typename BpChild>
+Return<sp<IChild>> castInterface(sp<IParent> parent, const char* childIndicator, bool emitError) {
     if (parent.get() == nullptr) {
         // casts always succeed with nullptrs.
         return nullptr;
@@ -92,7 +101,7 @@
     // TODO b/32001926 Needs to be fixed for socket mode.
     if (parent->isRemote()) {
         // binderized mode. Got BpChild. grab the remote and wrap it.
-        return sp<IChild>(new BpChild(toBinder<IParent, BpParent>(parent)));
+        return sp<IChild>(new BpChild(toBinder<IParent>(parent)));
     }
     // Passthrough mode. Got BnChild and BsChild.
     return sp<IChild>(static_cast<IChild *>(parent.get()));
diff --git a/transport/include/hidl/Static.h b/transport/include/hidl/Static.h
index 0133ff7..63b06fe 100644
--- a/transport/include/hidl/Static.h
+++ b/transport/include/hidl/Static.h
@@ -22,6 +22,7 @@
 #include <android/hidl/base/1.0/IBase.h>
 #include <hidl/ConcurrentMap.h>
 #include <hwbinder/IBinder.h>
+#include <hwbinder/IInterface.h>
 #include <utils/StrongPointer.h>
 
 namespace android {
@@ -33,14 +34,18 @@
     int prio;
 };
 
+extern ConcurrentMap<wp<::android::hidl::base::V1_0::IBase>, SchedPrio> gServicePrioMap;
+
+// For HidlBinderSupport and autogenerated code
+extern ConcurrentMap<const ::android::hidl::base::V1_0::IBase*, wp<::android::hardware::BHwBinder>>
+    gBnMap;
+
 // For HidlBinderSupport and autogenerated code
 // value function receives reinterpret_cast<void *>(static_cast<IFoo *>(foo)),
 // returns sp<IBinder>
 extern ConcurrentMap<std::string,
         std::function<sp<IBinder>(void *)>> gBnConstructorMap;
 
-extern ConcurrentMap<wp<::android::hidl::base::V1_0::IBase>, SchedPrio> gServicePrioMap;
-
 // For HidlPassthroughSupport and autogenerated code
 // value function receives reinterpret_cast<void *>(static_cast<IFoo *>(foo)),
 // returns sp<IBase>
diff --git a/transport/memory/1.0/default/Android.bp b/transport/memory/1.0/default/Android.bp
index b0c601a..93f6370 100644
--- a/transport/memory/1.0/default/Android.bp
+++ b/transport/memory/1.0/default/Android.bp
@@ -23,12 +23,10 @@
         "HidlFetch.cpp"
     ],
     shared_libs: [
-        "liblog",
         "libcutils",
         "libhardware",
         "libhwbinder",
         "libbase",
-        "libcutils",
         "libutils",
         "libhidlbase",
         "libhidltransport",