Merge "Add test cases for MemoryDealer"
diff --git a/base/HidlInternal.cpp b/base/HidlInternal.cpp
index 10e250b..babdac1 100644
--- a/base/HidlInternal.cpp
+++ b/base/HidlInternal.cpp
@@ -35,6 +35,11 @@
 const char* kGcovPrefixOverrideEnvVar = "GCOV_PREFIX_OVERRIDE";
 const char* kGcovPrefixPath = "/data/misc/trace/";
 const char* kSysPropHalCoverage = "hal.coverage.enable";
+#if defined(__LP64__)
+const char* kSysPropInstrumentationPath = "hal.instrumentation.lib.path.64";
+#else
+const char* kSysPropInstrumentationPath = "hal.instrumentation.lib.path.32";
+#endif
 #endif
 
 namespace android {
@@ -66,8 +71,8 @@
     : mEnableInstrumentation(false),
       mInstrumentationLibPackage(package),
       mInterfaceName(interface) {
-    configureInstrumentation(false);
 #ifdef LIBHIDL_TARGET_DEBUGGABLE
+    configureInstrumentation(false);
     if (__sanitizer_cov_dump != nullptr) {
         ::android::add_sysprop_change_callback(
             []() {
@@ -115,22 +120,18 @@
 HidlInstrumentor::~HidlInstrumentor() {}
 
 void HidlInstrumentor::configureInstrumentation(bool log) {
-    bool enableInstrumentation = property_get_bool(
-            "hal.instrumentation.enable",
-            false);
-    if (enableInstrumentation != mEnableInstrumentation) {
-        mEnableInstrumentation = enableInstrumentation;
-        if (mEnableInstrumentation) {
-            if (log) {
-                LOG(INFO) << "Enable instrumentation.";
-            }
-            registerInstrumentationCallbacks (&mInstrumentationCallbacks);
-        } else {
-            if (log) {
-                LOG(INFO) << "Disable instrumentation.";
-            }
-            mInstrumentationCallbacks.clear();
+    mEnableInstrumentation = property_get_bool("hal.instrumentation.enable", false);
+    if (mEnableInstrumentation) {
+        if (log) {
+            LOG(INFO) << "Enable instrumentation.";
         }
+        mInstrumentationCallbacks.clear();
+        registerInstrumentationCallbacks(&mInstrumentationCallbacks);
+    } else {
+        if (log) {
+            LOG(INFO) << "Disable instrumentation.";
+        }
+        mInstrumentationCallbacks.clear();
     }
 }
 
@@ -139,9 +140,7 @@
 #ifdef LIBHIDL_TARGET_DEBUGGABLE
     std::vector<std::string> instrumentationLibPaths;
     char instrumentationLibPath[PROPERTY_VALUE_MAX];
-    if (property_get("hal.instrumentation.lib.path",
-                     instrumentationLibPath,
-                     "") > 0) {
+    if (property_get(kSysPropInstrumentationPath, instrumentationLibPath, "") > 0) {
         instrumentationLibPaths.push_back(instrumentationLibPath);
     } else {
         static std::string halLibPathVndkSp = android::base::StringPrintf(
diff --git a/transport/Android.bp b/transport/Android.bp
index 77cfe27..5b0c11c 100644
--- a/transport/Android.bp
+++ b/transport/Android.bp
@@ -38,7 +38,6 @@
         "libvndksupport",
     ],
     export_shared_lib_headers: [
-        "libbase",
         "libutils",
         "libhidlbase",
     ],
diff --git a/transport/Android.mk b/transport/Android.mk
index 8012835..8060f3b 100644
--- a/transport/Android.mk
+++ b/transport/Android.mk
@@ -58,3 +58,5 @@
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
 endif # TARGET_BUILD_PDK not true
+
+include $(LOCAL_PATH)/base/1.0/vts/functional/Android.mk
diff --git a/transport/HidlPassthroughSupport.cpp b/transport/HidlPassthroughSupport.cpp
index b79d21c..c5ca1c9 100644
--- a/transport/HidlPassthroughSupport.cpp
+++ b/transport/HidlPassthroughSupport.cpp
@@ -25,30 +25,55 @@
 namespace hardware {
 namespace details {
 
+// TODO(b/69122224) remove once prebuilts are updated.
+extern BsConstructorMap gBsConstructorMap;
+
+static sp<IBase> tryWrap(const std::string& descriptor, sp<IBase> iface) {
+    auto func = getBsConstructorMap().get(descriptor, nullptr);
+    if (!func) {
+        func = gBsConstructorMap.get(descriptor, nullptr);
+    }
+    if (func) {
+        return func(static_cast<void*>(iface.get()));
+    }
+    return nullptr;
+}
+
 sp<IBase> wrapPassthroughInternal(sp<IBase> iface) {
     if (iface == nullptr || iface->isRemote()) {
         // doesn't know how to handle it.
         return iface;
     }
-    std::string myDescriptor = getDescriptor(iface.get());
-    if (myDescriptor.empty()) {
-        // interfaceDescriptor fails
+
+    // Consider the case when an AOSP interface is extended by partners.
+    // Then the partner's HAL interface library is loaded only in the vndk
+    // linker namespace, but not in the default linker namespace, where
+    // this code runs. As a result, BsConstructorMap in the latter does not
+    // have the entry for the descriptor name.
+    //
+    // Therefore, we try to wrap using the descript names of the parent
+    // types along the interface chain, instead of always using the descriptor
+    // name of the current interface.
+    sp<IBase> base;
+    auto ret = iface->interfaceChain([&](const auto& types) {
+        for (const std::string& descriptor : types) {
+            base = tryWrap(descriptor, iface);
+            if (base != nullptr) {
+                break;  // wrap is successful. no need to lookup further.
+            }
+        }
+    });
+
+    if (!ret.isOk()) {
         return nullptr;
     }
-    auto func = getBsConstructorMap().get(myDescriptor, nullptr);
-    if (!func) {
-        func = gBsConstructorMap.get(myDescriptor, nullptr);
-        if (!func) {
-            return nullptr;
-        }
-    }
 
-    sp<IBase> base = func(static_cast<void*>(iface.get()));
-
-    // To ensure this is an instance of IType, we would normally
-    // call castFrom, but gBsConstructorMap guarantees that its
-    // result is of the appropriate type (not necessaryly BsType,
-    // but definitely a child of IType).
+    // It is ensured that if this function is called with an instance of IType
+    // then the corresponding descriptor would be in the BsConstructorMap.
+    // This is because referencing IType implies that the interface library
+    // defining the type has already been loaded into the current linker
+    // namespace, and thus the library should have added an entry into the
+    // BsConstructorMap while executing the library's constructor.
     return base;
 }
 
diff --git a/transport/ServiceManagement.cpp b/transport/ServiceManagement.cpp
index ef86f99..e3c19e5 100644
--- a/transport/ServiceManagement.cpp
+++ b/transport/ServiceManagement.cpp
@@ -485,8 +485,7 @@
         // that thread, it will block forever because we hung up the one and only
         // binder thread on a condition variable that can only be notified by an
         // incoming binder call.
-        if (ProcessState::self()->getMaxThreads() <= 1 &&
-                IPCThreadState::self()->isLooperThread()) {
+        if (IPCThreadState::self()->isOnlyBinderThread()) {
             LOG(WARNING) << "Can't efficiently wait for " << mInterfaceName << "/"
                          << mInstanceName << ", because we are called from "
                          << "the only binder thread in this process.";
@@ -512,12 +511,9 @@
     }
 
     ~Waiter() {
-        if (mRegisteredForNotifications) {
-            if (!mSm->unregisterForNotifications(mInterfaceName, mInstanceName, this).
-                    withDefault(false)) {
-                LOG(ERROR) << "Could not unregister service notification for "
-                    << mInterfaceName << "/" << mInstanceName << ".";
-            }
+        if (!mDoneCalled) {
+            LOG(FATAL)
+                << "Waiter still registered for notifications, call done() before dropping ref!";
         }
     }
 
@@ -568,7 +564,23 @@
         std::unique_lock<std::mutex> lock(mMutex);
         mRegistered = false;
     }
-private:
+
+    // done() must be called before dropping the last strong ref to the Waiter, to make
+    // sure we can properly unregister with hwservicemanager.
+    void done() {
+        if (mRegisteredForNotifications) {
+            if (!mSm->unregisterForNotifications(mInterfaceName, mInstanceName, this)
+                     .withDefault(false)) {
+                LOG(ERROR) << "Could not unregister service notification for " << mInterfaceName
+                           << "/" << mInstanceName << ".";
+            } else {
+                mRegisteredForNotifications = false;
+            }
+        }
+        mDoneCalled = true;
+    }
+
+   private:
     const std::string mInterfaceName;
     const std::string mInstanceName;
     const sp<IServiceManager1_1>& mSm;
@@ -576,12 +588,14 @@
     std::condition_variable mCondition;
     bool mRegistered = false;
     bool mRegisteredForNotifications = false;
+    bool mDoneCalled = false;
 };
 
 void waitForHwService(
         const std::string &interface, const std::string &instanceName) {
     sp<Waiter> waiter = new Waiter(interface, instanceName, defaultServiceManager1_1());
     waiter->wait();
+    waiter->done();
 }
 
 // Prints relevant error/warning messages for error return values from
@@ -671,6 +685,7 @@
                 details::canCastInterface(base.get(), descriptor.c_str(), true /* emitError */);
 
             if (canCastRet.isOk() && canCastRet) {
+                waiter->done();
                 return base; // still needs to be wrapped by Bp class.
             }
 
@@ -684,6 +699,8 @@
         waiter->wait();
     }
 
+    waiter->done();
+
     if (getStub || vintfPassthru || vintfLegacy) {
         const sp<IServiceManager> pm = getPassthroughServiceManager();
         if (pm != nullptr) {
diff --git a/transport/Static.cpp b/transport/Static.cpp
index cbe6add..40e0c59 100644
--- a/transport/Static.cpp
+++ b/transport/Static.cpp
@@ -30,6 +30,7 @@
 sp<android::hidl::manager::V1_0::IServiceManager> gDefaultServiceManager;
 
 // Deprecated; kept for ABI compatibility. Use getBnConstructorMap.
+// TODO(b/69122224) remove once prebuilts are updated.
 BnConstructorMap gBnConstructorMap{};
 
 ConcurrentMap<const ::android::hidl::base::V1_0::IBase*, wp<::android::hardware::BHwBinder>>
@@ -38,6 +39,7 @@
 ConcurrentMap<wp<::android::hidl::base::V1_0::IBase>, SchedPrio> gServicePrioMap{};
 
 // Deprecated; kept for ABI compatibility. Use getBsConstructorMap.
+// TODO(b/69122224) remove once prebuilts are updated.
 BsConstructorMap gBsConstructorMap{};
 
 // For static executables, it is not guaranteed that gBnConstructorMap are initialized before
diff --git a/transport/base/1.0/vts/functional/Android.bp b/transport/base/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..f0bd45c
--- /dev/null
+++ b/transport/base/1.0/vts/functional/Android.bp
@@ -0,0 +1,34 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//       http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+
+cc_test {
+    name: "vts_ibase_test",
+    srcs: [
+        "vts_ibase_test.cpp",
+    ],
+    cflags: [
+        "-Wall",
+        "-Werror",
+    ],
+    shared_libs: [
+        "libbase",
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+    ],
+}
+
diff --git a/transport/base/1.0/vts/functional/Android.mk b/transport/base/1.0/vts/functional/Android.mk
new file mode 100644
index 0000000..61c6e31
--- /dev/null
+++ b/transport/base/1.0/vts/functional/Android.mk
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := VtsHalBaseV1_0TargetTest
+-include test/vts/tools/build/Android.host_config.mk
diff --git a/transport/base/1.0/vts/functional/AndroidTest.xml b/transport/base/1.0/vts/functional/AndroidTest.xml
new file mode 100644
index 0000000..80154f2
--- /dev/null
+++ b/transport/base/1.0/vts/functional/AndroidTest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Config for VTS VtsHalBaseV1_0TargetTest test cases">
+    <option name="config-descriptor:metadata" key="plan" value="vts-treble" />
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.VtsFilePusher">
+        <option name="abort-on-push-failure" value="false"/>
+        <option name="push-group" value="HalHidlTargetTest.push"/>
+    </target_preparer>
+    <multi_target_preparer class="com.android.tradefed.targetprep.VtsPythonVirtualenvPreparer" />
+    <test class="com.android.tradefed.testtype.VtsMultiDeviceTest">
+        <option name="test-module-name" value="VtsHalBaseV1_0TargetTest"/>
+        <option name="binary-test-working-directory" value="_32bit::/data/nativetest/" />
+        <option name="binary-test-working-directory" value="_64bit::/data/nativetest64/" />
+        <option name="binary-test-source" value="_32bit::DATA/nativetest/vts_ibase_test/vts_ibase_test" />
+        <option name="binary-test-source" value="_64bit::DATA/nativetest64/vts_ibase_test/vts_ibase_test" />
+        <option name="binary-test-type" value="gtest"/>
+        <option name="test-timeout" value="5m"/>
+    </test>
+</configuration>
diff --git a/transport/base/1.0/vts/functional/vts_ibase_test.cpp b/transport/base/1.0/vts/functional/vts_ibase_test.cpp
new file mode 100644
index 0000000..6d66042
--- /dev/null
+++ b/transport/base/1.0/vts/functional/vts_ibase_test.cpp
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <functional>
+#include <map>
+#include <string>
+
+#include <android/hidl/base/1.0/IBase.h>
+#include <android/hidl/manager/1.0/IServiceManager.h>
+#include <gtest/gtest.h>
+#include <hidl/HidlBinderSupport.h>
+#include <hidl/ServiceManagement.h>
+
+using android::hardware::hidl_array;
+using android::hardware::hidl_death_recipient;
+using android::hardware::hidl_handle;
+using android::hardware::hidl_string;
+using android::hardware::hidl_vec;
+using android::hardware::IBinder;
+using android::hardware::toBinder;
+using android::hidl::base::V1_0::IBase;
+using android::hidl::manager::V1_0::IServiceManager;
+using android::sp;
+using android::wp;
+
+template <typename T>
+static inline ::testing::AssertionResult isOk(const ::android::hardware::Return<T>& ret) {
+    return ret.isOk() ? (::testing::AssertionSuccess() << ret.description())
+                      : (::testing::AssertionFailure() << ret.description());
+}
+#define ASSERT_OK(__ret__) ASSERT_TRUE(isOk(__ret__))
+#define EXPECT_OK(__ret__) EXPECT_TRUE(isOk(__ret__))
+
+struct Hal {
+    sp<IBase> service;
+    std::string name;  // space separated list of android.hidl.foo@1.0::IFoo/instance-name
+};
+
+class VtsHalBaseV1_0TargetTest : public ::testing::Test {
+   public:
+    virtual void SetUp() override {
+        default_manager_ = ::android::hardware::defaultServiceManager();
+
+        ASSERT_NE(default_manager_, nullptr)
+            << "Failed to get default service manager." << std::endl;
+
+        ASSERT_OK(default_manager_->list([&](const auto& list) {
+            for (const auto& name : list) {
+                const std::string strName = name;
+                auto loc = strName.find_first_of('/');
+                if (loc == std::string::npos) {
+                    ADD_FAILURE() << "Invalid FQName: " << strName;
+                    continue;
+                }
+                const std::string fqName = strName.substr(0, loc);
+                const std::string instance = strName.substr(loc + 1);
+
+                sp<IBase> service = default_manager_->get(fqName, instance);
+                if (service == nullptr) {
+                    ADD_FAILURE() << "Null service for " << name << " " << fqName << " "
+                                  << instance;
+                    continue;
+                }
+
+                sp<IBinder> binder = toBinder(service);
+                if (binder == nullptr) {
+                    ADD_FAILURE() << "Null binder for " << name;
+                    continue;
+                }
+
+                auto iter = all_hals_.find(binder);
+                if (iter != all_hals_.end()) {
+                    // include all the names this is registered as for error messages
+                    iter->second.name += " " + strName;
+                } else {
+                    all_hals_.insert(iter, {binder, Hal{service, strName}});
+                }
+            }
+        }));
+
+        ASSERT_FALSE(all_hals_.empty());  // sanity
+    }
+
+    void EachHal(const std::function<void(const Hal&)>& check) {
+        for (auto iter = all_hals_.begin(); iter != all_hals_.end(); ++iter) {
+            check(iter->second);
+        }
+    }
+
+    // default service manager
+    sp<IServiceManager> default_manager_;
+
+    // map from underlying instance to actual instance
+    //
+    // this prevents calling the same service twice since the same service
+    // will get registered multiple times for its entire inheritance
+    // hierarchy (or perhaps as different instance names)
+    std::map<sp<IBinder>, Hal> all_hals_;
+};
+
+TEST_F(VtsHalBaseV1_0TargetTest, CanPing) {
+    EachHal(
+        [&](const Hal& base) { EXPECT_OK(base.service->ping()) << "Cannot ping " << base.name; });
+}
+
+TEST_F(VtsHalBaseV1_0TargetTest, InterfaceChain) {
+    EachHal([&](const Hal& base) {
+        EXPECT_OK(base.service->interfaceChain([&](const auto& interfaceChain) {
+            // must include IBase + subclasses
+            EXPECT_GT(interfaceChain.size(), 1u) << "Invalid instance name " << base.name;
+        })) << base.name;
+    });
+}
+
+TEST_F(VtsHalBaseV1_0TargetTest, Descriptor) {
+    EachHal([&](const Hal& base) {
+        EXPECT_OK(base.service->interfaceDescriptor([&](const auto& descriptor) {
+            // must include IBase + subclasses
+            EXPECT_GT(descriptor.size(), 0u) << base.name;
+            EXPECT_NE(IBase::descriptor, descriptor) << base.name;
+        })) << base.name;
+    });
+}
+
+TEST_F(VtsHalBaseV1_0TargetTest, Death) {
+    struct HidlDeathRecipient : hidl_death_recipient {
+        virtual void serviceDied(uint64_t /* cookie */, const wp<IBase>& /* who */){};
+    };
+    sp<hidl_death_recipient> recipient = new HidlDeathRecipient;
+
+    EachHal([&](const Hal& base) {
+        EXPECT_OK(base.service->linkToDeath(recipient, 0 /* cookie */))
+            << "Register death recipient " << base.name;
+        EXPECT_OK(base.service->unlinkToDeath(recipient)) << "Unlink death recipient " << base.name;
+    });
+}
+
+TEST_F(VtsHalBaseV1_0TargetTest, Debug) {
+    EachHal([&](const Hal& base) {
+        // normally one is passed, but this is tested by dumpstate
+        EXPECT_OK(base.service->debug(hidl_handle(), {}))
+            << "Handle empty debug handle " << base.name;
+    });
+}
+
+TEST_F(VtsHalBaseV1_0TargetTest, HashChain) {
+    EachHal([&](const Hal& base) {
+        EXPECT_OK(base.service->getHashChain([&](const auto& hashChain) {
+            // must include IBase + subclasses
+            EXPECT_NE(0u, hashChain.size()) << "Invalid hash chain " << base.name;
+        })) << base.name;
+    });
+}
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
diff --git a/transport/include/hidl/HidlBinderSupport.h b/transport/include/hidl/HidlBinderSupport.h
index 9759af1..55003cc 100644
--- a/transport/include/hidl/HidlBinderSupport.h
+++ b/transport/include/hidl/HidlBinderSupport.h
@@ -332,10 +332,7 @@
         if (sBnObj == nullptr) {
             auto func = details::getBnConstructorMap().get(myDescriptor, nullptr);
             if (!func) {
-                func = details::gBnConstructorMap.get(myDescriptor, nullptr);
-                if (!func) {
-                    return nullptr;
-                }
+                return nullptr;
             }
 
             sBnObj = sp<IBinder>(func(static_cast<void*>(ifacePtr)));
diff --git a/transport/include/hidl/Static.h b/transport/include/hidl/Static.h
index 0522e44..9d9a14a 100644
--- a/transport/include/hidl/Static.h
+++ b/transport/include/hidl/Static.h
@@ -44,8 +44,6 @@
 // For HidlBinderSupport and autogenerated code
 // value function receives reinterpret_cast<void *>(static_cast<IFoo *>(foo)),
 // returns sp<IBinder>
-// deprecated; use getBnConstructorMap instead.
-extern BnConstructorMap gBnConstructorMap;
 BnConstructorMap& getBnConstructorMap();
 
 using BsConstructorMap = ConcurrentMap<std::string,
@@ -53,8 +51,6 @@
 // For HidlPassthroughSupport and autogenerated code
 // value function receives reinterpret_cast<void *>(static_cast<IFoo *>(foo)),
 // returns sp<IBase>
-// deprecated; use getBsConstructorMap instead.
-extern BsConstructorMap gBsConstructorMap;
 BsConstructorMap& getBsConstructorMap();
 }  // namespace details
 }  // namespace hardware
diff --git a/vintfdata/Android.mk b/vintfdata/Android.mk
new file mode 100644
index 0000000..bc7a55a
--- /dev/null
+++ b/vintfdata/Android.mk
@@ -0,0 +1,89 @@
+#
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+FRAMEWORK_MANIFEST_INPUT_FILES := $(LOCAL_PATH)/manifest.xml
+ifdef DEVICE_FRAMEWORK_MANIFEST_FILE
+  FRAMEWORK_MANIFEST_INPUT_FILES += $(DEVICE_FRAMEWORK_MANIFEST_FILE)
+endif
+
+# VNDK Version in device compatibility matrix and framework manifest
+ifeq ($(BOARD_VNDK_VERSION),current)
+VINTF_VNDK_VERSION := $(PLATFORM_VNDK_VERSION)
+else
+VINTF_VNDK_VERSION := $(BOARD_VNDK_VERSION)
+endif
+
+# Device Compatibility Matrix
+ifdef DEVICE_MATRIX_FILE
+DEVICE_MATRIX_INPUT_FILE := $(DEVICE_MATRIX_FILE)
+else
+DEVICE_MATRIX_INPUT_FILE := $(LOCAL_PATH)/device_compatibility_matrix.default.xml
+endif
+
+include $(CLEAR_VARS)
+LOCAL_MODULE        := device_compatibility_matrix.xml
+LOCAL_MODULE_STEM   := compatibility_matrix.xml
+LOCAL_MODULE_CLASS  := ETC
+LOCAL_MODULE_PATH   := $(TARGET_OUT_VENDOR)/etc/vintf
+
+GEN := $(local-generated-sources-dir)/compatibility_matrix.xml
+
+$(GEN): PRIVATE_VINTF_VNDK_VERSION := $(VINTF_VNDK_VERSION)
+$(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 $@
+
+LOCAL_PREBUILT_MODULE_FILE := $(GEN)
+include $(BUILD_PREBUILT)
+BUILT_VENDOR_MATRIX := $(LOCAL_BUILT_MODULE)
+
+# Framework Manifest
+include $(CLEAR_VARS)
+LOCAL_MODULE        := framework_manifest.xml
+LOCAL_MODULE_STEM   := manifest.xml
+LOCAL_MODULE_CLASS  := ETC
+LOCAL_MODULE_PATH   := $(TARGET_OUT)/etc/vintf
+
+GEN := $(local-generated-sources-dir)/manifest.xml
+
+$(GEN): PRIVATE_FLAGS :=
+
+ifeq ($(PRODUCT_ENFORCE_VINTF_MANIFEST),true)
+ifdef BUILT_VENDOR_MATRIX
+$(GEN): $(BUILT_VENDOR_MATRIX)
+$(GEN): PRIVATE_FLAGS += -c "$(BUILT_VENDOR_MATRIX)"
+endif
+endif
+
+$(GEN): PRIVATE_VINTF_VNDK_VERSION := $(VINTF_VNDK_VERSION)
+$(GEN): PRIVATE_FRAMEWORK_MANIFEST_INPUT_FILES := $(FRAMEWORK_MANIFEST_INPUT_FILES)
+$(GEN): $(FRAMEWORK_MANIFEST_INPUT_FILES) $(HOST_OUT_EXECUTABLES)/assemble_vintf
+	PROVIDED_VNDK_VERSIONS="$(PRIVATE_VINTF_VNDK_VERSION) $(PRODUCT_EXTRA_VNDK_VERSIONS)" \
+	PLATFORM_SYSTEMSDK_VERSIONS="$(PLATFORM_SYSTEMSDK_VERSIONS)" \
+		$(HOST_OUT_EXECUTABLES)/assemble_vintf \
+		-i $(call normalize-path-list,$(PRIVATE_FRAMEWORK_MANIFEST_INPUT_FILES)) \
+		-o $@ $(PRIVATE_FLAGS)
+
+LOCAL_PREBUILT_MODULE_FILE := $(GEN)
+include $(BUILD_PREBUILT)
+BUILT_SYSTEM_MANIFEST := $(LOCAL_BUILT_MODULE)
+
+VINTF_VNDK_VERSION :=
+FRAMEWORK_MANIFEST_INPUT_FILES :=
+DEVICE_MATRIX_INPUT_FILE :=
diff --git a/vintfdata/device_compatibility_matrix.default.xml b/vintfdata/device_compatibility_matrix.default.xml
new file mode 100644
index 0000000..eaa513e
--- /dev/null
+++ b/vintfdata/device_compatibility_matrix.default.xml
@@ -0,0 +1,10 @@
+<compatibility-matrix version="1.0" type="device">
+    <hal format="hidl" optional="false">
+        <name>android.hidl.manager</name>
+        <version>1.0</version>
+        <interface>
+            <name>IServiceManager</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</compatibility-matrix>
diff --git a/manifest.xml b/vintfdata/manifest.xml
similarity index 100%
rename from manifest.xml
rename to vintfdata/manifest.xml