Merge "Add more HVAC properties to default vehicle HAL"
diff --git a/biometrics/fingerprint/2.1/IBiometricsFingerprint.hal b/biometrics/fingerprint/2.1/IBiometricsFingerprint.hal
index b7f8d88..3b24a2c 100644
--- a/biometrics/fingerprint/2.1/IBiometricsFingerprint.hal
+++ b/biometrics/fingerprint/2.1/IBiometricsFingerprint.hal
@@ -25,13 +25,12 @@
    * This call must block if the HAL state machine is in busy state until HAL
    * leaves the busy state.
    *
-   * @return isOk indicates if the request is accepted.
-   * @return debugErrno is a value the framework logs in case isOk == false.
+   * @return debugErrno is a value the framework logs in case it is not 0.
    */
   @callflow(next={"setActiveGroup"})
   @entry
   setNotify(IBiometricsFingerprintClientCallback clientCallback)
-      generates (bool isOk, int32_t debugErrno);
+      generates (RequestStatus debugErrno);
 
   /*
    * Fingerprint pre-enroll enroll request:
@@ -62,25 +61,23 @@
    * @param gid a framework defined fingerprint set (group) id.
    * @param timeoutSec a timeout in seconds.
    *
-   * @return isOk indicates if the request is accepted.
-   * @return debugErrno is a value the framework logs in case isOk == false.
+   * @return debugErrno is a value the framework logs in case it is not 0.
    *
    * A notify() function may be called with a more detailed error structure.
    */
   @callflow(next={"cancel", "enroll", "postEnroll", "remove"})
-  enroll(HwAuthToken hat, uint32_t gid, uint32_t timeoutSec)
-      generates (bool isOk, int32_t debugErrno);
+  enroll(uint8_t[69] hat, uint32_t gid, uint32_t timeoutSec)
+      generates (RequestStatus debugErrno);
 
   /*
    * Finishes the enroll operation and invalidates the preEnroll() generated
    * challenge. This must be called at the end of a multi-finger enrollment
    * session to indicate that no more fingers may be added.
    *
-   * @return isOk indicates if the request is accepted.
-   * @return debugErrno is a value the framework logs in case isOk == false.
+   * @return debugErrno is a value the framework logs in case it is not 0.
    */
   @callflow(next={"authenticate", "setActiveGroup", "enumerate", "remove"})
-  postEnroll() generates (bool isOk, int32_t debugErrno);
+  postEnroll() generates (RequestStatus debugErrno);
 
   /*
    * getAuthenticatorId:
@@ -99,12 +96,11 @@
    * to all running clients. Switches the HAL state machine back to the idle
    * state. Unlike enrollDone() doesn't invalidate the preEnroll() challenge.
    *
-   * @return isOk indicates if the request is accepted.
-   * @return debugErrno is a value the framework logs in case isOk == false.
+   * @return debugErrno is a value the framework logs in case it is not 0.
    */
   @callflow(next={"authenticate", "enroll", "enumerate", "remove",
     "setActiveGroup"})
-  cancel() generates (bool isOk, int32_t debugErrno);
+  cancel() generates (RequestStatus debugErrno);
 
   /*
    * Enumerate all the fingerprint templates found in the directory set by
@@ -115,11 +111,10 @@
    * fingerprintMsg.data.enumerated.remainingTemplates indicating how many more
    * enumeration messages to expect.
    *
-   * @return isOk indicates if the request is accepted.
-   * @return debugErrno is a value the framework logs in case isOk == false.
+   * @return debugErrno is a value the framework logs in case it is not 0.
    */
   @callflow(next={"remove", "enroll", "authenticate", "setActiveGroup"})
-  enumerate() generates (bool isOk, int32_t debugErrno);
+  enumerate() generates (RequestStatus debugErrno);
 
   /*
    * Fingerprint remove request:
@@ -135,12 +130,11 @@
    * @param fid template id to delete or 0 to delete all templates within the
    * current group.
    *
-   * @return isOk indicates if the request is accepted.
-   * @return debugErrno is a value the framework logs in case isOk == false.
+   * @return debugErrno is a value the framework logs in case it is not 0.
    */
   @callflow(next={"enumerate", "authenticate", "cancel", "getAuthenticatorId",
     "setActiveGroup"})
-  remove(uint32_t gid, uint32_t fid) generates (bool isOk, int32_t debugErrno);
+  remove(uint32_t gid, uint32_t fid) generates (RequestStatus debugErrno);
 
   /*
    * Restricts the HAL operation to a set of fingerprints belonging to a group
@@ -150,12 +144,11 @@
    * @param gid the fingerprint group (set) id.
    * @param storePath filesystem path to the template storage directory.
    *
-   * @return isOk indicates if the request is accepted.
-   * @return debugErrno is a value the framework logs in case isOk == false.
+   * @return debugErrno is a value the framework logs in case it is not 0.
    */
   @callflow(next={"authenticate", "preEnroll", "enumerate", "remove"})
   setActiveGroup(uint32_t gid, string storePath)
-      generates (bool isOk, int32_t debugErrno);
+      generates (RequestStatus debugErrno);
 
   /*
    * Authenticates an operation identified by operationId
@@ -163,10 +156,9 @@
    * @param operationId operation id.
    * @param gid fingerprint group id.
    *
-   * @return isOk indicates if the request is accepted.
-   * @return debugErrno is a value the framework logs in case isOk == false.
+   * @return debugErrno is a value the framework logs in case it is not 0.
    */
   @callflow(next={"cancel", "preEnroll", "remove"})
   authenticate(uint64_t operationId, uint32_t gid)
-      generates (bool isOk, int32_t debugErrno);
+      generates (RequestStatus debugErrno);
 };
diff --git a/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp b/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp
index 3ee7836..1316686 100644
--- a/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp
+++ b/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#define LOG_TAG "android.hardware.biometrics.fingerprint@2.1-impl"
 
 #include <hardware/hardware.h>
 #include <hardware/fingerprint.h>
@@ -25,6 +26,9 @@
 namespace V2_1 {
 namespace implementation {
 
+using RequestStatus =
+        android::hardware::biometrics::fingerprint::V2_1::RequestStatus;
+
 sp<IBiometricsFingerprintClientCallback>
     BiometricsFingerprint::mClientCallback = nullptr;
 
@@ -46,78 +50,81 @@
     mDevice = NULL;
 }
 
-Return<void> BiometricsFingerprint::setNotify(
-        const sp<IBiometricsFingerprintClientCallback>& clientCallback,
-        setNotify_cb cb)  {
+Return<RequestStatus> BiometricsFingerprint::ErrorFilter(int32_t error) {
+    switch(error) {
+        case 0: return RequestStatus::SYS_OK;
+        case -2: return RequestStatus::SYS_ENOENT;
+        case -4: return RequestStatus::SYS_EINTR;
+        case -5: return RequestStatus::SYS_EIO;
+        case -11: return RequestStatus::SYS_EAGAIN;
+        case -12: return RequestStatus::SYS_ENOMEM;
+        case -13: return RequestStatus::SYS_EACCES;
+        case -14: return RequestStatus::SYS_EFAULT;
+        case -16: return RequestStatus::SYS_EBUSY;
+        case -22: return RequestStatus::SYS_EINVAL;
+        case -28: return RequestStatus::SYS_ENOSPC;
+        case -110: return RequestStatus::SYS_ETIMEDOUT;
+        default:
+            ALOGE("An unknown error returned from fingerprint vendor library");
+            return RequestStatus::SYS_UNKNOWN;
+    }
+}
+
+Return<RequestStatus> BiometricsFingerprint::setNotify(
+        const sp<IBiometricsFingerprintClientCallback>& clientCallback) {
     mClientCallback = clientCallback;
-    int32_t debugErrno = mDevice->set_notify(mDevice, notify);
-    cb(debugErrno == 0, debugErrno);
-    return Void();
+    return RequestStatus::SYS_OK;
 }
 
 Return<uint64_t> BiometricsFingerprint::preEnroll()  {
     return mDevice->pre_enroll(mDevice);
 }
 
-Return<void> BiometricsFingerprint::enroll(const HwAuthToken& hat, uint32_t gid,
-        uint32_t timeoutSec, enroll_cb cb)  {
+Return<RequestStatus> BiometricsFingerprint::enroll(const hidl_array<uint8_t, 69>& hat,
+        uint32_t gid, uint32_t timeoutSec) {
     const hw_auth_token_t* authToken =
-        reinterpret_cast<const hw_auth_token_t*>(&hat);
-    int32_t debugErrno = mDevice->enroll(mDevice, authToken, gid, timeoutSec);
-    cb(debugErrno == 0, debugErrno);
-    return Void();
+        reinterpret_cast<const hw_auth_token_t*>(hat.data());
+    return ErrorFilter(mDevice->enroll(mDevice, authToken, gid, timeoutSec));
 }
 
-Return<void> BiometricsFingerprint::postEnroll(postEnroll_cb cb) {
-    int32_t debugErrno = mDevice->post_enroll(mDevice);
-    cb(debugErrno == 0, debugErrno);
-    return Void();
+Return<RequestStatus> BiometricsFingerprint::postEnroll() {
+    return ErrorFilter(mDevice->post_enroll(mDevice));
 }
 
 Return<uint64_t> BiometricsFingerprint::getAuthenticatorId() {
     return mDevice->get_authenticator_id(mDevice);
 }
 
-Return<void> BiometricsFingerprint::cancel(cancel_cb cb) {
-    int32_t debugErrno = mDevice->cancel(mDevice);
-    cb(debugErrno == 0, debugErrno);
-    return Void();
+Return<RequestStatus> BiometricsFingerprint::cancel() {
+    return ErrorFilter(mDevice->cancel(mDevice));
 }
 
-Return<void> BiometricsFingerprint::enumerate(enumerate_cb cb)  {
-    int32_t debugErrno = mDevice->enumerate(mDevice);
-    cb(debugErrno == 0, debugErrno);
-    return Void();
+Return<RequestStatus> BiometricsFingerprint::enumerate()  {
+    return ErrorFilter(mDevice->enumerate(mDevice));
 }
 
-Return<void> BiometricsFingerprint::remove(uint32_t gid, uint32_t fid,
-        remove_cb cb)  {
-    int32_t debugErrno = mDevice->remove(mDevice, gid, fid);
-    cb(debugErrno == 0, debugErrno);
-    return Void();
+Return<RequestStatus> BiometricsFingerprint::remove(uint32_t gid, uint32_t fid) {
+    return ErrorFilter(mDevice->remove(mDevice, gid, fid));
 }
 
-Return<void> BiometricsFingerprint::setActiveGroup(uint32_t gid,
-        const hidl_string& storePath, setActiveGroup_cb cb)  {
+Return<RequestStatus> BiometricsFingerprint::setActiveGroup(uint32_t gid,
+        const hidl_string& storePath) {
     if (storePath.size() >= PATH_MAX || storePath.size() <= 0) {
         ALOGE("Bad path length: %zd", storePath.size());
     }
-    int32_t debugErrno = mDevice->set_active_group(mDevice, gid,
-        storePath.c_str());
-    cb(debugErrno == 0, debugErrno);
-    return Void();
+    return ErrorFilter(mDevice->set_active_group(mDevice, gid,
+                                                    storePath.c_str()));
 }
 
-Return<void> BiometricsFingerprint::authenticate(uint64_t operationId,
-        uint32_t gid, authenticate_cb cb)  {
-    int32_t debugErrno = mDevice->authenticate(mDevice, operationId, gid);
-    cb(debugErrno == 0, debugErrno);
-    return Void();
+Return<RequestStatus> BiometricsFingerprint::authenticate(uint64_t operationId,
+        uint32_t gid) {
+    return ErrorFilter(mDevice->authenticate(mDevice, operationId, gid));
 }
 
 IBiometricsFingerprint* HIDL_FETCH_IBiometricsFingerprint(const char*) {
     int err;
     const hw_module_t *hw_mdl = NULL;
+    ALOGE("Opening fingerprint hal library...");
     if (0 != (err = hw_get_module(FINGERPRINT_HARDWARE_MODULE_ID, &hw_mdl))) {
         ALOGE("Can't open fingerprint HW Module, error: %d", err);
         return nullptr;
@@ -141,8 +148,16 @@
         return nullptr;
     }
 
-    return new BiometricsFingerprint(
-        reinterpret_cast<fingerprint_device_t*>(device));
+    fingerprint_device_t* fp_device =
+        reinterpret_cast<fingerprint_device_t*>(device);
+
+    if (0 != (err =
+            fp_device->set_notify(fp_device, BiometricsFingerprint::notify))) {
+        ALOGE("Can't register fingerprint module callback, error: %d", err);
+        return nullptr;
+    }
+
+    return new BiometricsFingerprint(fp_device);
 }
 
 } // namespace implementation
diff --git a/biometrics/fingerprint/2.1/default/BiometricsFingerprint.h b/biometrics/fingerprint/2.1/default/BiometricsFingerprint.h
index 4fdc328..de8727b 100644
--- a/biometrics/fingerprint/2.1/default/BiometricsFingerprint.h
+++ b/biometrics/fingerprint/2.1/default/BiometricsFingerprint.h
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-#ifndef HIDL_GENERATED_android_hardware_biometrics_fingerprint_V2_1_BiometricsFingerprint_H_
-#define HIDL_GENERATED_android_hardware_biometrics_fingerprint_V2_1_BiometricsFingerprint_H_
+#ifndef ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_1_BIOMETRICSFINGERPRINT_H
+#define ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_1_BIOMETRICSFINGERPRINT_H
 
 #include <utils/Log.h>
+#include <hidl/MQDescriptor.h>
 #include <android/hardware/biometrics/fingerprint/2.1/IBiometricsFingerprint.h>
 #include <hidl/Status.h>
 
-#include <hidl/MQDescriptor.h>
 namespace android {
 namespace hardware {
 namespace biometrics {
@@ -29,9 +29,9 @@
 namespace V2_1 {
 namespace implementation {
 
-using ::android::hardware::biometrics::fingerprint::V2_1::HwAuthToken;
 using ::android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprint;
 using ::android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprintClientCallback;
+using ::android::hardware::biometrics::fingerprint::V2_1::RequestStatus;
 using ::android::hardware::Return;
 using ::android::hardware::Void;
 using ::android::hardware::hidl_vec;
@@ -43,16 +43,16 @@
     BiometricsFingerprint(fingerprint_device_t *device);
     ~BiometricsFingerprint();
     // Methods from ::android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprint follow.
-    Return<void> setNotify(const sp<IBiometricsFingerprintClientCallback>& clientCallback, setNotify_cb _hidl_cb)  override;
-    Return<uint64_t> preEnroll()  override;
-    Return<void> enroll(const HwAuthToken& hat, uint32_t gid, uint32_t timeoutSec, enroll_cb _hidl_cb)  override;
-    Return<void> postEnroll(postEnroll_cb _hidl_cb)  override;
-    Return<uint64_t> getAuthenticatorId()  override;
-    Return<void> cancel(cancel_cb _hidl_cb)  override;
-    Return<void> enumerate(enumerate_cb _hidl_cb)  override;
-    Return<void> remove(uint32_t gid, uint32_t fid, remove_cb _hidl_cb)  override;
-    Return<void> setActiveGroup(uint32_t gid, const hidl_string& storePath, setActiveGroup_cb _hidl_cb)  override;
-    Return<void> authenticate(uint64_t operationId, uint32_t gid, authenticate_cb _hidl_cb)  override;
+    Return<RequestStatus> setNotify(const sp<IBiometricsFingerprintClientCallback>& clientCallback) override;
+    Return<uint64_t> preEnroll() override;
+    Return<RequestStatus> enroll(const hidl_array<uint8_t, 69>& hat, uint32_t gid, uint32_t timeoutSec) override;
+    Return<RequestStatus> postEnroll() override;
+    Return<uint64_t> getAuthenticatorId() override;
+    Return<RequestStatus> cancel() override;
+    Return<RequestStatus> enumerate() override;
+    Return<RequestStatus> remove(uint32_t gid, uint32_t fid) override;
+    Return<RequestStatus> setActiveGroup(uint32_t gid, const hidl_string& storePath) override;
+    Return<RequestStatus> authenticate(uint64_t operationId, uint32_t gid) override;
     static void notify(const fingerprint_msg_t *notify_msg) {
         if (mClientCallback == nullptr) {
             ALOGE("Receiving callbacks before the client callback is registered.");
@@ -63,6 +63,7 @@
         mClientCallback->notify(msg);
     }
 private:
+    Return<RequestStatus> ErrorFilter(int32_t error);
     static sp<IBiometricsFingerprintClientCallback> mClientCallback;
     fingerprint_device_t *mDevice;
 };
@@ -76,4 +77,4 @@
 }  // namespace hardware
 }  // namespace android
 
-#endif  // HIDL_GENERATED_android_hardware_biometrics_fingerprint_V2_1_BiometricsFingerprint_H_
+#endif  // ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_1_BIOMETRICSFINGERPRINT_H
diff --git a/biometrics/fingerprint/2.1/types.hal b/biometrics/fingerprint/2.1/types.hal
index cf68c04..201ec7c 100644
--- a/biometrics/fingerprint/2.1/types.hal
+++ b/biometrics/fingerprint/2.1/types.hal
@@ -17,6 +17,27 @@
 package android.hardware.biometrics.fingerprint@2.1;
 
 /*
+ * Request status indicates whether the request is accepted by the vendor
+ * implementation or not. These values are taken from the errno set,
+ * except for the SYS_UNKNOWN
+ */
+enum RequestStatus : int32_t {
+  SYS_UNKNOWN = 1,
+  SYS_OK = 0,
+  SYS_ENOENT = -2,
+  SYS_EINTR = -4,
+  SYS_EIO = -5,
+  SYS_EAGAIN = -11,
+  SYS_ENOMEM = -12,
+  SYS_EACCES = -13,
+  SYS_EFAULT = -14,
+  SYS_EBUSY = -16,
+  SYS_EINVAL = -22,
+  SYS_ENOSPC = -28,
+  SYS_ETIMEDOUT = -110,
+};
+
+/*
  * Fingerprint errors are meant to tell the framework to terminate the current
  * operation and ask for the user to correct the situation. These will almost
  * always result in messaging and user interaction to correct the problem.
@@ -66,25 +87,6 @@
   ACQUIRED_VENDOR_BASE = 1000,
 };
 
-/* TODO import from keymaster HIDL when available */
-enum HwAuthenticatorType : uint32_t {
-  HW_AUTH_NONE = 0,
-  HW_AUTH_PASSWORD = 1,
-  HW_AUTH_FINGERPRINT = 2,
-  HW_AUTH_ANY = 0xffffffff,
-};
-
-/* TODO import from keymaster HIDL when available */
-struct HwAuthToken {
-  uint8_t version;
-  uint64_t challenge;
-  uint64_t userId;
-  uint64_t authenticatorId;
-  uint32_t authenticatorType;
-  uint64_t timestamp;
-  uint8_t[32] hmac;
-};
-
 struct FingerprintFingerId {
   /* Group ID */
   uint32_t gid;
@@ -121,7 +123,7 @@
   /* Matched template ID */
   FingerprintFingerId finger;
   /* Authentication result from the keymaster */
-  HwAuthToken hat;
+  uint8_t[69] hat;
 };
 
 /* Run time type identification for the notify() call payload. */
@@ -137,12 +139,12 @@
 struct FingerprintMsg {
   /* Selects the payload below */
   FingerprintMsgType type;
-  union data {
+  union Data {
     FingerprintError error;
     FingerprintEnroll enroll;
     FingerprintEnumerated enumerated;
     FingerprintRemoved removed;
     FingerprintAcquired acquired;
     FingerprintAuthenticated authenticated;
-  };
+  } data;
 };
diff --git a/media/1.0/Android.bp b/media/1.0/Android.bp
new file mode 100644
index 0000000..c8bdd82
--- /dev/null
+++ b/media/1.0/Android.bp
@@ -0,0 +1,45 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+genrule {
+    name: "android.hardware.media@1.0_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces android.hardware.media@1.0",
+    srcs: [
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/media/1.0/types.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.media@1.0_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces android.hardware.media@1.0",
+    srcs: [
+        "types.hal",
+    ],
+    out: [
+        "android/hardware/media/1.0/types.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.media@1.0",
+    generated_sources: ["android.hardware.media@1.0_genc++"],
+    generated_headers: ["android.hardware.media@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.media@1.0_genc++_headers"],
+    shared_libs: [
+        "libhidl",
+        "libhwbinder",
+        "libutils",
+        "libcutils",
+        "android.hardware.graphics.common@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidl",
+        "libhwbinder",
+        "libutils",
+        "android.hardware.graphics.common@1.0",
+    ],
+}
diff --git a/media/1.0/types.hal b/media/1.0/types.hal
new file mode 100644
index 0000000..25931f8
--- /dev/null
+++ b/media/1.0/types.hal
@@ -0,0 +1,77 @@
+/*
+ * 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.media@1.0;
+
+import android.hardware.graphics.common@1.0::PixelFormat;
+
+/**
+ * Aliases
+ */
+typedef handle FileDescriptor; // This must have no more than one fd.
+typedef FileDescriptor Fence;
+typedef int32_t Status; // TODO: convert to an enum
+typedef vec<uint8_t> Bytes;
+
+/**
+ * Ref: frameworks/native/include/ui/GraphicBuffer.h
+ * Ref: system/core/include/system/window.h
+ */
+
+/**
+ * This struct contains attributes for a gralloc buffer that can be put into a
+ * union.
+ */
+struct GraphicBufferAttributes {
+    uint32_t width;
+    uint32_t height;
+    uint32_t stride;
+    PixelFormat format;
+    uint32_t usage; // TODO: convert to an enum
+    uint32_t generationNumber;
+};
+
+/**
+ * A GraphicBuffer is simply GraphicBufferAttributes plus a native handle.
+ */
+struct GraphicBuffer {
+    handle nativeHandle;
+    GraphicBufferAttributes attr;
+};
+
+/**
+ * Ref: frameworks/native/include/binder/IMemory.h
+ * Ref: frameworks/native/libs/binder/IMemory.cpp
+ */
+
+/**
+ * This struct contains attributes for a shared memory buffer that can be put
+ * into a union.
+ */
+struct SharedMemoryAttributes {
+    uint32_t size;
+    uint32_t flags; // TODO: convert to an enum
+    uint32_t offset;
+};
+
+/**
+ * A SharedMemory is simply SharedMemoryAttributes plus a native handle.
+ */
+struct SharedMemory {
+    handle nativeHandle;
+    SharedMemoryAttributes attr;
+};
+
diff --git a/media/Android.bp b/media/Android.bp
new file mode 100644
index 0000000..f2abc67
--- /dev/null
+++ b/media/Android.bp
@@ -0,0 +1,5 @@
+// This is an autogenerated file, do not edit.
+subdirs = [
+    "1.0",
+    "omx/1.0",
+]
diff --git a/media/omx/1.0/Android.bp b/media/omx/1.0/Android.bp
new file mode 100644
index 0000000..95d88a6
--- /dev/null
+++ b/media/omx/1.0/Android.bp
@@ -0,0 +1,87 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+genrule {
+    name: "android.hardware.media.omx@1.0_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces android.hardware.media.omx@1.0",
+    srcs: [
+        "types.hal",
+        "IGraphicBufferSource.hal",
+        "IOmx.hal",
+        "IOmxBufferSource.hal",
+        "IOmxNode.hal",
+        "IOmxObserver.hal",
+    ],
+    out: [
+        "android/hardware/media/omx/1.0/types.cpp",
+        "android/hardware/media/omx/1.0/GraphicBufferSourceAll.cpp",
+        "android/hardware/media/omx/1.0/OmxAll.cpp",
+        "android/hardware/media/omx/1.0/OmxBufferSourceAll.cpp",
+        "android/hardware/media/omx/1.0/OmxNodeAll.cpp",
+        "android/hardware/media/omx/1.0/OmxObserverAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.media.omx@1.0_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces android.hardware.media.omx@1.0",
+    srcs: [
+        "types.hal",
+        "IGraphicBufferSource.hal",
+        "IOmx.hal",
+        "IOmxBufferSource.hal",
+        "IOmxNode.hal",
+        "IOmxObserver.hal",
+    ],
+    out: [
+        "android/hardware/media/omx/1.0/types.h",
+        "android/hardware/media/omx/1.0/IGraphicBufferSource.h",
+        "android/hardware/media/omx/1.0/IHwGraphicBufferSource.h",
+        "android/hardware/media/omx/1.0/BnGraphicBufferSource.h",
+        "android/hardware/media/omx/1.0/BpGraphicBufferSource.h",
+        "android/hardware/media/omx/1.0/BsGraphicBufferSource.h",
+        "android/hardware/media/omx/1.0/IOmx.h",
+        "android/hardware/media/omx/1.0/IHwOmx.h",
+        "android/hardware/media/omx/1.0/BnOmx.h",
+        "android/hardware/media/omx/1.0/BpOmx.h",
+        "android/hardware/media/omx/1.0/BsOmx.h",
+        "android/hardware/media/omx/1.0/IOmxBufferSource.h",
+        "android/hardware/media/omx/1.0/IHwOmxBufferSource.h",
+        "android/hardware/media/omx/1.0/BnOmxBufferSource.h",
+        "android/hardware/media/omx/1.0/BpOmxBufferSource.h",
+        "android/hardware/media/omx/1.0/BsOmxBufferSource.h",
+        "android/hardware/media/omx/1.0/IOmxNode.h",
+        "android/hardware/media/omx/1.0/IHwOmxNode.h",
+        "android/hardware/media/omx/1.0/BnOmxNode.h",
+        "android/hardware/media/omx/1.0/BpOmxNode.h",
+        "android/hardware/media/omx/1.0/BsOmxNode.h",
+        "android/hardware/media/omx/1.0/IOmxObserver.h",
+        "android/hardware/media/omx/1.0/IHwOmxObserver.h",
+        "android/hardware/media/omx/1.0/BnOmxObserver.h",
+        "android/hardware/media/omx/1.0/BpOmxObserver.h",
+        "android/hardware/media/omx/1.0/BsOmxObserver.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.media.omx@1.0",
+    generated_sources: ["android.hardware.media.omx@1.0_genc++"],
+    generated_headers: ["android.hardware.media.omx@1.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.media.omx@1.0_genc++_headers"],
+    shared_libs: [
+        "libhidl",
+        "libhwbinder",
+        "libutils",
+        "libcutils",
+        "android.hardware.graphics.common@1.0",
+        "android.hardware.media@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidl",
+        "libhwbinder",
+        "libutils",
+        "android.hardware.graphics.common@1.0",
+        "android.hardware.media@1.0",
+    ],
+}
diff --git a/media/omx/1.0/IGraphicBufferSource.hal b/media/omx/1.0/IGraphicBufferSource.hal
new file mode 100644
index 0000000..bee57ac
--- /dev/null
+++ b/media/omx/1.0/IGraphicBufferSource.hal
@@ -0,0 +1,60 @@
+/*
+ * 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.media.omx@1.0;
+
+import android.hardware.graphics.common@1.0::Dataspace;
+
+import android.hardware.media@1.0::types;
+
+import IOmxNode;
+
+/**
+ * Ref: frameworks/av/media/libmedia/aidl/android/IGraphicBufferSource.aidl
+ *
+ * TODO: Add documentations.
+ */
+interface IGraphicBufferSource {
+
+    configure(IOmxNode omxNode, Dataspace dataspace)
+        generates (Status status);
+
+    setSuspend(bool suspend)
+        generates (Status status);
+
+    setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs)
+        generates (Status status);
+
+    setMaxFps(float maxFps)
+        generates (Status status);
+
+    setTimeLapseConfig(int64_t timePerFrameUs, int64_t timePerCaptureUs)
+        generates (Status status);
+
+    setStartTimeUs(int64_t startTimeUs)
+        generates (Status status);
+
+    setColorAspects(uint32_t aspects) // TODO: Maybe break down aspects.
+        generates (Status status);
+
+    setTimeOffsetUs(int64_t timeOffsetUs)
+        generates (Status status);
+
+    signalEndOfInputStream()
+        generates (Status status);
+
+};
+
diff --git a/media/omx/1.0/IOmx.hal b/media/omx/1.0/IOmx.hal
new file mode 100644
index 0000000..e9f0b76
--- /dev/null
+++ b/media/omx/1.0/IOmx.hal
@@ -0,0 +1,69 @@
+/*
+ * 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.media.omx@1.0;
+
+import android.hardware.media@1.0::types;
+
+import IOmxNode;
+import IOmxObserver;
+
+/**
+ * Ref: frameworks/av/include/media/IOMX.h: IOMX
+ *
+ * IOmx is the main entry point for communicating with OMX components.
+ */
+interface IOmx {
+
+    /**
+     * Information for an IOmxNode component.
+     */
+    struct ComponentInfo {
+        string mName;       //< Name of the component.
+        vec<string> mRoles; //< Roles of the component.
+    };
+
+    /**
+     * List available components.
+     *
+     * @param[out] status will be the status of the call.
+     * @param[out] nodeList will be a list of ComponentInfo.
+     */
+    listNodes(
+        ) generates (
+            Status status,
+            vec<ComponentInfo> nodeList
+        );
+
+    /**
+     * Allocate an IOmxNode instance with the specified component name.
+     *
+     * @param[in] name is the name of the component to create.
+     * @param[in] observer is an observer object that will receive messages from
+     * the created instance.
+     * @param[out] status will be the status of the call.
+     * @param[out] omxNode will be the allocated instance of IOmxNode.
+     */
+    allocateNode(
+            string name,
+            IOmxObserver observer
+        ) generates (
+            Status status,
+            IOmxNode omxNode
+        );
+
+};
+
diff --git a/media/omx/1.0/IOmxBufferSource.hal b/media/omx/1.0/IOmxBufferSource.hal
new file mode 100644
index 0000000..94c43fc
--- /dev/null
+++ b/media/omx/1.0/IOmxBufferSource.hal
@@ -0,0 +1,68 @@
+/*
+ * 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.media.omx@1.0;
+
+import android.hardware.media@1.0::types;
+
+/**
+ * Ref: frameworks/av/media/libmedia/aidl/android/IOMXBufferSource.aidl
+ *
+ * IOmxBufferSource is an interface for a listener for certain events from an
+ * IOmxNode instance. Use IOmxNode::setInputSurface() to attach an
+ * IOmxBufferSource instance to an IOmxNode instance.
+ *
+ * @see OMX_STATETYPE in the OpenMax IL standard.
+ */
+interface IOmxBufferSource {
+
+    /**
+     * onOmxExecuting() is invoked when the node state changes to
+     * OMX_StateExecuting state.
+     */
+    oneway onOmxExecuting();
+
+    /**
+     * onOmxIdle() is invoked when the node transitions from OMX_StateExecuting
+     * to OMX_StateIdle.
+     */
+    oneway onOmxIdle();
+
+    /**
+     * onOmxLoaded() is invoked when the node transitions from OMX_StateIdle or
+     * OMX_StateExecuting to OMX_StateLoaded.
+     */
+    oneway onOmxLoaded();
+
+    /**
+     * onInputBufferAdded() is invoked after a new input buffer is added to the
+     * node. This may happen within IOmxNode::allocateSecureBuffer() or
+     * IOmxNode::useBuffer().
+     *
+     * @param[in] buffer is the id of the added buffer.
+     */
+    oneway onInputBufferAdded(BufferId buffer);
+
+    /**
+     * onInputBufferEmptied() is invoked after an input buffer is emptied. This
+     * may happen within IOmxNode::emptyBuffer().
+     *
+     * @param[in] buffer is the id of the emptied buffer.
+     * @param[in] fence is the fence associated with the buffer.
+     */
+    oneway onInputBufferEmptied(BufferId buffer, Fence fence);
+};
+
diff --git a/media/omx/1.0/IOmxNode.hal b/media/omx/1.0/IOmxNode.hal
new file mode 100644
index 0000000..9483be4
--- /dev/null
+++ b/media/omx/1.0/IOmxNode.hal
@@ -0,0 +1,358 @@
+/*
+ * 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.media.omx@1.0;
+
+import IOmxBufferSource;
+
+import android.hardware.media@1.0::types;
+
+/**
+ * Ref: frameworks/av/include/media/IOMX.h: IOMXNode
+ * Ref: https://www.khronos.org/registry/omxil/specs/OpenMAX_IL_1_1_2_Specification.pdf
+ */
+
+/**
+ * IOmxNode is an interface for communicating with an OMX component (called
+ * "node" here) that has been previously obtained by calling
+ * IOmx::allocateNode().
+ */
+interface IOmxNode {
+
+    /**
+     * Free the node.
+     *
+     * @param[out] status will be the status of the call.
+     */
+    freeNode(
+        ) generates (
+            Status status
+        );
+
+    /**
+     * Invoke a command on the node.
+     *
+     * @param[in] cmd indicates the type of the command.
+     * @param[in] info holds information about 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
+        ) generates (
+            Status status
+        );
+
+    /**
+     * Retrieve a parameter setting from the node.
+     *
+     * @param[in] index indicates the type of the parameter to retrieve.
+     * @param[in] inParams holds some information about the retrieval.
+     * @param[out] status will be the status of the call.
+     * @param[out] outParams will be the current parameter setting.
+     *
+     * @see OMX_GetParameter() in the OpenMax IL standard.
+     */
+    getParameter(
+            uint32_t index,
+            Bytes inParams // TODO: describe structure better or point at standard
+        ) generates (
+            Status status,
+            Bytes outParams // TODO: describe structure better or point at standard
+        );
+
+    /**
+     * Change a parameter setting of the node.
+     *
+     * @param[in] index indicates the type of the parameter to change.
+     * @param[in] params holds the new parameter setting.
+     * @param[out] status will be the status of the call.
+     *
+     * @see OMX_SetParameter() in the OpenMax IL standard.
+     */
+    setParameter(
+            uint32_t index,
+            Bytes params // TODO: describe structure better or point at standard
+        ) generates (
+            Status status
+        );
+
+    /**
+     * Retrieve a configuration from the node.
+     *
+     * @param[in] index indicates the type of the configuration to retrieve.
+     * @param[in] inConfig holds some information about the retrieval.
+     * @param[out] status will be the status of the call.
+     * @param[out] outConfig will be the current configuration.
+     *
+     * @see OMX_GetConfig() in the OpenMax IL standard.
+     */
+    getConfig(
+            uint32_t index,
+            Bytes inConfig // TODO: describe structure better or point at standard
+        ) generates (
+            Status status,
+            Bytes outConfig // TODO: describe structure better or point at standard
+        );
+
+    /**
+     * Change a configuration of the node.
+     *
+     * @param[in] index indicates the type of the configuration to change.
+     * @param[in] config holds the new configuration.
+     * @param[out] status will be the status of the call.
+     *
+     * @see OMX_SetConfig() in the OpenMax IL standard.
+     */
+    setConfig(
+            uint32_t index,
+            Bytes config // TODO: describe structure better or point at standard
+        ) generates (
+            Status status
+        );
+
+    /**
+     * Set the mode of a port on the node.
+     *
+     * @param[in] portIndex is the index of the port.
+     * @param[in] mode is the target mode on the specified port.
+     */
+    setPortMode(
+            uint32_t portIndex,
+            PortMode mode
+        ) generates (
+            Status status
+        );
+
+    /**
+     * Prepare a port for adaptive playback. This is based on the extension
+     * "OMX.google.android.index.prepareForAdaptivePlayback".
+     *
+     * @param[in] portIndex is the index of the port.
+     * @param[in] enable indicates whether adaptive playback is enabled or not.
+     * @param[in] maxFrameWidth specifies the maximum frame width.
+     * @param[in] maxFrameHeight specifies the maximum frame height.
+     * @param[out] status status will be the status of the call.
+     */
+    prepareForAdaptivePlayback(
+            uint32_t portIndex,
+            bool enable,
+            uint32_t maxFrameWidth,
+            uint32_t maxFrameHeight
+        ) generates (
+            Status status
+        );
+
+    /**
+     * Configure a port for a tunneled playback mode. This is based on the
+     * extension "OMX.google.android.index.configureVideoTunnelMode".
+     *
+     * @param[in] portIndex is the index of the port.
+     * @param[in] tunneled indicates whether the tunneled mode is used or not.
+     * @param[in] audioHwSync is the HW SYNC ID of the audio HAL output stream
+     * to sync the video with.
+     * @param[out] status will be the status of the call.
+     * @param[out] sidebandHandle will contain the codec-allocated sideband
+     * window handle.
+     */
+    configureVideoTunnelMode(
+            uint32_t portIndex,
+            bool tunneled,
+            uint32_t audioHwSync
+        ) generates (
+            Status status,
+            handle sidebandHandle
+        );
+
+    /**
+     * Retrieve the buffer usage on a port. This is based on the extension
+     * "OMX.google.android.index.getAndroidNativeBufferUsage".
+     *
+     * @param[in] portIndex is the index of the port.
+     * @param[out] status will be the status of the call.
+     * @param[out] usage will be the usage.
+     */
+    getGraphicBufferUsage(
+            uint32_t portIndex
+        ) generates (
+            Status status,
+            uint32_t usage // TODO: Ask graphics team to define an enum.
+        );
+
+    /**
+     * Set up a listener to events related to the input surface.
+     *
+     * @param[in] bufferSource is the listener object that implements
+     * IOmxBufferSource.
+     * @param[out] status will be the status of the call.
+     *
+     * @see IOmxBufferSource.
+     */
+    setInputSurface(
+            IOmxBufferSource bufferSource
+        ) generates (
+            Status status
+        );
+
+    /**
+     * Allocate an opaque buffer on a port as a native handle.
+     *
+     * @param[in] portIndex is the index of the port.
+     * @param[in] size is the desired size of the buffer.
+     * @param[out] status will be the status of the call.
+     * @param[out] buffer will be the id of the allocated buffer, which will be
+     * needed in some other buffer-related function calls.
+     * @param[out] nativeHandle will be the native handle of the allocated
+     * buffer.
+     *
+     * @see OMX_AllocateBuffer() in the OpenMax IL standard.
+     */
+    allocateSecureBuffer(
+            uint32_t portIndex,
+            uint64_t size
+        ) generates (
+            Status status,
+            BufferId buffer,
+            handle nativeHandle
+        );
+
+    /**
+     * Assign a buffer to a port.
+     *
+     * @param[in] portIndex is the index of the port.
+     * @param[in] omxBuffer is the buffer to be assigned to the port.
+     * @param[out] status will be the status of the call.
+     * @param[out] buffer will be the id of the assigned buffer, which will be
+     * needed in some other buffer-related function calls.
+     *
+     * @see OMX_UseBuffer() in the OpenMax IL standard.
+     */
+    useBuffer(
+            uint32_t portIndex,
+            CodecBuffer omxBuffer
+        ) generates (
+            Status status,
+            BufferId buffer
+        );
+
+    /**
+     * Free a buffer previously assigned to a port by allocateSecureBuffer() or
+     * useBuffer().
+     *
+     * @param[in] portIndex is the index of the port.
+     * @param[in] buffer is the id of the buffer to be freed.
+     * @param[out] status will be the status of the call.
+     *
+     * @see OMX_FreeBuffer() in the OpenMax IL standard.
+     */
+    freeBuffer(
+            uint32_t portIndex,
+            BufferId buffer
+        ) generates (
+            Status status
+        );
+
+    /**
+     * Pass \p fence to the node if it supports fences. Otherwise, it waits on
+     * \p fence before calling OMX_FillThisBuffer(). The node will take
+     * ownership of the fence even if this call fails.
+     *
+     * If the port is in metadata mode, the buffer will be updated to point to
+     * the new buffer passed in via \p omxBuffer before OMX_FillThisBuffer() is
+     * called. Otherwise, \p omxBuffer is not used.
+     *
+     * @param[in] buffer is the id of the buffer to fill.
+     * @param[in] omxBuffer points to the new buffer in metadata mode.
+     * @param[in] fence is the fence to wait for (if not null).
+     * @param[out] status is the status of the call.
+     *
+     * @see OMX_FillThisBuffer() in the OpenMax IL standard.
+     */
+    fillBuffer(
+            BufferId buffer,
+            CodecBuffer omxBuffer,
+            Fence fence
+        ) generates (
+            Status status
+        );
+
+    /**
+     * Pass \p fence to the node if it supports fences. Otherwise, wait on
+     * \p fence before calling OMX_EmptyThisBuffer(). The node will take
+     * ownership of the fence even if this call fails.
+     *
+     * If the port is in metadata mode, the buffer will be updated to point to
+     * the new buffer passed in via \p omxBuffer before OMX_EmptyThisBuffer() is
+     * called. Otherwise, \p omxBuffer is not used.
+     *
+     * @param[in] buffer is the id of the buffer to fill.
+     * @param[in] omxBuffer points to the new buffer in metadata mode.
+     * @param[in] flags is put into the header information that is passed to
+     * OMX_EmptyBuffer().
+     * @param[in] timestampUs is put into the header information that is passed
+     * to OMX_EmptyBuffer().
+     * @param[in] fence is the fence to wait for (if not null).
+     * @param[out] status is the status of the call.
+     *
+     * @see OMX_EmptyThisBuffer() in the OpenMax IL standard.
+     */
+    emptyBuffer(
+            BufferId buffer,
+            CodecBuffer omxBuffer,
+            uint32_t flags, // TODO: describe structure better or point at standard
+            uint64_t timestampUs,
+            Fence fence
+        ) generates (
+            Status status
+        );
+
+    /**
+     * Request the node to translate an extension string to an index.
+     *
+     * @param[in] parameterName is the requested extension string.
+     * @param[out] status is the status of the call.
+     * @param[out] index is the translated index.
+     *
+     * @see OMX_GetExtensionIndex() in the OpenMax IL standard.
+     */
+    getExtensionIndex(
+            string parameterName
+        ) generates (
+            Status status,
+            uint32_t index
+        );
+
+    /**
+     * Add an OMX message on the node's message queue. The instance of
+     * IOmxObserver that was obtained during the creation of the node will
+     * receive the message in batches by the callback
+     * IOmxObserver::onMessages().
+     *
+     * @param[in] msg is the message to send.
+     * @param[out] status is the status of the call.
+     *
+     * @see IOmxObserver::onMessages().
+     */
+    dispatchMessage(
+            Message msg
+        ) generates (
+            Status status
+        );
+
+};
+
diff --git a/media/omx/1.0/IOmxObserver.hal b/media/omx/1.0/IOmxObserver.hal
new file mode 100644
index 0000000..c26a937
--- /dev/null
+++ b/media/omx/1.0/IOmxObserver.hal
@@ -0,0 +1,35 @@
+/*
+ * 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.media.omx@1.0;
+
+/**
+ * Ref: frameworks/av/include/media/IOMX.h: IOMXObserver
+ */
+
+/**
+ * IOmxObserver is a listener interface for OMX messages sent from an IOmxNode
+ * stance.
+ */
+interface IOmxObserver {
+
+    /**
+     * Invoked to process messages from an IOmxNode instance. Note that messages
+     * come in batches.
+     */
+    oneway onMessages(vec<Message> messages);
+};
+
diff --git a/media/omx/1.0/types.hal b/media/omx/1.0/types.hal
new file mode 100644
index 0000000..c0350de
--- /dev/null
+++ b/media/omx/1.0/types.hal
@@ -0,0 +1,178 @@
+/*
+ * 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.media.omx@1.0;
+
+import android.hardware.media@1.0::types;
+
+// Aliases
+typedef uint32_t BufferId;
+
+/**
+ * Ref: frameworks/av/include/media/IOMX.h: omx_message
+ *
+ * Data structure for an OMX message. This is essentially a union of different
+ * message types.
+ */
+struct Message {
+
+    /**
+     * There are four main types of messages.
+     */
+    enum Type : uint32_t {
+        EVENT,
+        EMPTY_BUFFER_DONE,
+        FILL_BUFFER_DONE,
+        FRAME_RENDERED,
+    };
+
+    /**
+     * @see OMX_EVENTTYPE in the OpenMax IL standard.
+     */
+    struct EventData {
+        uint32_t event; // TODO: if there are common core events, convert to an enum or point to std
+        uint32_t data1;
+        uint32_t data2;
+        uint32_t data3;
+        uint32_t data4;
+    };
+
+    struct BufferData {
+        BufferId buffer;
+    };
+
+    struct ExtendedBufferData {
+        BufferId buffer;
+        uint32_t rangeOffset;
+        uint32_t rangeLength;
+        uint32_t flags; // TODO: if common flags exist, define an enum of point to std
+        uint64_t timestampUs;
+    };
+
+    struct RenderData {
+        uint64_t timestampUs;
+        int64_t systemTimeNs;
+    };
+
+    union Data {
+        // if type == EVENT
+        EventData eventData;
+
+        // if type == EMPTY_BUFFER_DONE
+        BufferData bufferData;
+
+        // if type == FILL_BUFFER_DONE
+        ExtendedBufferData extendedBufferData;
+
+        // if type == FRAME_RENDERED
+        RenderData renderData;
+    };
+
+    /**
+     * The type of the message.
+     */
+    Type type;
+
+    /**
+     * The fence associated with the message.
+     */
+    Fence fence;
+
+    /**
+     * The union of data, discriminated by type.
+     */
+    Data data;
+};
+
+/**
+ * Ref: frameworks/native/include/ui/GraphicBuffer.h
+ * Ref: system/core/include/system/window.h
+ * Ref: frameworks/native/include/binder/IMemory.h
+ * Ref: frameworks/native/libs/binder/IMemory.cpp
+ * Ref: frameworks/av/include/media/OMXBuffer.h
+ *
+ * Data structure for buffer information. This is essentially a union of
+ * different buffer types.
+ */
+struct CodecBuffer {
+
+    /**
+     * There are four main types of buffers.
+     */
+    enum Type {
+        INVALID = 0,
+        PRESET,
+        SHARED_MEM,
+        ANW_BUFFER,
+        NATIVE_HANDLE
+    };
+
+    struct PresetAttributes {
+        uint32_t rangeLength;
+    };
+
+    union Attributes {
+        // if bufferType == PRESET
+        PresetAttributes preset;
+
+        // if bufferType == SHARED_MEM
+        SharedMemoryAttributes sharedMem;
+
+        // if bufferType == ANW_BUFFER
+        GraphicBufferAttributes anwBuffer;
+
+        // if bufferType == NATIVE_HANDLE
+        // No additional attributes.
+    };
+
+    /**
+     * Type of the buffer.
+     */
+    Type type;
+
+    /**
+     * Attributes that can be put into a union.
+     */
+    Attributes attr;
+
+    /**
+     * \p nativeHandle is used only for types SHARED_MEM, ANW_BUFFER and
+     * NATIVE_HANDLE.
+     *
+     * (A native handle cannot be put into a union as HIDL currently does not
+     * support discriminated unions.)
+     */
+    handle nativeHandle;
+
+};
+
+/**
+ * Ref: frameworks/av/include/media/IOMX.h
+ *
+ * Enumeration of port modes.
+ */
+enum PortMode {
+    PRESET_START = 0,
+    PRESET_BYTE_BUFFER,
+    PRESET_ANW_BUFFER,
+    PRESET_SECURE_BUFFER,
+    PRESET_END,
+    DYNAMIC_START = 100,
+    DYNAMIC_ANW_BUFFER,
+    DYNAMIC_NATIVE_HANDLE,
+    DYNAMIC_END
+};
+
diff --git a/thermal/1.0/IThermal.hal b/thermal/1.0/IThermal.hal
index a60bc7d..e5f70cb 100644
--- a/thermal/1.0/IThermal.hal
+++ b/thermal/1.0/IThermal.hal
@@ -32,6 +32,9 @@
      *         always returns and never removes such temperatures.
      *
      */
+    @callflow(next={"*"})
+    @entry
+    @exit
     getTemperatures()
         generates (ThermalStatus status, vec<Temperature> temperatures);
 
@@ -47,6 +50,9 @@
      *         the same regardless the number of calls to this method.
      *
      */
+    @callflow(next={"*"})
+    @entry
+    @exit
     getCpuUsages() generates (ThermalStatus status, vec<CpuUsage> cpuUsages);
 
     /*
@@ -63,6 +69,9 @@
      *         the list such cooling devices.
      *
      */
+    @callflow(next={"*"})
+    @entry
+    @exit
     getCoolingDevices()
         generates (ThermalStatus status, vec<CoolingDevice> devices);
 
diff --git a/thermal/1.0/default/Thermal.cpp b/thermal/1.0/default/Thermal.cpp
index 1b91687..6c2111f 100644
--- a/thermal/1.0/default/Thermal.cpp
+++ b/thermal/1.0/default/Thermal.cpp
@@ -20,6 +20,7 @@
 #include <errno.h>
 #include <hardware/hardware.h>
 #include <hardware/thermal.h>
+#include <vector>
 
 #include "Thermal.h"
 
@@ -29,173 +30,167 @@
 namespace V1_0 {
 namespace implementation {
 
-Thermal::Thermal(thermal_module_t* module) : mModule(module) {
-}
+Thermal::Thermal(thermal_module_t* module) : mModule(module) {}
 
 // Methods from ::android::hardware::thermal::V1_0::IThermal follow.
-Return<void> Thermal::getTemperatures(getTemperatures_cb _hidl_cb)  {
-    ThermalStatus status;
-    status.code = ThermalStatusCode::SUCCESS;
-    hidl_vec<Temperature> temperatures;
+Return<void> Thermal::getTemperatures(getTemperatures_cb _hidl_cb) {
+  ThermalStatus status;
+  status.code = ThermalStatusCode::SUCCESS;
+  hidl_vec<Temperature> temperatures;
 
-    if (!mModule || !mModule->getTemperatures) {
-        ALOGI("getTemperatures is not implemented in Thermal HAL.");
-        _hidl_cb(status, temperatures);
-        return Void();
-    }
-
-    ssize_t list_size = mModule->getTemperatures(mModule, nullptr, 0);
-    if (list_size >= 0) {
-       temperature_t *list = new temperature_t[list_size];
-       ssize_t size = mModule->getTemperatures(mModule, list, list_size);
-       if (size >= 0) {
-           if (list_size > size) {
-               list_size = size;
-           }
-
-           temperatures.resize(list_size);
-           for (ssize_t i = 0; i < list_size; ++i) {
-               switch (list[i].type) {
-                   case DEVICE_TEMPERATURE_UNKNOWN:
-                       temperatures[i].type = TemperatureType::UNKNOWN;
-                       break;
-                   case DEVICE_TEMPERATURE_CPU:
-                       temperatures[i].type = TemperatureType::CPU;
-                       break;
-                   case DEVICE_TEMPERATURE_GPU:
-                       temperatures[i].type = TemperatureType::GPU;
-                       break;
-                   case DEVICE_TEMPERATURE_BATTERY:
-                       temperatures[i].type = TemperatureType::BATTERY;
-                       break;
-                   case DEVICE_TEMPERATURE_SKIN:
-                       temperatures[i].type = TemperatureType::SKIN;
-                       break;
-                   default:
-                       ALOGE("Unknown temperature %s type", list[i].name);;
-               }
-               temperatures[i].name = list[i].name;
-               temperatures[i].currentValue = list[i].current_value;
-               temperatures[i].throttlingThreshold = list[i].throttling_threshold;
-               temperatures[i].shutdownThreshold = list[i].shutdown_threshold;
-               temperatures[i].vrThrottlingThreshold = list[i].vr_throttling_threshold;
-           }
-       } else {
-           status.code = ThermalStatusCode::FAILURE;
-           status.debugMessage = strerror(-size);
-       }
-       delete[] list;
-    } else {
-        status.code = ThermalStatusCode::FAILURE;
-        status.debugMessage = strerror(-list_size);
-    }
+  if (!mModule || !mModule->getTemperatures) {
+    ALOGI("getTemperatures is not implemented in Thermal HAL.");
     _hidl_cb(status, temperatures);
     return Void();
+  }
+
+  ssize_t size = mModule->getTemperatures(mModule, nullptr, 0);
+  if (size >= 0) {
+    std::vector<temperature_t> list;
+    list.resize(size);
+    size = mModule->getTemperatures(mModule, list.data(), list.size());
+    if (size >= 0) {
+      temperatures.resize(list.size());
+      for (size_t i = 0; i < list.size(); ++i) {
+        switch (list[i].type) {
+          case DEVICE_TEMPERATURE_UNKNOWN:
+            temperatures[i].type = TemperatureType::UNKNOWN;
+            break;
+          case DEVICE_TEMPERATURE_CPU:
+            temperatures[i].type = TemperatureType::CPU;
+            break;
+          case DEVICE_TEMPERATURE_GPU:
+            temperatures[i].type = TemperatureType::GPU;
+            break;
+          case DEVICE_TEMPERATURE_BATTERY:
+            temperatures[i].type = TemperatureType::BATTERY;
+            break;
+          case DEVICE_TEMPERATURE_SKIN:
+            temperatures[i].type = TemperatureType::SKIN;
+            break;
+          default:
+            ALOGE("Unknown temperature %s type", list[i].name);
+            ;
+        }
+        temperatures[i].name = list[i].name;
+        temperatures[i].currentValue = list[i].current_value;
+        temperatures[i].throttlingThreshold = list[i].throttling_threshold;
+        temperatures[i].shutdownThreshold = list[i].shutdown_threshold;
+        temperatures[i].vrThrottlingThreshold = list[i].vr_throttling_threshold;
+      }
+    }
+  }
+  if (size < 0) {
+    status.code = ThermalStatusCode::FAILURE;
+    status.debugMessage = strerror(-size);
+  }
+  _hidl_cb(status, temperatures);
+  return Void();
 }
 
-Return<void> Thermal::getCpuUsages(getCpuUsages_cb _hidl_cb)  {
-    ThermalStatus status;
-    hidl_vec<CpuUsage> cpuUsages;
-    status.code = ThermalStatusCode::SUCCESS;
+Return<void> Thermal::getCpuUsages(getCpuUsages_cb _hidl_cb) {
+  ThermalStatus status;
+  hidl_vec<CpuUsage> cpuUsages;
+  status.code = ThermalStatusCode::SUCCESS;
 
-    if (!mModule || !mModule->getCpuUsages) {
-        ALOGI("getCpuUsages is not implemented in Thermal HAL");
-        _hidl_cb(status, cpuUsages);
-        return Void();
-    }
-
-    ssize_t size = mModule->getCpuUsages(mModule, nullptr);
-    if (size >= 0) {
-        cpu_usage_t *list = new cpu_usage_t[size];
-        size = mModule->getCpuUsages(mModule, list);
-        if (size >= 0) {
-            cpuUsages.resize(size);
-            for (ssize_t i = 0; i < size; ++i) {
-                cpuUsages[i].name = list[i].name;
-                cpuUsages[i].active = list[i].active;
-                cpuUsages[i].total = list[i].total;
-                cpuUsages[i].isOnline = list[i].is_online;
-            }
-        } else {
-            status.code = ThermalStatusCode::FAILURE;
-            status.debugMessage = strerror(-size);
-        }
-        delete[] list;
-    } else {
-        status.code = ThermalStatusCode::FAILURE;
-        status.debugMessage = strerror(-size);
-    }
+  if (!mModule || !mModule->getCpuUsages) {
+    ALOGI("getCpuUsages is not implemented in Thermal HAL");
     _hidl_cb(status, cpuUsages);
     return Void();
+  }
+
+  ssize_t size = mModule->getCpuUsages(mModule, nullptr);
+  if (size >= 0) {
+    std::vector<cpu_usage_t> list;
+    list.resize(size);
+    size = mModule->getCpuUsages(mModule, list.data());
+    if (size >= 0) {
+      list.resize(size);
+      cpuUsages.resize(size);
+      for (size_t i = 0; i < list.size(); ++i) {
+        cpuUsages[i].name = list[i].name;
+        cpuUsages[i].active = list[i].active;
+        cpuUsages[i].total = list[i].total;
+        cpuUsages[i].isOnline = list[i].is_online;
+      }
+    } else {
+      status.code = ThermalStatusCode::FAILURE;
+      status.debugMessage = strerror(-size);
+    }
+  }
+  if (size < 0) {
+    status.code = ThermalStatusCode::FAILURE;
+    status.debugMessage = strerror(-size);
+  }
+  _hidl_cb(status, cpuUsages);
+  return Void();
 }
 
-Return<void> Thermal::getCoolingDevices(getCoolingDevices_cb _hidl_cb)  {
-    ThermalStatus status;
-    status.code = ThermalStatusCode::SUCCESS;
-    hidl_vec<CoolingDevice> coolingDevices;
+Return<void> Thermal::getCoolingDevices(getCoolingDevices_cb _hidl_cb) {
+  ThermalStatus status;
+  status.code = ThermalStatusCode::SUCCESS;
+  hidl_vec<CoolingDevice> coolingDevices;
 
-    if (!mModule || !mModule->getCoolingDevices) {
-        ALOGI("getCoolingDevices is not implemented in Thermal HAL.");
-        _hidl_cb(status, coolingDevices);
-        return Void();
-    }
-
-    ssize_t list_size = mModule->getCoolingDevices(mModule, nullptr, 0);
-    if (list_size >= 0) {
-        cooling_device_t *list = new cooling_device_t[list_size];
-        ssize_t size = mModule->getCoolingDevices(mModule, list, list_size);
-        if (size >= 0) {
-            if (list_size > size) {
-                list_size = size;
-            }
-            coolingDevices.resize(list_size);
-            for (ssize_t i = 0; i < list_size; ++i) {
-                switch (list[i].type) {
-                    case FAN_RPM:
-                        coolingDevices[i].type = CoolingType::FAN_RPM;
-                        break;
-                    default:
-                        ALOGE("Unknown cooling device %s type", list[i].name);
-                }
-                coolingDevices[i].name = list[i].name;
-                coolingDevices[i].currentValue = list[i].current_value;
-            }
-
-        } else {
-            status.code = ThermalStatusCode::FAILURE;
-            status.debugMessage = strerror(-size);
-        }
-        delete[] list;
-    } else {
-        status.code = ThermalStatusCode::FAILURE;
-        status.debugMessage = strerror(-list_size);
-    }
+  if (!mModule || !mModule->getCoolingDevices) {
+    ALOGI("getCoolingDevices is not implemented in Thermal HAL.");
     _hidl_cb(status, coolingDevices);
     return Void();
+  }
+
+  ssize_t size = mModule->getCoolingDevices(mModule, nullptr, 0);
+  if (size >= 0) {
+    std::vector<cooling_device_t> list;
+    list.resize(size);
+    size = mModule->getCoolingDevices(mModule, list.data(), list.size());
+    if (size >= 0) {
+      list.resize(size);
+      coolingDevices.resize(list.size());
+      for (size_t i = 0; i < list.size(); ++i) {
+        switch (list[i].type) {
+          case FAN_RPM:
+            coolingDevices[i].type = CoolingType::FAN_RPM;
+            break;
+          default:
+            ALOGE("Unknown cooling device %s type", list[i].name);
+        }
+        coolingDevices[i].name = list[i].name;
+        coolingDevices[i].currentValue = list[i].current_value;
+      }
+    }
+  }
+  if (size < 0) {
+    status.code = ThermalStatusCode::FAILURE;
+    status.debugMessage = strerror(-size);
+  }
+  _hidl_cb(status, coolingDevices);
+  return Void();
 }
 
 IThermal* HIDL_FETCH_IThermal(const char* /* name */) {
-    thermal_module_t* module;
-    status_t err = hw_get_module(THERMAL_HARDWARE_MODULE_ID,
-            const_cast<hw_module_t const**>(reinterpret_cast<hw_module_t**>(&module)));
-    if (err || !module) {
-        ALOGE("Couldn't load %s module (%s)", THERMAL_HARDWARE_MODULE_ID,
-              strerror(-err));
-    }
+  thermal_module_t* module;
+  status_t err = hw_get_module(THERMAL_HARDWARE_MODULE_ID,
+                               const_cast<hw_module_t const**>(
+                                   reinterpret_cast<hw_module_t**>(&module)));
+  if (err || !module) {
+    ALOGE("Couldn't load %s module (%s)", THERMAL_HARDWARE_MODULE_ID,
+          strerror(-err));
+  }
 
-    if (err == 0 && module->common.methods->open) {
-        struct hw_device_t* device;
-        err = module->common.methods->open(&module->common, THERMAL_HARDWARE_MODULE_ID, &device);
-        if (err) {
-            ALOGE("Couldn't open %s module (%s)", THERMAL_HARDWARE_MODULE_ID, strerror(-err));
-        } else {
-            return new Thermal(reinterpret_cast<thermal_module_t*>(device));
-        }
+  if (err == 0 && module->common.methods->open) {
+    struct hw_device_t* device;
+    err = module->common.methods->open(&module->common,
+                                       THERMAL_HARDWARE_MODULE_ID, &device);
+    if (err) {
+      ALOGE("Couldn't open %s module (%s)", THERMAL_HARDWARE_MODULE_ID,
+            strerror(-err));
+    } else {
+      return new Thermal(reinterpret_cast<thermal_module_t*>(device));
     }
-    return new Thermal(module);
+  }
+  return new Thermal(module);
 }
 
-} // namespace implementation
+}  // namespace implementation
 }  // namespace V1_0
 }  // namespace thermal
 }  // namespace hardware
diff --git a/thermal/1.0/types.hal b/thermal/1.0/types.hal
index 26a0f6f..8864f43 100644
--- a/thermal/1.0/types.hal
+++ b/thermal/1.0/types.hal
@@ -26,7 +26,7 @@
     SKIN = 3,
 };
 
-enum CoolingType : int32_t {
+enum CoolingType : uint32_t {
     /** Fan cooling device speed in RPM. */
     FAN_RPM = 0,
 };
@@ -118,9 +118,9 @@
 
 enum ThermalStatusCode : uint32_t {
     /** No errors. */
-    SUCCESS,
+    SUCCESS = 0,
     /** Unknown failure occured. */
-    FAILURE
+    FAILURE = 1
 };
 
 /**
diff --git a/thermal/1.0/vts/Android.mk b/thermal/1.0/vts/Android.mk
new file mode 100644
index 0000000..f1ac716
--- /dev/null
+++ b/thermal/1.0/vts/Android.mk
@@ -0,0 +1,84 @@
+#
+# 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)
+
+# build VTS driver for Thermal v1.0.
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libvts_driver_hidl_thermal@1.0
+
+LOCAL_SRC_FILES := \
+  Thermal.vts \
+  types.vts \
+
+LOCAL_C_INCLUDES := \
+  android.hardware.thermal@1.0 \
+  system/core/base/include \
+  system/core/include \
+
+LOCAL_SHARED_LIBRARIES += \
+  android.hardware.thermal@1.0 \
+  libbase \
+  libutils \
+  libcutils \
+  liblog \
+  libhidl \
+  libhwbinder \
+  libprotobuf-cpp-full \
+  libvts_common \
+  libvts_datatype \
+  libvts_measurement \
+  libvts_multidevice_proto \
+
+LOCAL_STATIC_LIBRARIES := \
+
+LOCAL_PROTOC_OPTIMIZE_TYPE := full
+
+LOCAL_MULTILIB := both
+
+include $(BUILD_SHARED_LIBRARY)
+
+# build profiler for thermal.
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libvts_profiler_hidl_thermal@1.0
+
+LOCAL_SRC_FILES := \
+   Thermal.vts \
+   types.vts \
+
+LOCAL_C_INCLUDES += \
+  test/vts/drivers/libprofiling \
+
+LOCAL_VTS_MODE := PROFILER
+
+LOCAL_SHARED_LIBRARIES := \
+   android.hardware.thermal@1.0 \
+   libbase \
+   libcutils \
+   liblog \
+   libhidl \
+   libhwbinder \
+   libprotobuf-cpp-full \
+   libvts_common \
+   libvts_multidevice_proto \
+   libvts_profiling \
+   libutils \
+
+LOCAL_PROTOC_OPTIMIZE_TYPE := full
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/thermal/1.0/vts/Thermal.vts b/thermal/1.0/vts/Thermal.vts
new file mode 100644
index 0000000..e76d943
--- /dev/null
+++ b/thermal/1.0/vts/Thermal.vts
@@ -0,0 +1,82 @@
+component_class: HAL_HIDL
+component_type_version: 1.0
+component_name: "IThermal"
+
+package: "android.hardware.thermal"
+
+import: "android.hardware.thermal@1.0::types"
+
+interface: {
+    api: {
+        name: "getTemperatures"
+        return_type_hidl: {
+            type: TYPE_STRUCT
+            predefined_type: "::android::hardware::thermal::V1_0::ThermalStatus"
+        }
+        return_type_hidl: {
+            type: TYPE_VECTOR
+            vector_value: {
+                type: TYPE_STRUCT
+                predefined_type: "::android::hardware::thermal::V1_0::Temperature"
+            }
+        }
+        callflow: {
+            next: "*"
+        }
+        callflow: {
+            entry: true
+        }
+        callflow: {
+            exit: true
+        }
+    }
+
+    api: {
+        name: "getCpuUsages"
+        return_type_hidl: {
+            type: TYPE_STRUCT
+            predefined_type: "::android::hardware::thermal::V1_0::ThermalStatus"
+        }
+        return_type_hidl: {
+            type: TYPE_VECTOR
+            vector_value: {
+                type: TYPE_STRUCT
+                predefined_type: "::android::hardware::thermal::V1_0::CpuUsage"
+            }
+        }
+        callflow: {
+            next: "*"
+        }
+        callflow: {
+            entry: true
+        }
+        callflow: {
+            exit: true
+        }
+    }
+
+    api: {
+        name: "getCoolingDevices"
+        return_type_hidl: {
+            type: TYPE_STRUCT
+            predefined_type: "::android::hardware::thermal::V1_0::ThermalStatus"
+        }
+        return_type_hidl: {
+            type: TYPE_VECTOR
+            vector_value: {
+                type: TYPE_STRUCT
+                predefined_type: "::android::hardware::thermal::V1_0::CoolingDevice"
+            }
+        }
+        callflow: {
+            next: "*"
+        }
+        callflow: {
+            entry: true
+        }
+        callflow: {
+            exit: true
+        }
+    }
+
+}
diff --git a/thermal/1.0/vts/functional/Android.bp b/thermal/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..7e0d1d0
--- /dev/null
+++ b/thermal/1.0/vts/functional/Android.bp
@@ -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.
+//
+
+cc_test {
+    name: "thermal_hidl_hal_test",
+    gtest: true,
+    srcs: ["thermal_hidl_hal_test.cpp"],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcutils",
+        "libhidl",
+        "libhwbinder",
+        "libnativehelper",
+        "libutils",
+        "android.hardware.thermal@1.0",
+    ],
+    static_libs: ["libgtest"],
+    cflags: [
+        "-O0",
+        "-g",
+    ],
+}
+
diff --git a/thermal/1.0/vts/functional/thermal_hidl_hal_test.cpp b/thermal/1.0/vts/functional/thermal_hidl_hal_test.cpp
new file mode 100644
index 0000000..e3b00ab
--- /dev/null
+++ b/thermal/1.0/vts/functional/thermal_hidl_hal_test.cpp
@@ -0,0 +1,219 @@
+/*
+ * 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 <algorithm>
+#include <cmath>
+#include <string>
+#include <vector>
+
+#define LOG_TAG "thermal_hidl_hal_test"
+
+#include <android-base/logging.h>
+#include <android/hardware/thermal/1.0/IThermal.h>
+#include <android/hardware/thermal/1.0/types.h>
+#include <gtest/gtest.h>
+#include <unistd.h>
+
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::thermal::V1_0::CoolingDevice;
+using ::android::hardware::thermal::V1_0::CpuUsage;
+using ::android::hardware::thermal::V1_0::IThermal;
+using ::android::hardware::thermal::V1_0::Temperature;
+using ::android::hardware::thermal::V1_0::TemperatureType;
+using ::android::hardware::thermal::V1_0::ThermalStatus;
+using ::android::hardware::thermal::V1_0::ThermalStatusCode;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+#define THERMAL_SERVICE_NAME "thermal"
+#define MONITORING_OPERATION_NUMBER 10
+
+#define UNDEFINED_TEMPERATURE (-FLT_MAX)
+
+#define MAX_DEVICE_TEMPERATURE 200
+#define MAX_FAN_SPEED 20000
+
+// The main test class for THERMAL HIDL HAL.
+class ThermalHidlTest : public ::testing::Test {
+ public:
+  virtual void SetUp() override {
+    thermal_ = IThermal::getService(THERMAL_SERVICE_NAME, false);
+    ASSERT_NE(thermal_, nullptr);
+    baseSize_ = 0;
+    names_.clear();
+  }
+
+  virtual void TearDown() override {}
+
+ protected:
+  // Check validity of temperatures returned by Thremal HAL.
+  void checkTemperatures(const hidl_vec<Temperature> temperatures) {
+    size_t size = temperatures.size();
+    EXPECT_LE(baseSize_, size);
+
+    for (size_t i = 0; i < size; ++i) {
+      checkDeviceTemperature(temperatures[i]);
+      if (i < baseSize_) {
+        EXPECT_EQ(names_[i], temperatures[i].name.c_str());
+      } else {
+        // Names must be unique.
+        EXPECT_EQ(names_.end(), std::find(names_.begin(), names_.end(),
+                                          temperatures[i].name.c_str()));
+        names_.push_back(temperatures[i].name);
+      }
+    }
+    baseSize_ = size;
+  }
+
+  // Check validity of CPU usages returned by Thermal HAL.
+  void checkCpuUsages(const hidl_vec<CpuUsage>& cpuUsages) {
+    size_t size = cpuUsages.size();
+    // A number of CPU's does not change.
+    if (baseSize_ != 0) EXPECT_EQ(baseSize_, size);
+
+    for (size_t i = 0; i < size; ++i) {
+      checkCpuUsage(cpuUsages[i]);
+      if (i < baseSize_) {
+        EXPECT_EQ(names_[i], cpuUsages[i].name.c_str());
+      } else {
+        // Names must be unique.
+        EXPECT_EQ(names_.end(), std::find(names_.begin(), names_.end(),
+                                          cpuUsages[i].name.c_str()));
+        names_.push_back(cpuUsages[i].name);
+      }
+    }
+    baseSize_ = size;
+  }
+
+  // Check validity of cooling devices information returned by Thermal HAL.
+  void checkCoolingDevices(const hidl_vec<CoolingDevice> coolingDevices) {
+    size_t size = coolingDevices.size();
+    EXPECT_LE(baseSize_, size);
+
+    for (size_t i = 0; i < size; ++i) {
+      checkCoolingDevice(coolingDevices[i]);
+      if (i < baseSize_) {
+        EXPECT_EQ(names_[i], coolingDevices[i].name.c_str());
+      } else {
+        // Names must be unique.
+        EXPECT_EQ(names_.end(), std::find(names_.begin(), names_.end(),
+                                          coolingDevices[i].name.c_str()));
+        names_.push_back(coolingDevices[i].name);
+      }
+    }
+    baseSize_ = size;
+  }
+
+  sp<IThermal> thermal_;
+
+ private:
+  // Check validity of temperature returned by Thermal HAL.
+  void checkDeviceTemperature(const Temperature& temperature) {
+    // .currentValue of known type is in Celsius and must be reasonable.
+    EXPECT_TRUE(temperature.type == TemperatureType::UNKNOWN ||
+                std::abs(temperature.currentValue) < MAX_DEVICE_TEMPERATURE ||
+                temperature.currentValue == UNDEFINED_TEMPERATURE);
+
+    // .name must not be empty.
+    EXPECT_LT(0u, temperature.name.size());
+
+    // .currentValue must not exceed .shutdwonThreshold if defined.
+    EXPECT_TRUE(temperature.currentValue < temperature.shutdownThreshold ||
+                temperature.currentValue == UNDEFINED_TEMPERATURE ||
+                temperature.shutdownThreshold == UNDEFINED_TEMPERATURE);
+
+    // .throttlingThreshold must not exceed .shutdownThreshold if defined.
+    EXPECT_TRUE(temperature.throttlingThreshold <
+                    temperature.shutdownThreshold ||
+                temperature.throttlingThreshold == UNDEFINED_TEMPERATURE ||
+                temperature.shutdownThreshold == UNDEFINED_TEMPERATURE);
+  }
+
+  // Check validity of CPU usage returned by Thermal HAL.
+  void checkCpuUsage(const CpuUsage& cpuUsage) {
+    // .active must be less than .total if CPU is online.
+    EXPECT_TRUE(!cpuUsage.isOnline ||
+                (cpuUsage.active >= 0 && cpuUsage.total >= 0 &&
+                 cpuUsage.total >= cpuUsage.active));
+
+    // .name must be not empty.
+    EXPECT_LT(0u, cpuUsage.name.size());
+  }
+
+  // Check validity of a cooling device information returned by Thermal HAL.
+  void checkCoolingDevice(const CoolingDevice& coolingDevice) {
+    EXPECT_LE(0, coolingDevice.currentValue);
+    EXPECT_GT(MAX_FAN_SPEED, coolingDevice.currentValue);
+    EXPECT_LT(0u, coolingDevice.name.size());
+  }
+
+  size_t baseSize_;
+  std::vector<hidl_string> names_;
+};
+
+// Sanity test for Thermal::getTemperatures().
+TEST_F(ThermalHidlTest, TemperatureTest) {
+  hidl_vec<Temperature> passed;
+  for (size_t i = 0; i < MONITORING_OPERATION_NUMBER; ++i) {
+    thermal_->getTemperatures(
+        [&passed](ThermalStatus status, hidl_vec<Temperature> temperatures) {
+          EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code);
+          passed = temperatures;
+        });
+
+    checkTemperatures(passed);
+    sleep(1);
+  }
+}
+
+// Sanity test for Thermal::getCpuUsages().
+TEST_F(ThermalHidlTest, CpuUsageTest) {
+  hidl_vec<CpuUsage> passed;
+  for (size_t i = 0; i < MONITORING_OPERATION_NUMBER; ++i) {
+    thermal_->getCpuUsages(
+        [&passed](ThermalStatus status, hidl_vec<CpuUsage> cpuUsages) {
+          EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code);
+          passed = cpuUsages;
+        });
+
+    checkCpuUsages(passed);
+    sleep(1);
+  }
+}
+
+// Sanity test for Thermal::getCoolingDevices().
+TEST_F(ThermalHidlTest, CoolingDeviceTest) {
+  hidl_vec<CoolingDevice> passed;
+  for (size_t i = 0; i < MONITORING_OPERATION_NUMBER; ++i) {
+    thermal_->getCoolingDevices([&passed](
+        ThermalStatus status, hidl_vec<CoolingDevice> coolingDevices) {
+      EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code);
+      passed = coolingDevices;
+    });
+
+    checkCoolingDevices(passed);
+    sleep(1);
+  }
+}
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  int status = RUN_ALL_TESTS();
+  ALOGI("Test result = %d", status);
+  return status;
+}
diff --git a/thermal/1.0/vts/types.vts b/thermal/1.0/vts/types.vts
new file mode 100644
index 0000000..1e60f48
--- /dev/null
+++ b/thermal/1.0/vts/types.vts
@@ -0,0 +1,157 @@
+component_class: HAL_HIDL
+component_type_version: 1.0
+component_name: "types"
+
+package: "android.hardware.thermal"
+
+
+attribute: {
+    name: "::android::hardware::thermal::V1_0::TemperatureType"
+    type: TYPE_ENUM
+    enum_value: {
+        scalar_type: "uint32_t"
+
+        enumerator: "UNKNOWN"
+        scalar_value: {
+            uint32_t: 1000
+        }
+        enumerator: "CPU"
+        scalar_value: {
+            uint32_t: 0
+        }
+        enumerator: "GPU"
+        scalar_value: {
+            uint32_t: 1
+        }
+        enumerator: "BATTERY"
+        scalar_value: {
+            uint32_t: 2
+        }
+        enumerator: "SKIN"
+        scalar_value: {
+            uint32_t: 3
+        }
+    }
+}
+
+attribute: {
+    name: "::android::hardware::thermal::V1_0::CoolingType"
+    type: TYPE_ENUM
+    enum_value: {
+        scalar_type: "uint32_t"
+
+        enumerator: "FAN_RPM"
+        scalar_value: {
+            uint32_t: 0
+        }
+    }
+}
+
+attribute: {
+    name: "::android::hardware::thermal::V1_0::Temperature"
+    type: TYPE_STRUCT
+    struct_value: {
+        name: "type"
+        type: TYPE_ENUM
+        predefined_type: "::android::hardware::thermal::V1_0::TemperatureType"
+    }
+    struct_value: {
+        name: "name"
+        type: TYPE_STRING
+    }
+    struct_value: {
+        name: "currentValue"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+    struct_value: {
+        name: "throttlingThreshold"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+    struct_value: {
+        name: "shutdownThreshold"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+    struct_value: {
+        name: "vrThrottlingThreshold"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+}
+
+attribute: {
+    name: "::android::hardware::thermal::V1_0::CoolingDevice"
+    type: TYPE_STRUCT
+    struct_value: {
+        name: "type"
+        type: TYPE_ENUM
+        predefined_type: "::android::hardware::thermal::V1_0::CoolingType"
+    }
+    struct_value: {
+        name: "name"
+        type: TYPE_STRING
+    }
+    struct_value: {
+        name: "currentValue"
+        type: TYPE_SCALAR
+        scalar_type: "float_t"
+    }
+}
+
+attribute: {
+    name: "::android::hardware::thermal::V1_0::CpuUsage"
+    type: TYPE_STRUCT
+    struct_value: {
+        name: "name"
+        type: TYPE_STRING
+    }
+    struct_value: {
+        name: "active"
+        type: TYPE_SCALAR
+        scalar_type: "uint64_t"
+    }
+    struct_value: {
+        name: "total"
+        type: TYPE_SCALAR
+        scalar_type: "uint64_t"
+    }
+    struct_value: {
+        name: "isOnline"
+        type: TYPE_SCALAR
+        scalar_type: "bool_t"
+    }
+}
+
+attribute: {
+    name: "::android::hardware::thermal::V1_0::ThermalStatusCode"
+    type: TYPE_ENUM
+    enum_value: {
+        scalar_type: "uint32_t"
+
+        enumerator: "SUCCESS"
+        scalar_value: {
+            uint32_t: 0
+        }
+        enumerator: "FAILURE"
+        scalar_value: {
+            uint32_t: 1
+        }
+    }
+}
+
+attribute: {
+    name: "::android::hardware::thermal::V1_0::ThermalStatus"
+    type: TYPE_STRUCT
+    struct_value: {
+        name: "code"
+        type: TYPE_ENUM
+        predefined_type: "::android::hardware::thermal::V1_0::ThermalStatusCode"
+    }
+    struct_value: {
+        name: "debugMessage"
+        type: TYPE_STRING
+    }
+}
+
diff --git a/thermal/Android.bp b/thermal/Android.bp
index ba90f2c..ed19a37 100644
--- a/thermal/Android.bp
+++ b/thermal/Android.bp
@@ -2,4 +2,5 @@
 subdirs = [
     "1.0",
     "1.0/default",
+    "1.0/vts/functional",
 ]