Merge "Remove VehiclePermisionMode from VHAL"
diff --git a/boot/1.0/vts/functional/vts/testcases/hal/boot/hidl/target/AndroidTest.xml b/boot/1.0/vts/functional/vts/testcases/hal/boot/hidl/target/AndroidTest.xml
index 6c7809c..bc759bf 100644
--- a/boot/1.0/vts/functional/vts/testcases/hal/boot/hidl/target/AndroidTest.xml
+++ b/boot/1.0/vts/functional/vts/testcases/hal/boot/hidl/target/AndroidTest.xml
@@ -24,6 +24,7 @@
             _32bit::DATA/nativetest/boot_hidl_hal_test/boot_hidl_hal_test,
             _64bit::DATA/nativetest64/boot_hidl_hal_test/boot_hidl_hal_test,
             "/>
+        <option name="test-config-path" value="vts/testcases/hal/boot/hidl/target/HalBootHidlTargetTest.config" />
         <option name="binary-test-type" value="gtest" />
         <option name="test-timeout" value="1m" />
     </test>
diff --git a/boot/1.0/vts/functional/vts/testcases/hal/boot/hidl/target/HalBootHidlTargetTest.config b/boot/1.0/vts/functional/vts/testcases/hal/boot/hidl/target/HalBootHidlTargetTest.config
new file mode 100644
index 0000000..ebb4d1b
--- /dev/null
+++ b/boot/1.0/vts/functional/vts/testcases/hal/boot/hidl/target/HalBootHidlTargetTest.config
@@ -0,0 +1,20 @@
+{
+    "use_gae_db": true,
+    "coverage": true,
+    "modules": [
+        {
+            "module_name": "system/lib64/hw/bootctrl.msm8996",
+            "git_project": {
+                "name": "platform/hardware/qcom/bootctrl",
+                "path": "hardware/qcom/bootctrl"
+            }
+        },
+        {
+            "module_name": "system/lib64/hw/android.hardware.boot@1.0-impl",
+            "git_project": {
+                "name": "platform/hardware/interfaces",
+                "path": "hardware/interfaces"
+            }
+        }
+    ]
+}
diff --git a/camera/device/3.2/types.hal b/camera/device/3.2/types.hal
index 3ce5037..505b6ba 100644
--- a/camera/device/3.2/types.hal
+++ b/camera/device/3.2/types.hal
@@ -635,7 +635,7 @@
          * Shutter message contents. Valid if type is MsgType::SHUTTER
          */
         ShutterMsg shutter;
-    };
+    } msg;
 
 };
 
diff --git a/contexthub/1.0/IContexthub.hal b/contexthub/1.0/IContexthub.hal
index 8d19aeb..8c792fd 100644
--- a/contexthub/1.0/IContexthub.hal
+++ b/contexthub/1.0/IContexthub.hal
@@ -60,9 +60,11 @@
      * After the init method for nanoApp returns success, this must be indicated
      * to the service by an asynchronous call to handleTxnResult.
      *
+     * Loading a nanoapp must not take more than 30 seconds.
+     *
      * @param hubId identifer of the contextHub
-     *        appBinary binary for the nanoApp
-     *        msg   message to be sent
+     *        appBinary serialized NanoApppBinary for the nanoApp
+     *        transactionId transactionId for this call
      *
      * @return result OK if transation started
      *                BAD_VALUE if parameters are not sane
@@ -71,7 +73,9 @@
      *                TRANSACTION_FAILED if load failed synchronously
      *
      */
-    loadNanoApp(uint32_t hubId, NanoAppBinary appBinary, uint32_t transactionId)
+    loadNanoApp(uint32_t hubId,
+                vec<uint8_t> appBinary,
+                uint32_t transactionId)
             generates (Result result);
 
     /**
@@ -79,6 +83,8 @@
      * After this, success must be indicated to the service through an
      * asynchronous call to handleTxnResult.
      *
+     * Unloading a nanoapp must not take more than 5 seconds.
+     *
      * @param hubId identifer of the contextHub
      *        appId appIdentifier returned by the HAL
      *        msg   message to be sent
@@ -98,6 +104,8 @@
      * After this, success must be indicated to the service through an
      * asynchronous message.
      *
+     * Enabling a nanoapp must not take more than 5 seconds.
+     *
      * @param hubId identifer of the contextHub
      *        appId appIdentifier returned by the HAL
      *        msg   message to be sent
@@ -117,6 +125,8 @@
      * After this, success must be indicated to the service through an
      * asynchronous message.
      *
+     * Disabling a nanoapp must not take more than 5 seconds.
+     *
      * @param hubId identifer of the contextHub
      *        appId appIdentifier returned by the HAL
      *        msg   message to be sent
@@ -136,7 +146,11 @@
      *
      * @param hubId identifer of the contextHub
      *
-     * @return apps all nanoApps on the hub
+     * @return apps all nanoApps on the hub.
+     *              All nanoApps that can be modified by the service must
+     *              be returned. A non-modifiable nanoapps must not be
+     *              returned. A modifiable nanoApp is one that can be
+     *              unloaded/disabled/enabled by the service.
      *
      */
     queryApps(uint32_t hubId) generates (Result result);
diff --git a/contexthub/1.0/IContexthubCallback.hal b/contexthub/1.0/IContexthubCallback.hal
index 29c41ce..9e9cf27 100644
--- a/contexthub/1.0/IContexthubCallback.hal
+++ b/contexthub/1.0/IContexthubCallback.hal
@@ -22,41 +22,44 @@
      * implementation to allow the HAL to send asynchronous messages back
      * to the service and registered clients of the ContextHub service.
      *
-     * @params hubId : identifier of the hub calling callback
-     *         msg   : message
+     * @params msg : message
      *
      */
-     handleClientMsg(uint32_t hubId, ContextHubMsg msg);
+     handleClientMsg(ContextHubMsg msg);
 
     /*
      * This callback is passed by the Contexthub service to the HAL
      * implementation to allow the HAL to send the response for a
      * transaction.
      *
-     * @params hubId : identifier of the hub calling callback
-     *         txnId : transaction id whose result is being sent
+     * @params txnId : transaction id whose result is being sent
      *                 passed in by the service at start of transacation.
      *         result: result of transaction.
      *
      */
-     handleTxnResult(uint32_t hubId, uint32_t txnId,
-             TransactionResult result);
+     handleTxnResult(uint32_t txnId, TransactionResult result);
 
     /*
      * This callback is passed by the Contexthub service to the HAL
      * implementation to allow the HAL to send an asynchronous event
      * to the ContextHub service.
      *
-     * @params hubId : identifier of the hub calling callback
-     *         msg   : message
+     * @params msg : message
      *
      */
-     handleHubEvent(uint32_t hubId, AsyncEventType evt);
+     handleHubEvent(AsyncEventType evt);
 
      /*
       * This callback is passed by the Contexthub service to the HAL
       * implementation to allow the HAL to send information about the
       * currently loaded and active nanoapps on the hub.
+      *
+      * @params appInfo : vector of HubAppinfo structure for each nanoApp
+      *                   on the hub that can be enabled, disabled and
+      *                   unloaded by the service. Any nanoApps that cannot
+      *                   be controlled by the service must not be reported.
+      *                   All nanoApps that can be controlled by the service
+      *                   must be reported.
       */
-      handleAppsInfo(uint32_t hubId, vec<HubAppInfo> appInfo);
+      handleAppsInfo(vec<HubAppInfo> appInfo);
 };
diff --git a/contexthub/1.0/default/Android.bp b/contexthub/1.0/default/Android.bp
new file mode 100644
index 0000000..7c5f79d
--- /dev/null
+++ b/contexthub/1.0/default/Android.bp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 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_library_shared {
+    name: "android.hardware.contexthub@1.0-impl",
+    relative_install_path: "hw",
+    srcs: ["Contexthub.cpp"],
+    shared_libs: [
+        "liblog",
+        "libcutils",
+        "libhardware",
+        "libhwbinder",
+        "libbase",
+        "libcutils",
+        "libutils",
+        "libhidlbase",
+        "libhidltransport",
+        "android.hardware.contexthub@1.0",
+    ],
+}
diff --git a/contexthub/1.0/default/Android.mk b/contexthub/1.0/default/Android.mk
new file mode 100644
index 0000000..ad40878
--- /dev/null
+++ b/contexthub/1.0/default/Android.mk
@@ -0,0 +1,23 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_MODULE := android.hardware.contexthub@1.0-service
+LOCAL_INIT_RC := android.hardware.contexthub@1.0-service.rc
+LOCAL_SRC_FILES := \
+        service.cpp \
+
+LOCAL_SHARED_LIBRARIES := \
+        libbase \
+        libcutils \
+        libdl \
+        libhardware \
+        libhardware_legacy \
+        libhidlbase \
+        libhidltransport \
+        libhwbinder \
+        liblog \
+        libutils \
+        android.hardware.contexthub@1.0 \
+
+include $(BUILD_EXECUTABLE)
diff --git a/contexthub/1.0/default/Contexthub.cpp b/contexthub/1.0/default/Contexthub.cpp
new file mode 100644
index 0000000..d530a87
--- /dev/null
+++ b/contexthub/1.0/default/Contexthub.cpp
@@ -0,0 +1,528 @@
+/*
+ * Copyright (C) 2016 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 "Contexthub.h"
+
+#include <inttypes.h>
+
+#include <android/log.h>
+#include <android/hardware/contexthub/1.0/IContexthub.h>
+#include <hardware/context_hub.h>
+
+#undef LOG_TAG
+#define LOG_TAG "ContextHubHalAdapter"
+
+namespace android {
+namespace hardware {
+namespace contexthub {
+namespace V1_0 {
+namespace implementation {
+
+static constexpr uint64_t ALL_APPS = UINT64_C(0xFFFFFFFFFFFFFFFF);
+
+Contexthub::Contexthub()
+        : mInitCheck(NO_INIT),
+          mContextHubModule(nullptr),
+          mIsTransactionPending(false) {
+    const hw_module_t *module;
+
+    mInitCheck = hw_get_module(CONTEXT_HUB_MODULE_ID, &module);
+
+    if (mInitCheck != OK) {
+        ALOGE("Could not load %s module: %s", CONTEXT_HUB_MODULE_ID, strerror(-mInitCheck));
+    } else if (module == nullptr) {
+        ALOGE("hal returned succes but a null module!");
+        // Assign an error, this should not really happen...
+        mInitCheck = UNKNOWN_ERROR;
+    } else {
+        ALOGI("Loaded Context Hub module");
+        mContextHubModule = reinterpret_cast<const context_hub_module_t *>(module);
+    }
+}
+
+bool Contexthub::setOsAppAsDestination(hub_message_t *msg, int hubId) {
+    if (!isValidHubId(hubId)) {
+        ALOGW("%s: Hub information is null for hubHandle %d",
+              __FUNCTION__,
+              hubId);
+        return false;
+    } else {
+        msg->app_name = mCachedHubInfo[hubId].osAppName;
+        return true;
+    }
+}
+
+Return<void> Contexthub::getHubs(getHubs_cb _hidl_cb) {
+    std::vector<ContextHub> hubs;
+    if (isInitialized()) {
+        const context_hub_t *hubArray = nullptr;
+        size_t numHubs;
+
+        // Explicitly discarding const. HAL method discards it.
+        numHubs = mContextHubModule->get_hubs(const_cast<context_hub_module_t *>(mContextHubModule),
+                                              &hubArray);
+        ALOGI("Context Hub Hal Adapter reports %zu hubs", numHubs);
+
+        mCachedHubInfo.clear();
+
+        for (size_t i = 0; i < numHubs; i++) {
+            CachedHubInformation info;
+            ContextHub c;
+
+            c.hubId = hubArray[i].hub_id;
+            c.name = hubArray[i].name;
+            c.vendor = hubArray[i].vendor;
+            c.toolchain = hubArray[i].toolchain;
+            c.toolchainVersion = hubArray[i].toolchain_version;
+            c.platformVersion = hubArray[i].platform_version;
+            c.maxSupportedMsgLen = hubArray[i].max_supported_msg_len;
+            c.peakMips = hubArray[i].peak_mips;
+            c.peakPowerDrawMw = hubArray[i].peak_power_draw_mw;
+            c.stoppedPowerDrawMw = hubArray[i].stopped_power_draw_mw;
+            c.sleepPowerDrawMw = hubArray[i].sleep_power_draw_mw;
+
+            info.callBack = nullptr;
+            info.osAppName = hubArray[i].os_app_name;
+            mCachedHubInfo[hubArray[i].hub_id] = info;
+
+            hubs.push_back(c);
+        }
+    } else {
+        ALOGW("Context Hub Hal Adapter not initialized");
+    }
+
+    _hidl_cb(hubs);
+    return Void();
+}
+
+bool Contexthub::isValidHubId(uint32_t hubId) {
+    if (!mCachedHubInfo.count(hubId)) {
+        ALOGW("Hub information not found for hubId %" PRIu32, hubId);
+        return false;
+    } else {
+        return true;
+    }
+}
+
+sp<IContexthubCallback> Contexthub::getCallBackForHubId(uint32_t hubId) {
+    if (!isValidHubId(hubId)) {
+        return nullptr;
+    } else {
+        return mCachedHubInfo[hubId].callBack;
+    }
+}
+
+Return<Result> Contexthub::sendMessageToHub(uint32_t hubId,
+                                            const ContextHubMsg &msg) {
+    if (!isInitialized()) {
+        return Result::NOT_INIT;
+    }
+
+    if (!isValidHubId(hubId) || msg.msg.size() > UINT32_MAX) {
+        return Result::BAD_PARAMS;
+    }
+
+    hub_message_t txMsg = {
+        .app_name.id = msg.appName,
+        .message_type = msg.msgType,
+        .message_len = static_cast<uint32_t>(msg.msg.size()), // Note the check above
+        .message = static_cast<const uint8_t *>(msg.msg.data()),
+    };
+
+    ALOGI("Sending msg of type %" PRIu32 ", size %" PRIu32 " to app 0x%" PRIx64,
+          txMsg.message_type,
+          txMsg.message_len,
+          txMsg.app_name.id);
+
+    if(mContextHubModule->send_message(hubId, &txMsg) != 0) {
+        return Result::TRANSACTION_FAILED;
+    }
+
+    return Result::OK;
+}
+
+Return<Result> Contexthub::reboot(uint32_t hubId) {
+    if (!isInitialized()) {
+      return Result::NOT_INIT;
+    }
+
+    hub_message_t msg;
+
+    if (setOsAppAsDestination(&msg, hubId) == false) {
+        return Result::BAD_PARAMS;
+    }
+
+    msg.message_type = CONTEXT_HUB_OS_REBOOT;
+    msg.message_len = 0;
+    msg.message = nullptr;
+
+    if(mContextHubModule->send_message(hubId, &msg) != 0) {
+        return Result::TRANSACTION_FAILED;
+    } else {
+        return Result::OK;
+    }
+}
+
+Return<Result> Contexthub::registerCallback(uint32_t hubId,
+                                            const sp<IContexthubCallback> &cb) {
+    Return<Result> retVal = Result::BAD_PARAMS;
+
+    if (!isInitialized()) {
+        // Not initilalized
+        ALOGW("Context hub not initialized successfully");
+        retVal = Result::NOT_INIT;
+    } else if (!isValidHubId(hubId)) {
+        // Initialized, but hubId is  not valid
+        retVal = Result::BAD_PARAMS;
+    } else if (mContextHubModule->subscribe_messages(hubId,
+                                                     contextHubCb,
+                                                     this) == 0) {
+        // Initialized && valid hub && subscription successful
+        retVal = Result::OK;
+        mCachedHubInfo[hubId].callBack = cb;
+    } else {
+        // Initalized && valid hubId - but subscription unsuccessful
+        // This is likely an internal error in the HAL implementation, but we
+        // cannot add more information.
+        ALOGW("Could not subscribe to the hub for callback");
+        retVal = Result::UNKNOWN_FAILURE;
+    }
+
+    return retVal;
+}
+
+static bool isValidOsStatus(const uint8_t *msg,
+                            size_t msgLen,
+                            status_response_t *rsp) {
+    // Workaround a bug in some HALs
+    if (msgLen == 1) {
+        rsp->result = msg[0];
+        return true;
+    }
+
+    if (msg == nullptr || msgLen != sizeof(*rsp)) {
+        ALOGI("Received invalid response (is null : %d, size %zu)",
+              msg == nullptr ? 1 : 0,
+              msgLen);
+        return false;
+    }
+
+    memcpy(rsp, msg, sizeof(*rsp));
+
+    // No sanity checks on return values
+    return true;
+}
+
+int Contexthub::handleOsMessage(sp<IContexthubCallback> cb,
+                                uint32_t msgType,
+                                const uint8_t *msg,
+                                int msgLen) {
+    int retVal = -1;
+
+
+    switch(msgType) {
+        case CONTEXT_HUB_APPS_ENABLE:
+        case CONTEXT_HUB_APPS_DISABLE:
+        case CONTEXT_HUB_LOAD_APP:
+        case CONTEXT_HUB_UNLOAD_APP:
+        {
+            struct status_response_t rsp;
+            TransactionResult result;
+            if (isValidOsStatus(msg, msgLen, &rsp) && rsp.result == 0) {
+                retVal = 0;
+                result = TransactionResult::SUCCESS;
+            } else {
+                result = TransactionResult::FAILURE;
+            }
+
+            if (cb != nullptr) {
+                cb->handleTxnResult(mTransactionId, result);
+            }
+            retVal = 0;
+            mIsTransactionPending = false;
+            break;
+        }
+
+        case CONTEXT_HUB_QUERY_APPS:
+        {
+            std::vector<HubAppInfo> apps;
+            int numApps = msgLen / sizeof(hub_app_info);
+            const hub_app_info *unalignedInfoAddr = reinterpret_cast<const hub_app_info *>(msg);
+
+            for (int i = 0; i < numApps; i++) {
+                hub_app_info query_info;
+                memcpy(&query_info, &unalignedInfoAddr[i], sizeof(query_info));
+                HubAppInfo app;
+                app.appId = query_info.app_name.id;
+                app.version = query_info.version;
+                // TODO :: Add memory ranges
+
+                apps.push_back(app);
+            }
+
+            if (cb != nullptr) {
+                cb->handleAppsInfo(apps);
+            }
+            retVal = 0;
+            break;
+        }
+
+        case CONTEXT_HUB_QUERY_MEMORY:
+        {
+            // Deferring this use
+            retVal = 0;
+            break;
+        }
+
+        case CONTEXT_HUB_OS_REBOOT:
+        {
+            mIsTransactionPending = false;
+            if (cb != nullptr) {
+                cb->handleHubEvent(AsyncEventType::RESTARTED);
+            }
+            retVal = 0;
+            break;
+        }
+
+        default:
+        {
+            retVal = -1;
+            break;
+        }
+      }
+
+      return retVal;
+}
+
+int Contexthub::contextHubCb(uint32_t hubId,
+                             const struct hub_message_t *rxMsg,
+                             void *cookie) {
+    Contexthub *obj = static_cast<Contexthub *>(cookie);
+
+    if (rxMsg == nullptr) {
+        ALOGW("Ignoring NULL message");
+        return -1;
+    }
+
+    if (!obj->isValidHubId(hubId)) {
+        ALOGW("Invalid hub Id %" PRIu32, hubId);
+        return -1;
+    }
+
+    sp<IContexthubCallback> cb = obj->getCallBackForHubId(hubId);
+
+    if (cb == nullptr) {
+        // This should not ever happen
+        ALOGW("No callback registered, returning");
+        return -1;
+    }
+
+    if (rxMsg->message_type < CONTEXT_HUB_TYPE_PRIVATE_MSG_BASE) {
+        obj->handleOsMessage(cb,
+                             rxMsg->message_type,
+                             static_cast<const uint8_t *>(rxMsg->message),
+                             rxMsg->message_len);
+    } else {
+        ContextHubMsg msg;
+
+        msg.appName = rxMsg->app_name.id;
+        msg.msgType = rxMsg->message_type;
+        msg.msg = std::vector<uint8_t>(static_cast<const uint8_t *>(rxMsg->message),
+                                       static_cast<const uint8_t *>(rxMsg->message) +
+                                       rxMsg->message_len);
+
+        cb->handleClientMsg(msg);
+    }
+
+    return 0;
+}
+
+Return<Result> Contexthub::unloadNanoApp(uint32_t hubId,
+                                         uint64_t appId,
+                                         uint32_t transactionId) {
+    if (!isInitialized()) {
+      return Result::NOT_INIT;
+    }
+
+    if (mIsTransactionPending) {
+        return Result::TRANSACTION_PENDING;
+    }
+
+    hub_message_t msg;
+
+    if (setOsAppAsDestination(&msg, hubId) == false) {
+        return Result::BAD_PARAMS;
+    }
+
+    struct apps_disable_request_t req;
+
+    msg.message_type = CONTEXT_HUB_UNLOAD_APP;
+    msg.message_len = sizeof(req);
+    msg.message = &req;
+    req.app_name.id = appId;
+
+    if(mContextHubModule->send_message(hubId, &msg) != 0) {
+        return Result::TRANSACTION_FAILED;
+    } else {
+        mTransactionId = transactionId;
+        mIsTransactionPending = true;
+        return Result::OK;
+    }
+}
+
+Return<Result> Contexthub::loadNanoApp(uint32_t hubId,
+                                       const ::android::hardware::hidl_vec<uint8_t>& appBinary,
+                                       uint32_t transactionId) {
+    if (!isInitialized()) {
+      return Result::NOT_INIT;
+    }
+
+    if (mIsTransactionPending) {
+        return Result::TRANSACTION_PENDING;
+    }
+
+    hub_message_t hubMsg;
+
+    if (setOsAppAsDestination(&hubMsg, hubId) == false) {
+        return Result::BAD_PARAMS;
+    }
+
+    hubMsg.message_type = CONTEXT_HUB_LOAD_APP;
+    hubMsg.message_len = appBinary.size();
+    hubMsg.message = appBinary.data();
+
+    if(mContextHubModule->send_message(hubId, &hubMsg) != 0) {
+        return Result::TRANSACTION_FAILED;
+    } else {
+        mTransactionId = transactionId;
+        mIsTransactionPending = true;
+        return Result::OK;
+    }
+}
+
+Return<Result> Contexthub::enableNanoApp(uint32_t hubId,
+                                         uint64_t appId,
+                                         uint32_t transactionId) {
+    if (!isInitialized()) {
+      return Result::NOT_INIT;
+    }
+
+    if (mIsTransactionPending) {
+        return Result::TRANSACTION_PENDING;
+    }
+
+    hub_message_t msg;
+
+    if (setOsAppAsDestination(&msg, hubId) == false) {
+        return Result::BAD_PARAMS;
+    }
+
+    struct apps_enable_request_t req;
+
+    msg.message_type = CONTEXT_HUB_APPS_ENABLE;
+    msg.message_len = sizeof(req);
+    req.app_name.id = appId;
+    msg.message = &req;
+
+    if(mContextHubModule->send_message(hubId, &msg) != 0) {
+        return Result::TRANSACTION_FAILED;
+    } else {
+        mTransactionId = transactionId;
+        mIsTransactionPending = true;
+        return Result::OK;
+    }
+}
+
+Return<Result> Contexthub::disableNanoApp(uint32_t hubId,
+                                          uint64_t appId,
+                                          uint32_t transactionId) {
+    if (!isInitialized()) {
+      return Result::NOT_INIT;
+    }
+
+    if (mIsTransactionPending) {
+        return Result::TRANSACTION_PENDING;
+    }
+
+    hub_message_t msg;
+
+    if (setOsAppAsDestination(&msg, hubId) == false) {
+        return Result::BAD_PARAMS;
+    }
+
+    struct apps_disable_request_t req;
+
+    msg.message_type = CONTEXT_HUB_APPS_DISABLE;
+    msg.message_len = sizeof(req);
+    req.app_name.id = appId;
+    msg.message = &req;
+
+    if(mContextHubModule->send_message(hubId, &msg) != 0) {
+        return Result::TRANSACTION_FAILED;
+    } else {
+        mTransactionId = transactionId;
+        mIsTransactionPending = true;
+        return Result::OK;
+    }
+}
+
+Return<Result> Contexthub::queryApps(uint32_t hubId) {
+    if (!isInitialized()) {
+      return Result::NOT_INIT;
+    }
+
+    hub_message_t msg;
+
+    if (setOsAppAsDestination(&msg, hubId) == false) {
+        ALOGW("Could not find hubId %" PRIu32, hubId);
+        return Result::BAD_PARAMS;
+    }
+
+    query_apps_request_t payload;
+    payload.app_name.id = ALL_APPS; // TODO : Pass this in as a parameter
+    msg.message = &payload;
+    msg.message_len = sizeof(payload);
+    msg.message_type = CONTEXT_HUB_QUERY_APPS;
+
+    if(mContextHubModule->send_message(hubId, &msg) != 0) {
+        ALOGW("Query Apps sendMessage failed");
+        return Result::TRANSACTION_FAILED;
+    }
+
+    return Result::OK;
+}
+
+bool Contexthub::isInitialized() {
+    return (mInitCheck == OK && mContextHubModule != nullptr);
+}
+
+IContexthub *HIDL_FETCH_IContexthub(const char * halName) {
+    ALOGI("%s Called for %s", __FUNCTION__, halName);
+    Contexthub *contexthub = new Contexthub;
+
+    if (!contexthub->isInitialized()) {
+        delete contexthub;
+        contexthub = nullptr;
+    }
+
+    return contexthub;
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace contexthub
+}  // namespace hardware
+}  // namespace android
diff --git a/contexthub/1.0/default/Contexthub.h b/contexthub/1.0/default/Contexthub.h
new file mode 100644
index 0000000..0883ce8
--- /dev/null
+++ b/contexthub/1.0/default/Contexthub.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef ANDROID_HARDWARE_CONTEXTHUB_V1_0_CONTEXTHUB_H_
+#define ANDROID_HARDWARE_CONTEXTHUB_V1_0_CONTEXTHUB_H_
+
+#include <unordered_map>
+
+#include <android/hardware/contexthub/1.0/IContexthub.h>
+#include <hardware/context_hub.h>
+
+namespace android {
+namespace hardware {
+namespace contexthub {
+namespace V1_0 {
+namespace implementation {
+
+struct Contexthub : public ::android::hardware::contexthub::V1_0::IContexthub {
+    Contexthub();
+
+    Return<void> getHubs(getHubs_cb _hidl_cb) override;
+
+    Return<Result> registerCallback(uint32_t hubId,
+                                    const sp<IContexthubCallback> &cb) override;
+
+    Return<Result> sendMessageToHub(uint32_t hubId,
+                                    const ContextHubMsg &msg) override;
+
+    Return<Result> loadNanoApp(uint32_t hubId,
+                               const ::android::hardware::hidl_vec<uint8_t>& appBinary,
+                               uint32_t transactionId) override;
+
+    Return<Result> unloadNanoApp(uint32_t hubId,
+                                 uint64_t appId,
+                                 uint32_t transactionId) override;
+
+    Return<Result> enableNanoApp(uint32_t hubId,
+                                 uint64_t appId,
+                                 uint32_t transactionId) override;
+
+    Return<Result> disableNanoApp(uint32_t hubId,
+                                  uint64_t appId,
+                                  uint32_t transactionId) override;
+
+    Return<Result> queryApps(uint32_t hubId) override;
+
+    Return<Result> reboot(uint32_t hubId);
+
+    bool isInitialized();
+
+private:
+
+    struct CachedHubInformation{
+        struct hub_app_name_t osAppName;
+        sp<IContexthubCallback> callBack;
+    };
+
+    status_t mInitCheck;
+    const struct context_hub_module_t *mContextHubModule;
+    std::unordered_map<uint32_t, CachedHubInformation> mCachedHubInfo;
+
+    sp<IContexthubCallback> mCb;
+    bool mIsTransactionPending;
+    uint32_t mTransactionId;
+
+    bool isValidHubId(uint32_t hubId);
+
+    sp<IContexthubCallback> getCallBackForHubId(uint32_t hubId);
+
+    int handleOsMessage(sp<IContexthubCallback> cb,
+                        uint32_t msgType,
+                        const uint8_t *msg,
+                        int msgLen);
+
+    static int contextHubCb(uint32_t hubId,
+                            const struct hub_message_t *rxMsg,
+                            void *cookie);
+
+    bool setOsAppAsDestination(hub_message_t *msg, int hubId);
+
+    DISALLOW_COPY_AND_ASSIGN(Contexthub);
+};
+
+extern "C" IContexthub *HIDL_FETCH_IContexthub(const char *name);
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace contexthub
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_CONTEXTHUB_V1_0_CONTEXTHUB_H_
diff --git a/contexthub/1.0/default/android.hardware.contexthub@1.0-service.rc b/contexthub/1.0/default/android.hardware.contexthub@1.0-service.rc
new file mode 100644
index 0000000..8dba85f
--- /dev/null
+++ b/contexthub/1.0/default/android.hardware.contexthub@1.0-service.rc
@@ -0,0 +1,4 @@
+service contexthub-hal-1-0 /system/bin/hw/android.hardware.contexthub@1.0-service
+    class hal
+    user system
+    group system
diff --git a/contexthub/1.0/default/service.cpp b/contexthub/1.0/default/service.cpp
new file mode 100644
index 0000000..db9a4e7
--- /dev/null
+++ b/contexthub/1.0/default/service.cpp
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#define LOG_TAG "android.hardware.contexthub@1.0-service"
+
+#include <android/hardware/contexthub/1.0/IContexthub.h>
+#include <hidl/LegacySupport.h>
+
+using android::hardware::contexthub::V1_0::IContexthub;
+using android::hardware::defaultPassthroughServiceImplementation;
+
+int main() {
+    return defaultPassthroughServiceImplementation<IContexthub>("context_hub");
+}
diff --git a/contexthub/1.0/types.hal b/contexthub/1.0/types.hal
index b9f014b..043bb39 100644
--- a/contexthub/1.0/types.hal
+++ b/contexthub/1.0/types.hal
@@ -18,6 +18,7 @@
 
 enum Result : uint32_t {
     OK,                  // Success
+    UNKNOWN_FAILURE,     // Failure, unknown reason
     BAD_PARAMS,          // Parameters not sane
     NOT_INIT,            // not initialized
     TRANSACTION_FAILED,  // transaction failed
diff --git a/contexthub/Android.bp b/contexthub/Android.bp
index bbb3e4b..ba90f2c 100644
--- a/contexthub/Android.bp
+++ b/contexthub/Android.bp
@@ -1,4 +1,5 @@
 // This is an autogenerated file, do not edit.
 subdirs = [
     "1.0",
+    "1.0/default",
 ]
diff --git a/graphics/composer/2.1/default/HwcClient.cpp b/graphics/composer/2.1/default/HwcClient.cpp
index 16af94c..5599959 100644
--- a/graphics/composer/2.1/default/HwcClient.cpp
+++ b/graphics/composer/2.1/default/HwcClient.cpp
@@ -934,7 +934,7 @@
         return false;
     }
 
-    auto err = mHal.setLayerPlaneAlpha(mDisplay, mLayer, read());
+    auto err = mHal.setLayerPlaneAlpha(mDisplay, mLayer, readFloat());
     if (err != Error::NONE) {
         mWriter.setError(getCommandLoc(), err);
     }
diff --git a/graphics/composer/2.1/default/IComposerCommandBuffer.h b/graphics/composer/2.1/default/IComposerCommandBuffer.h
index 030db88..199a744 100644
--- a/graphics/composer/2.1/default/IComposerCommandBuffer.h
+++ b/graphics/composer/2.1/default/IComposerCommandBuffer.h
@@ -35,7 +35,7 @@
 #include <android/hardware/graphics/composer/2.1/IComposer.h>
 #include <log/log.h>
 #include <sync/sync.h>
-#include <MessageQueue.h>
+#include <fmq/MessageQueue.h>
 
 namespace android {
 namespace hardware {
diff --git a/ir/1.0/IConsumerIr.hal b/ir/1.0/IConsumerIr.hal
index f928c0e..f9e6316 100644
--- a/ir/1.0/IConsumerIr.hal
+++ b/ir/1.0/IConsumerIr.hal
@@ -28,7 +28,7 @@
      *
      * returns: true on success, false on error.
      */
-    transmit(int32_t carrierFreq, vec<int32_t> pattern, int32_t patternLen) generates (bool success);
+    transmit(int32_t carrierFreq, vec<int32_t> pattern) generates (bool success);
 
     /*
      * getCarrierFreqs() enumerates which frequencies the IR transmitter supports.
diff --git a/ir/1.0/default/ConsumerIr.cpp b/ir/1.0/default/ConsumerIr.cpp
index 763e09a..8cfb2e8 100644
--- a/ir/1.0/default/ConsumerIr.cpp
+++ b/ir/1.0/default/ConsumerIr.cpp
@@ -32,8 +32,8 @@
 }
 
 // Methods from ::android::hardware::consumerir::V1_0::IConsumerIr follow.
-Return<bool> ConsumerIr::transmit(int32_t carrierFreq, const hidl_vec<int32_t>& pattern, int32_t patternLen) {
-    return mDevice->transmit(mDevice, carrierFreq, pattern.data(), patternLen) == 0;
+Return<bool> ConsumerIr::transmit(int32_t carrierFreq, const hidl_vec<int32_t>& pattern) {
+    return mDevice->transmit(mDevice, carrierFreq, pattern.data(), pattern.size()) == 0;
 }
 
 Return<void> ConsumerIr::getCarrierFreqs(getCarrierFreqs_cb _hidl_cb) {
diff --git a/ir/1.0/default/ConsumerIr.h b/ir/1.0/default/ConsumerIr.h
index 527c577..1532183 100644
--- a/ir/1.0/default/ConsumerIr.h
+++ b/ir/1.0/default/ConsumerIr.h
@@ -40,7 +40,7 @@
 struct ConsumerIr : public IConsumerIr {
     ConsumerIr(consumerir_device_t *device);
     // Methods from ::android::hardware::ir::V1_0::IConsumerIr follow.
-    Return<bool> transmit(int32_t carrierFreq, const hidl_vec<int32_t>& pattern, int32_t patternLen) override;
+    Return<bool> transmit(int32_t carrierFreq, const hidl_vec<int32_t>& pattern) override;
     Return<void> getCarrierFreqs(getCarrierFreqs_cb _hidl_cb) override;
 private:
     consumerir_device_t *mDevice;
diff --git a/media/1.0/types.hal b/media/1.0/types.hal
index 98dfe14..89b7fa2 100644
--- a/media/1.0/types.hal
+++ b/media/1.0/types.hal
@@ -27,28 +27,28 @@
 
 /**
  * Ref: frameworks/native/include/ui/GraphicBuffer.h
- * Ref: system/core/include/system/window.h
+ * Ref: system/core/include/system/window.h: ANativeWindowBuffer
  */
 
 /**
  * This struct contains attributes for a gralloc buffer that can be put into a
  * union.
  */
-struct GraphicBufferAttributes {
+struct AnwBufferAttributes {
     uint32_t width;
     uint32_t height;
     uint32_t stride;
     PixelFormat format;
     uint32_t usage; // TODO: convert to an enum
-    uint32_t generationNumber;
+    uint64_t layerCount;
 };
 
 /**
- * A GraphicBuffer is simply GraphicBufferAttributes plus a native handle.
+ * An AnwBuffer is simply AnwBufferAttributes plus a native handle.
  */
-struct GraphicBuffer {
+struct AnwBuffer {
     handle nativeHandle;
-    GraphicBufferAttributes attr;
+    AnwBufferAttributes attr;
 };
 
 /**
diff --git a/media/omx/1.0/IGraphicBufferSource.hal b/media/omx/1.0/IGraphicBufferSource.hal
index a5b5813..9b3ab0c 100644
--- a/media/omx/1.0/IGraphicBufferSource.hal
+++ b/media/omx/1.0/IGraphicBufferSource.hal
@@ -29,32 +29,23 @@
  */
 interface IGraphicBufferSource {
 
-    configure(IOmxNode omxNode, Dataspace dataspace)
-        generates (Status status);
+    configure(IOmxNode omxNode, Dataspace dataspace);
 
-    setSuspend(bool suspend)
-        generates (Status status);
+    setSuspend(bool suspend);
 
-    setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs)
-        generates (Status status);
+    setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs);
 
-    setMaxFps(float maxFps)
-        generates (Status status);
+    setMaxFps(float maxFps);
 
-    setTimeLapseConfig(int64_t timePerFrameUs, int64_t timePerCaptureUs)
-        generates (Status status);
+    setTimeLapseConfig(int64_t timePerFrameUs, int64_t timePerCaptureUs);
 
-    setStartTimeUs(int64_t startTimeUs)
-        generates (Status status);
+    setStartTimeUs(int64_t startTimeUs);
 
-    setColorAspects(ColorAspects aspects)
-        generates (Status status);
+    setColorAspects(ColorAspects aspects);
 
-    setTimeOffsetUs(int64_t timeOffsetUs)
-        generates (Status status);
+    setTimeOffsetUs(int64_t timeOffsetUs);
 
-    signalEndOfInputStream()
-        generates (Status status);
+    signalEndOfInputStream();
 
 };
 
diff --git a/media/omx/1.0/IOmxNode.hal b/media/omx/1.0/IOmxNode.hal
index 9483be4..5945b44 100644
--- a/media/omx/1.0/IOmxNode.hal
+++ b/media/omx/1.0/IOmxNode.hal
@@ -46,14 +46,14 @@
      * Invoke a command on the node.
      *
      * @param[in] cmd indicates the type of the command.
-     * @param[in] info holds information about the command.
+     * @param[in] param is a parameter for the command.
      * @param[out] status will be the status of the call.
      *
      * @see OMX_SendCommand() in the OpenMax IL standard.
      */
     sendCommand(
             uint32_t cmd,
-            Bytes info // TODO: describe structure better or point at standard
+            int32_t param
         ) generates (
             Status status
         );
diff --git a/media/omx/1.0/types.hal b/media/omx/1.0/types.hal
index 79c3a44..ccb2ddf 100644
--- a/media/omx/1.0/types.hal
+++ b/media/omx/1.0/types.hal
@@ -34,6 +34,7 @@
 
     NAME_NOT_FOUND          = -2,
     NO_MEMORY               = -12,
+    BAD_VALUE               = -22,
     ERROR_UNSUPPORTED       = -1010,
     UNKNOWN_ERROR           = -2147483648,
 };
@@ -149,7 +150,7 @@
         SharedMemoryAttributes sharedMem;
 
         // if bufferType == ANW_BUFFER
-        GraphicBufferAttributes anwBuffer;
+        AnwBufferAttributes anwBuffer;
 
         // if bufferType == NATIVE_HANDLE
         // No additional attributes.
diff --git a/power/1.0/vts/functional/power_hidl_hal_test.cpp b/power/1.0/vts/functional/power_hidl_hal_test.cpp
index 8833c04..045a34b 100644
--- a/power/1.0/vts/functional/power_hidl_hal_test.cpp
+++ b/power/1.0/vts/functional/power_hidl_hal_test.cpp
@@ -35,18 +35,8 @@
 class PowerHidlTest : public ::testing::Test {
  public:
   virtual void SetUp() override {
-    // TODO(b/33385836) Delete copied code
-    bool getStub = false;
-    char getSubProperty[PROPERTY_VALUE_MAX];
-    if (property_get("vts.hidl.get_stub", getSubProperty, "") > 0) {
-        if (!strcmp(getSubProperty, "true") || !strcmp(getSubProperty, "True") ||
-            !strcmp(getSubProperty, "1")) {
-            getStub = true;
-        }
-    }
-    power = IPower::getService("power", getStub);
+    power = IPower::getService("power");
     ASSERT_NE(power, nullptr);
-    ASSERT_EQ(!getStub, power->isRemote());
   }
 
   virtual void TearDown() override {}
diff --git a/power/1.0/vts/functional/vts/testcases/hal/power/hidl/target/AndroidTest.xml b/power/1.0/vts/functional/vts/testcases/hal/power/hidl/target/AndroidTest.xml
index bb80de2..0eb2142 100644
--- a/power/1.0/vts/functional/vts/testcases/hal/power/hidl/target/AndroidTest.xml
+++ b/power/1.0/vts/functional/vts/testcases/hal/power/hidl/target/AndroidTest.xml
@@ -24,6 +24,7 @@
             _32bit::DATA/nativetest/power_hidl_hal_test/power_hidl_hal_test,
             _64bit::DATA/nativetest64/power_hidl_hal_test/power_hidl_hal_test,
             "/>
+        <option name="test-config-path" value="vts/testcases/hal/power/hidl/target/HalPowerHidlTargetTest.config" />
         <option name="binary-test-type" value="gtest" />
         <option name="test-timeout" value="1m" />
     </test>
diff --git a/power/1.0/vts/functional/vts/testcases/hal/power/hidl/target/HalPowerHidlTargetTest.config b/power/1.0/vts/functional/vts/testcases/hal/power/hidl/target/HalPowerHidlTargetTest.config
new file mode 100644
index 0000000..54c0175
--- /dev/null
+++ b/power/1.0/vts/functional/vts/testcases/hal/power/hidl/target/HalPowerHidlTargetTest.config
@@ -0,0 +1,34 @@
+{
+    "use_gae_db": true,
+    "coverage": true,
+    "modules": [
+        {
+            "module_name": "system/lib64/hw/power.bullhead",
+            "git_project": {
+                "name": "device/lge/bullhead",
+                "path": "device/lge/bullhead"
+            }
+        },
+        {
+            "module_name": "system/lib64/hw/power.marlin",
+            "git_project": {
+                "name": "device/google/marlin",
+                "path": "device/google/marlin"
+            }
+        },
+        {
+            "module_name": "system/lib64/hw/power.sailfish",
+            "git_project": {
+                "name": "device/google/marlin",
+                "path": "device/google/marlin"
+            }
+        },
+        {
+            "module_name": "system/lib64/hw/android.hardware.power@1.0-impl",
+            "git_project": {
+                "name": "platform/hardware/interfaces",
+                "path": "hardware/interfaces"
+            }
+        }
+    ]
+}
diff --git a/tests/bar/1.0/Android.bp b/tests/bar/1.0/Android.bp
index 6ef8ac2..e4c79fa 100644
--- a/tests/bar/1.0/Android.bp
+++ b/tests/bar/1.0/Android.bp
@@ -6,10 +6,12 @@
     cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.tests.bar@1.0",
     srcs: [
         "IBar.hal",
+        "IComplicated.hal",
         "IImportTypes.hal",
     ],
     out: [
         "android/hardware/tests/bar/1.0/BarAll.cpp",
+        "android/hardware/tests/bar/1.0/ComplicatedAll.cpp",
         "android/hardware/tests/bar/1.0/ImportTypesAll.cpp",
     ],
 }
@@ -20,6 +22,7 @@
     cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.tests.bar@1.0",
     srcs: [
         "IBar.hal",
+        "IComplicated.hal",
         "IImportTypes.hal",
     ],
     out: [
@@ -28,6 +31,11 @@
         "android/hardware/tests/bar/1.0/BnBar.h",
         "android/hardware/tests/bar/1.0/BpBar.h",
         "android/hardware/tests/bar/1.0/BsBar.h",
+        "android/hardware/tests/bar/1.0/IComplicated.h",
+        "android/hardware/tests/bar/1.0/IHwComplicated.h",
+        "android/hardware/tests/bar/1.0/BnComplicated.h",
+        "android/hardware/tests/bar/1.0/BpComplicated.h",
+        "android/hardware/tests/bar/1.0/BsComplicated.h",
         "android/hardware/tests/bar/1.0/IImportTypes.h",
         "android/hardware/tests/bar/1.0/IHwImportTypes.h",
         "android/hardware/tests/bar/1.0/BnImportTypes.h",
diff --git a/tests/bar/1.0/IBar.hal b/tests/bar/1.0/IBar.hal
index 21c3473..5f94d07 100644
--- a/tests/bar/1.0/IBar.hal
+++ b/tests/bar/1.0/IBar.hal
@@ -17,9 +17,12 @@
 package android.hardware.tests.bar@1.0;
 
 import android.hardware.tests.foo@1.0::IFoo;
+import android.hardware.tests.foo@1.0::ISimple;
 import android.hardware.tests.foo@1.0::Abc;
 import android.hardware.tests.foo@1.0::Unrelated;
 
+import IComplicated;
+
 interface IBar extends android.hardware.tests.foo@1.0::IFoo {
 
     typedef android.hardware.tests.foo@1.0::IFoo FunkyAlias;
@@ -33,4 +36,6 @@
     expectNullHandle(handle h, Abc xyz) generates (bool hIsNull, bool xyzHasNull);
     takeAMask(BitField bf, bitfield<BitField> first, MyMask second, Mask third)
             generates (BitField bf, uint8_t first, uint8_t second, uint8_t third);
+
+    haveAInterface(ISimple i) generates (ISimple i);
 };
diff --git a/tests/bar/1.0/IComplicated.hal b/tests/bar/1.0/IComplicated.hal
new file mode 100644
index 0000000..deaef8d
--- /dev/null
+++ b/tests/bar/1.0/IComplicated.hal
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+package android.hardware.tests.bar@1.0;
+
+import android.hardware.tests.foo@1.0::ISimple;
+
+interface IComplicated extends ISimple {
+};
diff --git a/tests/bar/1.0/default/Bar.cpp b/tests/bar/1.0/default/Bar.cpp
index a750fe4..4152bb9 100644
--- a/tests/bar/1.0/default/Bar.cpp
+++ b/tests/bar/1.0/default/Bar.cpp
@@ -165,6 +165,13 @@
     return Void();
 }
 
+Return<void> Bar::haveAInterface(const sp<ISimple> &in,
+            haveAInterface_cb _hidl_cb) {
+    _hidl_cb(in);
+    return Void();
+}
+
+
 IBar* HIDL_FETCH_IBar(const char* /* name */) {
     return new Bar();
 }
diff --git a/tests/bar/1.0/default/Bar.h b/tests/bar/1.0/default/Bar.h
index 71737fe..70bffe7 100644
--- a/tests/bar/1.0/default/Bar.h
+++ b/tests/bar/1.0/default/Bar.h
@@ -71,6 +71,8 @@
 
     Return<void> takeAMask(BitField bf, uint8_t first, const MyMask& second, uint8_t third,
             takeAMask_cb _hidl_cb) override;
+    Return<void> haveAInterface(const sp<ISimple> &in,
+            haveAInterface_cb _hidl_cb) override;
 
 private:
     sp<IFoo> mFoo;
diff --git a/tests/foo/1.0/ISimple.hal b/tests/foo/1.0/ISimple.hal
index 92e9d95..0d45835 100644
--- a/tests/foo/1.0/ISimple.hal
+++ b/tests/foo/1.0/ISimple.hal
@@ -18,4 +18,8 @@
 
 interface ISimple {
     getCookie() generates (int32_t cookie);
+    customVecInt() generates (vec<int32_t> chain);
+    customVecStr() generates (vec<string> chain);
+    mystr() generates (string str);
+    myhandle() generates (handle str);
 };
diff --git a/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/TvCecHidlTest.py b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/TvCecHidlTest.py
index ba062d9..cd2374a 100644
--- a/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/TvCecHidlTest.py
+++ b/tv/cec/1.0/vts/functional/vts/testcases/hal/tv_cec/hidl/host/TvCecHidlTest.py
@@ -34,11 +34,15 @@
         self.dut.shell.InvokeTerminal("one")
         self.dut.shell.one.Execute("setenforce 0")  # SELinux permissive mode
 
+        self.dut.shell.one.Execute(
+            "setprop vts.hal.vts.hidl.get_stub true")
+
         self.dut.hal.InitHidlHal(target_type="tv_cec",
                                  target_basepaths=["/system/lib64"],
                                  target_version=1.0,
                                  target_package="android.hardware.tv.cec",
                                  target_component_name="IHdmiCec",
+                                 hw_binder_service_name="tv.cec",
                                  bits=64)
 
     def testGetCecVersion1(self):
diff --git a/vehicle/2.0/vts/functional/vts/testcases/hal/vehicle/hidl/host/VehicleHidlTest.py b/vehicle/2.0/vts/functional/vts/testcases/hal/vehicle/hidl/host/VehicleHidlTest.py
index bc37e59..8da36d1 100644
--- a/vehicle/2.0/vts/functional/vts/testcases/hal/vehicle/hidl/host/VehicleHidlTest.py
+++ b/vehicle/2.0/vts/functional/vts/testcases/hal/vehicle/hidl/host/VehicleHidlTest.py
@@ -33,6 +33,7 @@
         self.dut = self.registerController(android_device)[0]
 
         self.dut.shell.InvokeTerminal("one")
+        self.dut.shell.one.Execute("setenforce 0")  # SELinux permissive mode
 
         if self.enable_profiling:
             profiling_utils.EnableVTSProfiling(self.dut.shell.one)
@@ -55,25 +56,13 @@
             self.ProcessAndUploadTraceData(self.dut, profiling_trace_path)
             profiling_utils.DisableVTSProfiling(self.dut.shell.one)
 
-    def testEcho1(self):
-        """A simple testcase which sends a command."""
-        self.dut.shell.InvokeTerminal("my_shell1")  # creates a remote shell instance.
-        results = self.dut.shell.my_shell1.Execute("echo hello_world")  # runs a shell command.
-        logging.info(str(results[const.STDOUT]))  # prints the stdout
-        asserts.assertEqual(results[const.STDOUT][0].strip(), "hello_world")  # checks the stdout
-        asserts.assertEqual(results[const.EXIT_CODE][0], 0)  # checks the exit code
+    def testListProperties(self):
+        logging.info("vehicle_types")
+        vehicle_types = self.dut.hal.vehicle.GetHidlTypeInterface("types")
+        logging.info("vehicle_types: %s", vehicle_types)
 
-    def testEcho2(self):
-        """A simple testcase which sends two commands."""
-        self.dut.shell.InvokeTerminal("my_shell2")
-        my_shell = getattr(self.dut.shell, "my_shell2")
-        results = my_shell.Execute(["echo hello", "echo world"])
-        logging.info(str(results[const.STDOUT]))
-        asserts.assertEqual(len(results[const.STDOUT]), 2)  # check the number of processed commands
-        asserts.assertEqual(results[const.STDOUT][0].strip(), "hello")
-        asserts.assertEqual(results[const.STDOUT][1].strip(), "world")
-        asserts.assertEqual(results[const.EXIT_CODE][0], 0)
-        asserts.assertEqual(results[const.EXIT_CODE][1], 0)
+        allConfigs = self.dut.hal.vehicle.getAllPropConfigs()
+        logging.info("all supported properties: %s", allConfigs)
 
 if __name__ == "__main__":
     test_runner.main()
diff --git a/vehicle/2.0/vts/types.vts b/vehicle/2.0/vts/types.vts
index d368138..99fa6e7 100644
--- a/vehicle/2.0/vts/types.vts
+++ b/vehicle/2.0/vts/types.vts
@@ -1149,6 +1149,10 @@
     enum_value: {
         scalar_type: "int32_t"
 
+        enumerator: "NONE"
+        scalar_value: {
+            int32_t: 0
+        }
         enumerator: "READ"
         scalar_value: {
             int32_t: 1
diff --git a/wifi/1.0/vts/functional/Android.bp b/wifi/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..422eec5
--- /dev/null
+++ b/wifi/1.0/vts/functional/Android.bp
@@ -0,0 +1,50 @@
+//
+// Copyright (C) 2016 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: "wifi_hidl_test",
+    gtest: true,
+    srcs: [
+        "main.cpp",
+        "wifi_ap_iface_hidl_test.cpp",
+        "wifi_chip_hidl_test.cpp",
+        "wifi_hidl_test.cpp",
+        "wifi_hidl_test_utils.cpp",
+        "wifi_nan_iface_hidl_test.cpp",
+        "wifi_p2p_iface_hidl_test.cpp",
+        "wifi_rtt_controller_hidl_test.cpp",
+        "wifi_sta_iface_hidl_test.cpp"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcutils",
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libnativehelper",
+        "libutils",
+        "android.hardware.wifi@1.0",
+    ],
+    static_libs: ["libgtest"],
+    cflags: [
+        "--coverage",
+        "-O0",
+        "-g",
+    ],
+    ldflags: [
+        "--coverage"
+    ]
+}
diff --git a/wifi/1.0/vts/functional/Android.mk b/wifi/1.0/vts/functional/Android.mk
new file mode 100644
index 0000000..f9e3276
--- /dev/null
+++ b/wifi/1.0/vts/functional/Android.mk
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2016 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 $(call all-subdir-makefiles)
diff --git a/wifi/1.0/vts/functional/main.cpp b/wifi/1.0/vts/functional/main.cpp
new file mode 100644
index 0000000..b33b5eb
--- /dev/null
+++ b/wifi/1.0/vts/functional/main.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2016 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 <android-base/logging.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+class WifiHidlEnvironment : public ::testing::Environment {
+   public:
+    virtual void SetUp() override { stopFramework(); }
+    virtual void TearDown() override { startFramework(); }
+
+   private:
+};
+
+int main(int argc, char** argv) {
+    ::testing::AddGlobalTestEnvironment(new WifiHidlEnvironment);
+    ::testing::InitGoogleTest(&argc, argv);
+    int status = RUN_ALL_TESTS();
+    LOG(INFO) << "Test result = " << status;
+    return status;
+}
diff --git a/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp
new file mode 100644
index 0000000..dc7b0b9
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_ap_iface_hidl_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 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 <android-base/logging.h>
+
+#include <android/hardware/wifi/1.0/IWifiApIface.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifiApIface;
+using ::android::sp;
+
+/**
+ * Fixture to use for all AP Iface HIDL interface tests.
+ */
+class WifiApIfaceHidlTest : public ::testing::Test {
+   public:
+    virtual void SetUp() override {}
+
+    virtual void TearDown() override { stopWifi(); }
+
+   protected:
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifiApIface proxy object is
+ * successfully created.
+ */
+TEST(WifiApIfaceHidlTestNoFixture, Create) {
+    EXPECT_NE(nullptr, getWifiApIface().get());
+    stopWifi();
+}
diff --git a/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp
new file mode 100644
index 0000000..b6ecd8b
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_chip_hidl_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 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 <android-base/logging.h>
+
+#include <android/hardware/wifi/1.0/IWifiChip.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifiChip;
+using ::android::sp;
+
+/**
+ * Fixture to use for all Wifi chip HIDL interface tests.
+ */
+class WifiChipHidlTest : public ::testing::Test {
+   public:
+    virtual void SetUp() override {}
+
+    virtual void TearDown() override { stopWifi(); }
+
+   protected:
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifiChip proxy object is
+ * successfully created.
+ */
+TEST(WifiChipHidlTestNoFixture, Create) {
+    EXPECT_NE(nullptr, getWifiChip().get());
+    stopWifi();
+}
diff --git a/wifi/1.0/vts/functional/wifi_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_hidl_test.cpp
new file mode 100644
index 0000000..3e350e5
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_hidl_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 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 <android-base/logging.h>
+
+#include <android/hardware/wifi/1.0/IWifi.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifi;
+using ::android::sp;
+
+/**
+ * Fixture to use for all root Wifi HIDL interface tests.
+ */
+class WifiHidlTest : public ::testing::Test {
+   public:
+    virtual void SetUp() override {}
+
+    virtual void TearDown() override { stopWifi(); }
+
+   protected:
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifi proxy object is
+ * successfully created.
+ */
+TEST(WifiHidlTestNoFixture, Create) {
+    EXPECT_NE(nullptr, getWifi().get());
+    stopWifi();
+}
diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
new file mode 100644
index 0000000..f88b866
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.cpp
@@ -0,0 +1,278 @@
+/*
+ * Copyright (C) 2016 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 <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifi;
+using ::android::hardware::wifi::V1_0::IWifiApIface;
+using ::android::hardware::wifi::V1_0::IWifiChip;
+using ::android::hardware::wifi::V1_0::IWifiNanIface;
+using ::android::hardware::wifi::V1_0::IWifiP2pIface;
+using ::android::hardware::wifi::V1_0::IWifiRttController;
+using ::android::hardware::wifi::V1_0::IWifiStaIface;
+using ::android::hardware::wifi::V1_0::ChipModeId;
+using ::android::hardware::wifi::V1_0::ChipId;
+using ::android::hardware::wifi::V1_0::IfaceType;
+using ::android::hardware::wifi::V1_0::WifiStatus;
+using ::android::hardware::wifi::V1_0::WifiStatusCode;
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+
+const char kWifiServiceName[] = "wifi";
+
+void stopFramework() {
+    ASSERT_EQ(std::system("svc wifi disable"), 0);
+    sleep(5);
+}
+
+void startFramework() { ASSERT_EQ(std::system("svc wifi enable"), 0); }
+
+sp<IWifi> getWifi() {
+    sp<IWifi> wifi = IWifi::getService(kWifiServiceName);
+    return wifi;
+}
+
+sp<IWifiChip> getWifiChip() {
+    sp<IWifi> wifi = getWifi();
+    if (!wifi.get()) {
+        return nullptr;
+    }
+
+    bool operation_failed = false;
+    wifi->start([&](WifiStatus status) {
+        if (status.code != WifiStatusCode::SUCCESS) {
+            operation_failed = true;
+        }
+    });
+    if (operation_failed) {
+        return nullptr;
+    }
+
+    std::vector<ChipId> wifi_chip_ids;
+    wifi->getChipIds(
+        [&](const WifiStatus& status, const hidl_vec<ChipId>& chip_ids) {
+            if (status.code != WifiStatusCode::SUCCESS) {
+                operation_failed = true;
+            }
+            wifi_chip_ids = chip_ids;
+        });
+    // We don't expect more than 1 chip currently.
+    if (operation_failed || wifi_chip_ids.size() != 1) {
+        return nullptr;
+    }
+
+    sp<IWifiChip> wifi_chip;
+    wifi->getChip(wifi_chip_ids[0],
+                  [&](const WifiStatus& status, const sp<IWifiChip>& chip) {
+                      if (status.code != WifiStatusCode::SUCCESS) {
+                          operation_failed = true;
+                      }
+                      wifi_chip = chip;
+                  });
+    if (operation_failed) {
+        return nullptr;
+    }
+    return wifi_chip;
+}
+
+// Since we currently only support one iface of each type. Just iterate thru the
+// modes of operation and find the mode ID to use for that iface type.
+bool findModeToSupportIfaceType(IfaceType type,
+                                const std::vector<IWifiChip::ChipMode>& modes,
+                                ChipModeId* mode_id) {
+    for (const auto& mode : modes) {
+        std::vector<IWifiChip::ChipIfaceCombination> combinations =
+            mode.availableCombinations;
+        for (const auto& combination : combinations) {
+            std::vector<IWifiChip::ChipIfaceCombinationLimit> iface_limits =
+                combination.limits;
+            for (const auto& iface_limit : iface_limits) {
+                std::vector<IfaceType> iface_types = iface_limit.types;
+                for (const auto& iface_type : iface_types) {
+                    if (iface_type == type) {
+                        *mode_id = mode.id;
+                        return true;
+                    }
+                }
+            }
+        }
+    }
+    return false;
+}
+
+bool configureChipToSupportIfaceType(const sp<IWifiChip>& wifi_chip,
+                                     IfaceType type) {
+    bool operation_failed = false;
+    std::vector<IWifiChip::ChipMode> chip_modes;
+    wifi_chip->getAvailableModes(
+        [&](WifiStatus status, const hidl_vec<IWifiChip::ChipMode>& modes) {
+            if (status.code != WifiStatusCode::SUCCESS) {
+                operation_failed = true;
+            }
+            chip_modes = modes;
+        });
+    if (operation_failed) {
+        return false;
+    }
+
+    ChipModeId mode_id;
+    if (!findModeToSupportIfaceType(type, chip_modes, &mode_id)) {
+        return false;
+    }
+
+    wifi_chip->configureChip(mode_id, [&](WifiStatus status) {
+        if (status.code != WifiStatusCode::SUCCESS) {
+            operation_failed = true;
+        }
+    });
+    if (operation_failed) {
+        return false;
+    }
+    return true;
+}
+
+sp<IWifiApIface> getWifiApIface() {
+    sp<IWifiChip> wifi_chip = getWifiChip();
+    if (!wifi_chip.get()) {
+        return nullptr;
+    }
+    if (!configureChipToSupportIfaceType(wifi_chip, IfaceType::AP)) {
+        return nullptr;
+    }
+
+    bool operation_failed = false;
+    sp<IWifiApIface> wifi_ap_iface;
+    wifi_chip->createApIface(
+        [&](const WifiStatus& status, const sp<IWifiApIface>& iface) {
+            if (status.code != WifiStatusCode::SUCCESS) {
+                operation_failed = true;
+            }
+            wifi_ap_iface = iface;
+        });
+    if (operation_failed) {
+        return nullptr;
+    }
+    return wifi_ap_iface;
+}
+
+sp<IWifiNanIface> getWifiNanIface() {
+    sp<IWifiChip> wifi_chip = getWifiChip();
+    if (!wifi_chip.get()) {
+        return nullptr;
+    }
+    if (!configureChipToSupportIfaceType(wifi_chip, IfaceType::NAN)) {
+        return nullptr;
+    }
+
+    bool operation_failed = false;
+    sp<IWifiNanIface> wifi_nan_iface;
+    wifi_chip->createNanIface(
+        [&](const WifiStatus& status, const sp<IWifiNanIface>& iface) {
+            if (status.code != WifiStatusCode::SUCCESS) {
+                operation_failed = true;
+            }
+            wifi_nan_iface = iface;
+        });
+    if (operation_failed) {
+        return nullptr;
+    }
+    return wifi_nan_iface;
+}
+
+sp<IWifiP2pIface> getWifiP2pIface() {
+    sp<IWifiChip> wifi_chip = getWifiChip();
+    if (!wifi_chip.get()) {
+        return nullptr;
+    }
+    if (!configureChipToSupportIfaceType(wifi_chip, IfaceType::P2P)) {
+        return nullptr;
+    }
+
+    bool operation_failed = false;
+    sp<IWifiP2pIface> wifi_p2p_iface;
+    wifi_chip->createP2pIface(
+        [&](const WifiStatus& status, const sp<IWifiP2pIface>& iface) {
+            if (status.code != WifiStatusCode::SUCCESS) {
+                operation_failed = true;
+            }
+            wifi_p2p_iface = iface;
+        });
+    if (operation_failed) {
+        return nullptr;
+    }
+    return wifi_p2p_iface;
+}
+
+sp<IWifiStaIface> getWifiStaIface() {
+    sp<IWifiChip> wifi_chip = getWifiChip();
+    if (!wifi_chip.get()) {
+        return nullptr;
+    }
+    if (!configureChipToSupportIfaceType(wifi_chip, IfaceType::STA)) {
+        return nullptr;
+    }
+
+    bool operation_failed = false;
+    sp<IWifiStaIface> wifi_sta_iface;
+    wifi_chip->createStaIface(
+        [&](const WifiStatus& status, const sp<IWifiStaIface>& iface) {
+            if (status.code != WifiStatusCode::SUCCESS) {
+                operation_failed = true;
+            }
+            wifi_sta_iface = iface;
+        });
+    if (operation_failed) {
+        return nullptr;
+    }
+    return wifi_sta_iface;
+}
+
+sp<IWifiRttController> getWifiRttController() {
+    sp<IWifiChip> wifi_chip = getWifiChip();
+    if (!wifi_chip.get()) {
+        return nullptr;
+    }
+    sp<IWifiStaIface> wifi_sta_iface = getWifiStaIface();
+    if (!wifi_sta_iface.get()) {
+        return nullptr;
+    }
+
+    bool operation_failed = false;
+    sp<IWifiRttController> wifi_rtt_controller;
+    wifi_chip->createRttController(
+        wifi_sta_iface, [&](const WifiStatus& status,
+                            const sp<IWifiRttController>& controller) {
+            if (status.code != WifiStatusCode::SUCCESS) {
+                operation_failed = true;
+            }
+            wifi_rtt_controller = controller;
+        });
+    if (operation_failed) {
+        return nullptr;
+    }
+    return wifi_rtt_controller;
+}
+
+void stopWifi() {
+    sp<IWifi> wifi = getWifi();
+    ASSERT_NE(wifi, nullptr);
+    wifi->stop([](const WifiStatus& status) {
+        ASSERT_EQ(status.code, WifiStatusCode::SUCCESS);
+    });
+}
diff --git a/wifi/1.0/vts/functional/wifi_hidl_test_utils.h b/wifi/1.0/vts/functional/wifi_hidl_test_utils.h
new file mode 100644
index 0000000..08933d9
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_hidl_test_utils.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#pragma once
+
+#include <android/hardware/wifi/1.0/IWifi.h>
+#include <android/hardware/wifi/1.0/IWifiApIface.h>
+#include <android/hardware/wifi/1.0/IWifiChip.h>
+#include <android/hardware/wifi/1.0/IWifiNanIface.h>
+#include <android/hardware/wifi/1.0/IWifiP2pIface.h>
+#include <android/hardware/wifi/1.0/IWifiRttController.h>
+#include <android/hardware/wifi/1.0/IWifiStaIface.h>
+
+// Used to stop the android framework (wifi service) before every
+// test.
+void stopFramework();
+void startFramework();
+
+// Helper functions to obtain references to the various HIDL interface objects.
+// Note: We only have a single instance of each of these objects currently.
+// These helper functions should be modified to return vectors if we support
+// multiple instances.
+android::sp<android::hardware::wifi::V1_0::IWifi> getWifi();
+android::sp<android::hardware::wifi::V1_0::IWifiChip> getWifiChip();
+android::sp<android::hardware::wifi::V1_0::IWifiApIface> getWifiApIface();
+android::sp<android::hardware::wifi::V1_0::IWifiNanIface> getWifiNanIface();
+android::sp<android::hardware::wifi::V1_0::IWifiP2pIface> getWifiP2pIface();
+android::sp<android::hardware::wifi::V1_0::IWifiStaIface> getWifiStaIface();
+android::sp<android::hardware::wifi::V1_0::IWifiRttController>
+getWifiRttController();
+// Used to trigger IWifi.stop() at the end of every test.
+void stopWifi();
diff --git a/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp
new file mode 100644
index 0000000..a8be48c
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_nan_iface_hidl_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Nanache 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 <android-base/logging.h>
+
+#include <android/hardware/wifi/1.0/IWifiNanIface.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifiNanIface;
+using ::android::sp;
+
+/**
+ * Fixture to use for all NAN Iface HIDL interface tests.
+ */
+class WifiNanIfaceHidlTest : public ::testing::Test {
+   public:
+    virtual void SetUp() override {}
+
+    virtual void TearDown() override { stopWifi(); }
+
+   protected:
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifiNanIface proxy object is
+ * successfully created.
+ */
+TEST(WifiNanIfaceHidlTestNoFixture, Create) {
+    EXPECT_NE(nullptr, getWifiNanIface().get());
+    stopWifi();
+}
diff --git a/wifi/1.0/vts/functional/wifi_p2p_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_p2p_iface_hidl_test.cpp
new file mode 100644
index 0000000..e29226d
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_p2p_iface_hidl_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the P2pache 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 <android-base/logging.h>
+
+#include <android/hardware/wifi/1.0/IWifiP2pIface.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifiP2pIface;
+using ::android::sp;
+
+/**
+ * Fixture to use for all P2P Iface HIDL interface tests.
+ */
+class WifiP2pIfaceHidlTest : public ::testing::Test {
+   public:
+    virtual void SetUp() override {}
+
+    virtual void TearDown() override { stopWifi(); }
+
+   protected:
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifiP2pIface proxy object is
+ * successfully created.
+ */
+TEST(WifiP2pIfaceHidlTestNoFixture, Create) {
+    EXPECT_NE(nullptr, getWifiP2pIface().get());
+    stopWifi();
+}
diff --git a/wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp
new file mode 100644
index 0000000..7aee761
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_rtt_controller_hidl_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 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 <android-base/logging.h>
+
+#include <android/hardware/wifi/1.0/IWifiRttController.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifiRttController;
+using ::android::sp;
+
+/**
+ * Fixture to use for all RTT controller HIDL interface tests.
+ */
+class WifiRttControllerHidlTest : public ::testing::Test {
+   public:
+    virtual void SetUp() override {}
+
+    virtual void TearDown() override { stopWifi(); }
+
+   protected:
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifiRttController proxy object is
+ * successfully created.
+ */
+TEST(WifiRttControllerHidlTestNoFixture, Create) {
+    EXPECT_NE(nullptr, getWifiRttController().get());
+    stopWifi();
+}
diff --git a/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp b/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp
new file mode 100644
index 0000000..770763c
--- /dev/null
+++ b/wifi/1.0/vts/functional/wifi_sta_iface_hidl_test.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Staache 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 <android-base/logging.h>
+
+#include <android/hardware/wifi/1.0/IWifiStaIface.h>
+
+#include <gtest/gtest.h>
+
+#include "wifi_hidl_test_utils.h"
+
+using ::android::hardware::wifi::V1_0::IWifiStaIface;
+using ::android::sp;
+
+/**
+ * Fixture to use for all STA Iface HIDL interface tests.
+ */
+class WifiStaIfaceHidlTest : public ::testing::Test {
+   public:
+    virtual void SetUp() override {}
+
+    virtual void TearDown() override { stopWifi(); }
+
+   protected:
+};
+
+/*
+ * Create:
+ * Ensures that an instance of the IWifiStaIface proxy object is
+ * successfully created.
+ */
+TEST(WifiStaIfaceHidlTestNoFixture, Create) {
+    EXPECT_NE(nullptr, getWifiStaIface().get());
+    stopWifi();
+}
diff --git a/wifi/Android.bp b/wifi/Android.bp
index ea43db4..d4e0fda 100644
--- a/wifi/Android.bp
+++ b/wifi/Android.bp
@@ -1,5 +1,6 @@
 // This is an autogenerated file, do not edit.
 subdirs = [
     "1.0",
+    "1.0/vts/functional",
     "supplicant/1.0",
 ]