Merge "Zero-init HIDL core types (hidl_handle)."
diff --git a/base/HidlSupport.cpp b/base/HidlSupport.cpp
index 65863b4..f97f216 100644
--- a/base/HidlSupport.cpp
+++ b/base/HidlSupport.cpp
@@ -138,10 +138,11 @@
 
 static const char *const kEmptyString = "";
 
-hidl_string::hidl_string()
-    : mBuffer(kEmptyString),
-      mSize(0),
-      mOwnsBuffer(false) {
+hidl_string::hidl_string() {
+    memset(this, 0, sizeof(*this));
+    // mSize is zero
+    // mOwnsBuffer is false
+    mBuffer = kEmptyString;
 }
 
 hidl_string::~hidl_string() {
diff --git a/base/include/hidl/HidlInternal.h b/base/include/hidl/HidlInternal.h
index 6377c46..0b80cd4 100644
--- a/base/include/hidl/HidlInternal.h
+++ b/base/include/hidl/HidlInternal.h
@@ -68,6 +68,7 @@
 struct hidl_pointer {
     hidl_pointer()
         : _pad(0) {
+        static_assert(sizeof(*this) == 8, "wrong size");
     }
     hidl_pointer(T* ptr) : hidl_pointer() { mPointer = ptr; }
     hidl_pointer(const hidl_pointer<T>& other) : hidl_pointer() { mPointer = other.mPointer; }
diff --git a/base/include/hidl/HidlSupport.h b/base/include/hidl/HidlSupport.h
index 55f21ea..7812099 100644
--- a/base/include/hidl/HidlSupport.h
+++ b/base/include/hidl/HidlSupport.h
@@ -326,11 +326,15 @@
 
 template<typename T>
 struct hidl_vec {
-    hidl_vec()
-        : mBuffer(nullptr),
-          mSize(0),
-          mOwnsBuffer(true) {
+    hidl_vec() {
         static_assert(hidl_vec<T>::kOffsetOfBuffer == 0, "wrong offset");
+
+        memset(this, 0, sizeof(*this));
+        // mSize is 0
+        // mBuffer is nullptr
+
+        // this is for consistency with the original implementation
+        mOwnsBuffer = true;
     }
 
     // Note, does not initialize primitive types.
@@ -340,8 +344,7 @@
         *this = other;
     }
 
-    hidl_vec(hidl_vec<T> &&other) noexcept
-    : mOwnsBuffer(false) {
+    hidl_vec(hidl_vec<T> &&other) noexcept : hidl_vec() {
         *this = std::move(other);
     }
 
@@ -355,7 +358,7 @@
               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) {
+    hidl_vec(InputIterator first, InputIterator last) : hidl_vec() {
         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.");
@@ -365,6 +368,7 @@
         }
         mSize = static_cast<uint32_t>(size);
         mBuffer = new T[mSize];
+        mOwnsBuffer = true;
 
         size_t idx = 0;
         for (; first != last; ++first) {
@@ -849,7 +853,9 @@
 // Version functions
 struct hidl_version {
 public:
-    constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {}
+    constexpr hidl_version(uint16_t major, uint16_t minor) : mMajor(major), mMinor(minor) {
+        static_assert(sizeof(*this) == 4, "wrong size");
+    }
 
     bool operator==(const hidl_version& other) const {
         return (mMajor == other.get_major() && mMinor == other.get_minor());
diff --git a/transport/HidlBinderSupport.cpp b/transport/HidlBinderSupport.cpp
index caf7cf8..62b1755 100644
--- a/transport/HidlBinderSupport.cpp
+++ b/transport/HidlBinderSupport.cpp
@@ -256,16 +256,16 @@
     }
 
     // for get + set
-    std::unique_lock<std::mutex> _lock = details::gBnMap.lock();
+    std::unique_lock<std::mutex> _lock = details::gBnMap->lock();
 
-    wp<BHwBinder> wBnObj = details::gBnMap.getLocked(ifacePtr, nullptr);
+    wp<BHwBinder> wBnObj = details::gBnMap->getLocked(ifacePtr, nullptr);
     sp<IBinder> sBnObj = wBnObj.promote();
 
     if (sBnObj == nullptr) {
         auto func = details::getBnConstructorMap().get(descriptor, nullptr);
         if (!func) {
             // TODO(b/69122224): remove this static variable when prebuilts updated
-            func = details::gBnConstructorMap.get(descriptor, nullptr);
+            func = details::gBnConstructorMap->get(descriptor, nullptr);
         }
         LOG_ALWAYS_FATAL_IF(func == nullptr, "%s gBnConstructorMap returned null for %s", __func__,
                             descriptor.c_str());
@@ -274,7 +274,7 @@
         LOG_ALWAYS_FATAL_IF(sBnObj == nullptr, "%s Bn constructor function returned null for %s",
                             __func__, descriptor.c_str());
 
-        details::gBnMap.setLocked(ifacePtr, static_cast<BHwBinder*>(sBnObj.get()));
+        details::gBnMap->setLocked(ifacePtr, static_cast<BHwBinder*>(sBnObj.get()));
     }
 
     return sBnObj;
diff --git a/transport/HidlPassthroughSupport.cpp b/transport/HidlPassthroughSupport.cpp
index ff68a1e..bc67656 100644
--- a/transport/HidlPassthroughSupport.cpp
+++ b/transport/HidlPassthroughSupport.cpp
@@ -31,7 +31,7 @@
     auto func = getBsConstructorMap().get(descriptor, nullptr);
     if (!func) {
         // TODO(b/69122224): remove this when prebuilts don't reference it
-        func = gBsConstructorMap.get(descriptor, nullptr);
+        func = gBsConstructorMap->get(descriptor, nullptr);
     }
     if (func) {
         return func(static_cast<void*>(iface.get()));
diff --git a/transport/HidlTransportSupport.cpp b/transport/HidlTransportSupport.cpp
index db70438..b433b70 100644
--- a/transport/HidlTransportSupport.cpp
+++ b/transport/HidlTransportSupport.cpp
@@ -85,9 +85,9 @@
     // Due to ABI considerations, IBase cannot have a destructor to clean this up.
     // So, because this API is so infrequently used, (expected to be usually only
     // one time for a process, but it can be more), we are cleaning it up here.
-    std::unique_lock<std::mutex> lock = details::gServicePrioMap.lock();
-    pruneMapLocked(details::gServicePrioMap);
-    details::gServicePrioMap.setLocked(service, {policy, priority});
+    std::unique_lock<std::mutex> lock = details::gServicePrioMap->lock();
+    pruneMapLocked(details::gServicePrioMap.get());
+    details::gServicePrioMap->setLocked(service, {policy, priority});
 
     return true;
 }
@@ -101,9 +101,9 @@
     // Due to ABI considerations, IBase cannot have a destructor to clean this up.
     // So, because this API is so infrequently used, (expected to be usually only
     // one time for a process, but it can be more), we are cleaning it up here.
-    std::unique_lock<std::mutex> lock = details::gServiceSidMap.lock();
-    pruneMapLocked(details::gServiceSidMap);
-    details::gServiceSidMap.setLocked(service, requesting);
+    std::unique_lock<std::mutex> lock = details::gServiceSidMap->lock();
+    pruneMapLocked(details::gServiceSidMap.get());
+    details::gServiceSidMap->setLocked(service, requesting);
 
     return true;
 }
diff --git a/transport/InternalStatic.h b/transport/InternalStatic.h
index b0fefa9..1dfaae4 100644
--- a/transport/InternalStatic.h
+++ b/transport/InternalStatic.h
@@ -26,10 +26,12 @@
 namespace hardware {
 namespace details {
 
+// TODO(b/69122224): remove this
 // deprecated; use getBnConstructorMap instead.
-extern BnConstructorMap gBnConstructorMap;
+extern DoNotDestruct<BnConstructorMap> gBnConstructorMap;
+// TODO(b/69122224): remove this
 // deprecated; use getBsConstructorMap instead.
-extern BsConstructorMap gBsConstructorMap;
+extern DoNotDestruct<BsConstructorMap> gBsConstructorMap;
 
 }  // namespace details
 }  // namespace hardware
diff --git a/transport/Static.cpp b/transport/Static.cpp
index 0bbd48d..af16e8f 100644
--- a/transport/Static.cpp
+++ b/transport/Static.cpp
@@ -28,27 +28,28 @@
 namespace details {
 
 // Deprecated; kept for ABI compatibility. Use getBnConstructorMap.
-BnConstructorMap gBnConstructorMap{};
+DoNotDestruct<BnConstructorMap> gBnConstructorMap{};
 
-ConcurrentMap<const ::android::hidl::base::V1_0::IBase*, wp<::android::hardware::BHwBinder>>
-    gBnMap{};
+DoNotDestruct<ConcurrentMap<const ::android::hidl::base::V1_0::IBase*,
+                            wp<::android::hardware::BHwBinder>>>
+        gBnMap{};
 
 // TODO(b/122472540): replace with single, hidden map
-ConcurrentMap<wp<::android::hidl::base::V1_0::IBase>, SchedPrio> gServicePrioMap{};
-ConcurrentMap<wp<::android::hidl::base::V1_0::IBase>, bool> gServiceSidMap{};
+DoNotDestruct<ConcurrentMap<wp<::android::hidl::base::V1_0::IBase>, SchedPrio>> gServicePrioMap{};
+DoNotDestruct<ConcurrentMap<wp<::android::hidl::base::V1_0::IBase>, bool>> gServiceSidMap{};
 
 // Deprecated; kept for ABI compatibility. Use getBsConstructorMap.
-BsConstructorMap gBsConstructorMap{};
+DoNotDestruct<BsConstructorMap> gBsConstructorMap{};
 
 // For static executables, it is not guaranteed that gBnConstructorMap are initialized before
 // used in HAL definition libraries.
 BnConstructorMap& getBnConstructorMap() {
-    static BnConstructorMap map{};
+    static BnConstructorMap& map = *new BnConstructorMap();
     return map;
 }
 
 BsConstructorMap& getBsConstructorMap() {
-    static BsConstructorMap map{};
+    static BsConstructorMap& map = *new BsConstructorMap();
     return map;
 }
 
diff --git a/transport/allocator/1.0/Android.bp b/transport/allocator/1.0/Android.bp
index a3d885a..80364a7 100644
--- a/transport/allocator/1.0/Android.bp
+++ b/transport/allocator/1.0/Android.bp
@@ -14,4 +14,3 @@
     ],
     gen_java: false,
 }
-
diff --git a/transport/base/1.0/Android.bp b/transport/base/1.0/Android.bp
index cebb01b..f90831e 100644
--- a/transport/base/1.0/Android.bp
+++ b/transport/base/1.0/Android.bp
@@ -12,4 +12,3 @@
     ],
     gen_java: true,
 }
-
diff --git a/transport/include/hidl/ConcurrentMap.h b/transport/include/hidl/ConcurrentMap.h
index 1b06dfd..329752c 100644
--- a/transport/include/hidl/ConcurrentMap.h
+++ b/transport/include/hidl/ConcurrentMap.h
@@ -90,6 +90,23 @@
     std::map<K, V> mMap;
 };
 
+namespace details {
+
+// TODO(b/69122224): remove this type and usages of it
+// DO NOT ADD USAGES
+template <typename T>
+class DoNotDestruct {
+  public:
+    DoNotDestruct() { new (buffer) T(); }
+    T& get() { return *reinterpret_cast<T*>(buffer); }
+    T* operator->() { return reinterpret_cast<T*>(buffer); }
+
+  private:
+    alignas(T) char buffer[sizeof(T)];
+};
+
+}  // namespace details
+
 }  // namespace hardware
 }  // namespace android
 
diff --git a/transport/include/hidl/Static.h b/transport/include/hidl/Static.h
index cc711b7..be74bae 100644
--- a/transport/include/hidl/Static.h
+++ b/transport/include/hidl/Static.h
@@ -37,12 +37,17 @@
     int prio;
 };
 
-extern ConcurrentMap<wp<::android::hidl::base::V1_0::IBase>, SchedPrio> gServicePrioMap;
-extern ConcurrentMap<wp<::android::hidl::base::V1_0::IBase>, bool> gServiceSidMap;
+// TODO(b/69122224): remove this
+extern DoNotDestruct<ConcurrentMap<wp<::android::hidl::base::V1_0::IBase>, SchedPrio>>
+        gServicePrioMap;
+// TODO(b/69122224): remove this
+extern DoNotDestruct<ConcurrentMap<wp<::android::hidl::base::V1_0::IBase>, bool>> gServiceSidMap;
 
+// TODO(b/69122224): remove this
 // For HidlBinderSupport and autogenerated code
-extern ConcurrentMap<const ::android::hidl::base::V1_0::IBase*, wp<::android::hardware::BHwBinder>>
-    gBnMap;
+extern DoNotDestruct<ConcurrentMap<const ::android::hidl::base::V1_0::IBase*,
+                                   wp<::android::hardware::BHwBinder>>>
+        gBnMap;
 
 using BnConstructorMap = ConcurrentMap<std::string, std::function<sp<IBinder>(void*)>>;
 // For HidlBinderSupport and autogenerated code
diff --git a/transport/manager/1.0/Android.bp b/transport/manager/1.0/Android.bp
index 869c58e..c91dcd2 100644
--- a/transport/manager/1.0/Android.bp
+++ b/transport/manager/1.0/Android.bp
@@ -15,4 +15,3 @@
     ],
     gen_java: true,
 }
-
diff --git a/transport/manager/1.1/Android.bp b/transport/manager/1.1/Android.bp
index 407dfa3..82545e5 100644
--- a/transport/manager/1.1/Android.bp
+++ b/transport/manager/1.1/Android.bp
@@ -15,4 +15,3 @@
     ],
     gen_java: true,
 }
-
diff --git a/transport/manager/1.2/Android.bp b/transport/manager/1.2/Android.bp
index 3f02f78..e7ee143 100644
--- a/transport/manager/1.2/Android.bp
+++ b/transport/manager/1.2/Android.bp
@@ -17,4 +17,3 @@
     ],
     gen_java: true,
 }
-
diff --git a/transport/memory/1.0/Android.bp b/transport/memory/1.0/Android.bp
index eaa3037..dd76889 100644
--- a/transport/memory/1.0/Android.bp
+++ b/transport/memory/1.0/Android.bp
@@ -16,4 +16,3 @@
     ],
     gen_java: false,
 }
-
diff --git a/transport/safe_union/1.0/Android.bp b/transport/safe_union/1.0/Android.bp
index 88c7d5d..2760863 100644
--- a/transport/safe_union/1.0/Android.bp
+++ b/transport/safe_union/1.0/Android.bp
@@ -12,4 +12,3 @@
     ],
     gen_java: true,
 }
-
diff --git a/transport/token/1.0/Android.bp b/transport/token/1.0/Android.bp
index c0988cb..28f16f7 100644
--- a/transport/token/1.0/Android.bp
+++ b/transport/token/1.0/Android.bp
@@ -14,4 +14,3 @@
     ],
     gen_java: true,
 }
-
diff --git a/vintfdata/Android.mk b/vintfdata/Android.mk
index 3db7065..78351fe 100644
--- a/vintfdata/Android.mk
+++ b/vintfdata/Android.mk
@@ -44,10 +44,13 @@
 GEN := $(local-generated-sources-dir)/compatibility_matrix.xml
 
 $(GEN): PRIVATE_VINTF_VNDK_VERSION := $(VINTF_VNDK_VERSION)
+$(GEN): PRIVATE_DEVICE_MATRIX_INPUT_FILE := $(DEVICE_MATRIX_INPUT_FILE)
 $(GEN): $(DEVICE_MATRIX_INPUT_FILE) $(HOST_OUT_EXECUTABLES)/assemble_vintf
 	REQUIRED_VNDK_VERSION=$(PRIVATE_VINTF_VNDK_VERSION) \
 	BOARD_SYSTEMSDK_VERSIONS="$(BOARD_SYSTEMSDK_VERSIONS)" \
-		$(HOST_OUT_EXECUTABLES)/assemble_vintf -i $< -o $@
+		$(HOST_OUT_EXECUTABLES)/assemble_vintf \
+		-i $(call normalize-path-list,$(PRIVATE_DEVICE_MATRIX_INPUT_FILE)) \
+		-o $@
 
 LOCAL_PREBUILT_MODULE_FILE := $(GEN)
 include $(BUILD_PREBUILT)
@@ -77,4 +80,4 @@
 
 VINTF_VNDK_VERSION :=
 FRAMEWORK_MANIFEST_INPUT_FILES :=
-DEVICE_MATRIX_INPUT_FILE :=
\ No newline at end of file
+DEVICE_MATRIX_INPUT_FILE :=