Merge "Initial HIDL vehicle HAL"
diff --git a/Android.bp b/Android.bp
index 7424633..3f9b925 100644
--- a/Android.bp
+++ b/Android.bp
@@ -3,6 +3,10 @@
     "audio/common/2.0",
     "audio/effect/2.0",
     "benchmarks/msgq/1.0",
+    "graphics/allocator/2.0",
+    "graphics/allocator/2.0/default",
+    "graphics/mapper/2.0",
+    "graphics/mapper/2.0/default",
     "memtrack/1.0",
     "memtrack/1.0/default",
     "light/2.0",
@@ -11,6 +15,7 @@
     "radio/1.0",
     "power/1.0",
     "power/1.0/default",
+    "soundtrigger/2.0",
     "tests/bar/1.0",
     "tests/baz/1.0",
     "tests/expression/1.0",
diff --git a/graphics/allocator/2.0/Android.bp b/graphics/allocator/2.0/Android.bp
new file mode 100644
index 0000000..f29c50b
--- /dev/null
+++ b/graphics/allocator/2.0/Android.bp
@@ -0,0 +1,46 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+genrule {
+    name: "android.hardware.graphics.allocator@2.0_genc++",
+    tool: "hidl-gen",
+    cmd: "$tool -o $genDir -Lc++ -randroid.hardware:hardware/interfaces android.hardware.graphics.allocator@2.0",
+    srcs: [
+        "types.hal",
+        "IAllocator.hal",
+    ],
+    out: [
+        "android/hardware/graphics/allocator/2.0/types.cpp",
+        "android/hardware/graphics/allocator/2.0/AllocatorAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.graphics.allocator@2.0_genc++_headers",
+    tool: "hidl-gen",
+    cmd: "$tool -o $genDir -Lc++ -randroid.hardware:hardware/interfaces android.hardware.graphics.allocator@2.0",
+    srcs: [
+        "types.hal",
+        "IAllocator.hal",
+    ],
+    out: [
+        "android/hardware/graphics/allocator/2.0/types.h",
+        "android/hardware/graphics/allocator/2.0/IAllocator.h",
+        "android/hardware/graphics/allocator/2.0/IHwAllocator.h",
+        "android/hardware/graphics/allocator/2.0/BnAllocator.h",
+        "android/hardware/graphics/allocator/2.0/BpAllocator.h",
+        "android/hardware/graphics/allocator/2.0/BsAllocator.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.graphics.allocator@2.0",
+    generated_sources: ["android.hardware.graphics.allocator@2.0_genc++"],
+    generated_headers: ["android.hardware.graphics.allocator@2.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.graphics.allocator@2.0_genc++_headers"],
+    shared_libs: [
+        "libhidl",
+        "libhwbinder",
+        "libutils",
+        "libcutils",
+    ],
+}
diff --git a/graphics/allocator/2.0/IAllocator.hal b/graphics/allocator/2.0/IAllocator.hal
new file mode 100644
index 0000000..8accb82
--- /dev/null
+++ b/graphics/allocator/2.0/IAllocator.hal
@@ -0,0 +1,177 @@
+/*
+ * 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.graphics.allocator@2.0;
+
+interface IAllocator {
+    enum Capability : int32_t {
+        /* reserved */
+        INVALID = 0,
+
+        /*
+         * testAllocate will always return UNDEFINED unless this capability
+         * is supported.
+         */
+        TEST_ALLOCATE = 1,
+    };
+
+    struct BufferDescriptorInfo {
+        /*
+         * The width specifies how many columns of pixels should be in the
+         * allocated buffer, but does not necessarily represent the offset in
+         * columns between the same column in adjacent rows. The rows may be
+         * padded.
+         */
+        uint32_t width;
+
+       /*
+        * The height specifies how many rows of pixels should be in the
+        * allocated buffer.
+        */
+        uint32_t height;
+
+        /* Buffer pixel format. */
+        PixelFormat format;
+
+        /*
+         * Buffer producer usage mask; valid flags can be found in the
+         * definition of ProducerUsage.
+         */
+        uint64_t producerUsageMask;
+
+        /*
+         * Buffer consumer usage mask; valid flags can be found in the
+         * definition of ConsumerUsage.
+         */
+        uint64_t consumerUsageMask;
+    };
+
+    /*
+     * Provides a list of supported capabilities (as described in the
+     * definition of Capability above). This list must not change after
+     * initialization.
+     *
+     * @return capabilities is a list of supported capabilities.
+     */
+    getCapabilities() generates (vec<Capability> capabilities);
+
+    /*
+     * Retrieves implementation-defined debug information, which will be
+     * displayed during, for example, `dumpsys SurfaceFlinger`.
+     *
+     * @return debugInfo is a string of debug information.
+     */
+    dumpDebugInfo() generates (string debugInfo);
+
+    /*
+     * Creates a new, opaque buffer descriptor.
+     *
+     * @param descriptorInfo specifies the attributes of the buffer
+     *        descriptor.
+     * @return error is NONE upon success. Otherwise,
+     *         BAD_VALUE when any attribute in descriptorInfo is invalid.
+     *         NO_RESOURCES when no more descriptors can currently be created.
+     * @return descriptor is the newly created buffer descriptor.
+     */
+    createDescriptor(BufferDescriptorInfo descriptorInfo)
+          generates (Error error,
+                     BufferDescriptor descriptor);
+
+    /*
+     * Destroys an existing buffer descriptor.
+     *
+     * @param descriptor is the descriptor to destroy.
+     * @return error is either NONE or BAD_DESCRIPTOR.
+     */
+    destroyDescriptor(BufferDescriptor descriptor) generates (Error error);
+
+    /*
+     * Tests whether a buffer allocation can succeed, ignoring potential
+     * resource contention which might lead to a NO_RESOURCES error.
+     *
+     * @param descriptors is a list of buffer descriptors.
+     * @return error is NONE or NOT_SHARED upon success;
+     *         NONE when buffers can be created and share a backing store.
+     *         NOT_SHARED when buffers can be created but require more than a
+     *                    backing store.
+     *         Otherwise,
+     *         BAD_DESCRIPTOR when any of the descriptors is invalid.
+     *         UNSUPPORTED when any of the descriptors can never be satisfied.
+     *         UNDEFINED when TEST_ALLOCATE is not listed in getCapabilities.
+     */
+    testAllocate(vec<BufferDescriptor> descriptors) generates (Error error);
+
+    /*
+     * Attempts to allocate a list of buffers sharing a backing store.
+     *
+     * Each buffer will correspond to one of the descriptors passed into the
+     * function and will hold a reference to its backing store. If the device
+     * is unable to share the backing store between the buffers, it must
+     * attempt to allocate the buffers with different backing stores and
+     * return NOT_SHARED if it is successful.
+     *
+     * @param descriptors is the buffer descriptors to attempt to allocate.
+     * @return error is NONE or NOT_SHARED upon success;
+     *         NONE when buffers can be created and share a backing store.
+     *         NOT_SHARED when buffers can be created but require more than a
+     *                    backing store.
+     *         Otherwise,
+     *         BAD_DESCRIPTOR when any of the descriptors is invalid.
+     *         UNSUPPORTED when any of the descriptors can never be satisfied.
+     *         NO_RESOURCES when any of the buffers cannot be created at this
+     *                      time.
+     * @return buffers is the allocated buffers.
+     */
+    allocate(vec<BufferDescriptor> descriptors)
+        generates (Error error,
+                   vec<Buffer> buffers);
+
+    /*
+     * Frees a buffer.
+     *
+     * @param buffer is the buffer to be freed.
+     * @return error is NONE upon success. Otherwise,
+     *         BAD_BUFFER when the buffer is invalid.
+     */
+    free(Buffer buffer) generates (Error error);
+
+    /*
+     * Exports a buffer for use in other client libraries or for cross-process
+     * sharing.
+     *
+     * The exported handle is a handle to the backing store of the buffer, not
+     * to the buffer itself. It however may not hold any reference to the
+     * backing store and may be considered invalid by client libraries. To use
+     * it and, in most cases, to save it for later use, a client must make a
+     * clone of the handle and have the cloned handle hold a reference to the
+     * backing store. Such a cloned handle will stay valid even after the
+     * original buffer is freed. Refer to native_handle_clone and IMapper for
+     * how a handle is cloned and how a reference is added.
+     *
+     * @param descriptor is the descriptor used to allocate the buffer.
+     * @param buffer is the buffer to be exported.
+     * @return error is NONE upon success. Otherwise,
+     *         BAD_DESCRIPTOR when the descriptor is invalid.
+     *         BAD_BUFFER when the buffer is invalid.
+     *         BAD_VALUE when descriptor and buffer do not match.
+     *         NO_RESOURCES when the buffer cannot be exported at this time.
+     * @return bufferHandle is the exported handle.
+     */
+    exportHandle(BufferDescriptor descriptor,
+                 Buffer buffer)
+      generates (Error error,
+                 handle bufferHandle);
+};
diff --git a/graphics/allocator/2.0/default/Android.bp b/graphics/allocator/2.0/default/Android.bp
new file mode 100644
index 0000000..9a24773
--- /dev/null
+++ b/graphics/allocator/2.0/default/Android.bp
@@ -0,0 +1,24 @@
+cc_library_shared {
+    name: "android.hardware.graphics.allocator@2.0-impl",
+    relative_install_path: "hw",
+    srcs: ["Gralloc.cpp"],
+    cppflags: ["-Wall", "-Wextra"],
+    shared_libs: [
+        "android.hardware.graphics.allocator@2.0",
+        "libbase",
+        "libcutils",
+        "libhardware",
+        "libhidl",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+    ],
+}
+
+cc_library_static {
+    name: "libgralloc1-adapter",
+    srcs: ["gralloc1-adapter.c"],
+    include_dirs: ["system/core/libsync/include"],
+    cflags: ["-Wall", "-Wextra", "-Wno-unused-parameter"],
+    export_include_dirs: ["."],
+}
diff --git a/graphics/allocator/2.0/default/Gralloc.cpp b/graphics/allocator/2.0/default/Gralloc.cpp
new file mode 100644
index 0000000..a7fc6c1
--- /dev/null
+++ b/graphics/allocator/2.0/default/Gralloc.cpp
@@ -0,0 +1,297 @@
+/*
+ * Copyright 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 "GrallocPassthrough"
+
+#include <type_traits>
+#include <unordered_set>
+#include <vector>
+
+#include <string.h>
+
+#include <hardware/gralloc1.h>
+#include <log/log.h>
+
+#include "Gralloc.h"
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace implementation {
+
+class GrallocHal : public IAllocator {
+public:
+    GrallocHal(const hw_module_t* module);
+    virtual ~GrallocHal();
+
+    // IAllocator interface
+    Return<void> getCapabilities(getCapabilities_cb hidl_cb) override;
+    Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
+    Return<void> createDescriptor(const BufferDescriptorInfo& descriptorInfo,
+            createDescriptor_cb hidl_cb) override;
+    Return<Error> destroyDescriptor(BufferDescriptor descriptor) override;
+
+    Return<Error> testAllocate(
+            const hidl_vec<BufferDescriptor>& descriptors) override;
+    Return<void> allocate(const hidl_vec<BufferDescriptor>& descriptors,
+            allocate_cb hidl_cb) override;
+    Return<Error> free(Buffer buffer) override;
+
+    Return<void> exportHandle(BufferDescriptor descriptor,
+            Buffer buffer, exportHandle_cb hidl_cb) override;
+
+private:
+    void initCapabilities();
+
+    template<typename T>
+    void initDispatch(T& func, gralloc1_function_descriptor_t desc);
+    void initDispatch();
+
+    bool hasCapability(Capability capability) const;
+
+    gralloc1_device_t* mDevice;
+
+    std::unordered_set<Capability> mCapabilities;
+
+    struct {
+        GRALLOC1_PFN_DUMP dump;
+        GRALLOC1_PFN_CREATE_DESCRIPTOR createDescriptor;
+        GRALLOC1_PFN_DESTROY_DESCRIPTOR destroyDescriptor;
+        GRALLOC1_PFN_SET_DIMENSIONS setDimensions;
+        GRALLOC1_PFN_SET_FORMAT setFormat;
+        GRALLOC1_PFN_SET_CONSUMER_USAGE setConsumerUsage;
+        GRALLOC1_PFN_SET_PRODUCER_USAGE setProducerUsage;
+        GRALLOC1_PFN_ALLOCATE allocate;
+        GRALLOC1_PFN_RELEASE release;
+        GRALLOC1_PFN_GET_BACKING_STORE getBackingStore;
+        GRALLOC1_PFN_GET_STRIDE getStride;
+        GRALLOC1_PFN_GET_NUM_FLEX_PLANES getNumFlexPlanes;
+    } mDispatch;
+};
+
+GrallocHal::GrallocHal(const hw_module_t* module)
+    : mDevice(nullptr), mDispatch()
+{
+    int status = gralloc1_open(module, &mDevice);
+    if (status) {
+        LOG_ALWAYS_FATAL("failed to open gralloc1 device: %s",
+                strerror(-status));
+    }
+
+    initCapabilities();
+    initDispatch();
+}
+
+GrallocHal::~GrallocHal()
+{
+    gralloc1_close(mDevice);
+}
+
+void GrallocHal::initCapabilities()
+{
+    uint32_t count;
+    mDevice->getCapabilities(mDevice, &count, nullptr);
+
+    std::vector<Capability> caps(count);
+    mDevice->getCapabilities(mDevice, &count, reinterpret_cast<
+              std::underlying_type<Capability>::type*>(caps.data()));
+    caps.resize(count);
+
+    mCapabilities.insert(caps.cbegin(), caps.cend());
+}
+
+template<typename T>
+void GrallocHal::initDispatch(T& func, gralloc1_function_descriptor_t desc)
+{
+    auto pfn = mDevice->getFunction(mDevice, desc);
+    if (!pfn) {
+        LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc);
+    }
+
+    func = reinterpret_cast<T>(pfn);
+}
+
+void GrallocHal::initDispatch()
+{
+    initDispatch(mDispatch.dump, GRALLOC1_FUNCTION_DUMP);
+    initDispatch(mDispatch.createDescriptor,
+            GRALLOC1_FUNCTION_CREATE_DESCRIPTOR);
+    initDispatch(mDispatch.destroyDescriptor,
+            GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR);
+    initDispatch(mDispatch.setDimensions, GRALLOC1_FUNCTION_SET_DIMENSIONS);
+    initDispatch(mDispatch.setFormat, GRALLOC1_FUNCTION_SET_FORMAT);
+    initDispatch(mDispatch.setConsumerUsage,
+            GRALLOC1_FUNCTION_SET_CONSUMER_USAGE);
+    initDispatch(mDispatch.setProducerUsage,
+            GRALLOC1_FUNCTION_SET_PRODUCER_USAGE);
+    initDispatch(mDispatch.allocate, GRALLOC1_FUNCTION_ALLOCATE);
+    initDispatch(mDispatch.release, GRALLOC1_FUNCTION_RELEASE);
+}
+
+bool GrallocHal::hasCapability(Capability capability) const
+{
+    return (mCapabilities.count(capability) > 0);
+}
+
+Return<void> GrallocHal::getCapabilities(getCapabilities_cb hidl_cb)
+{
+    std::vector<Capability> caps(
+            mCapabilities.cbegin(), mCapabilities.cend());
+
+    hidl_vec<Capability> reply;
+    reply.setToExternal(caps.data(), caps.size());
+    hidl_cb(reply);
+
+    return Void();
+}
+
+Return<void> GrallocHal::dumpDebugInfo(dumpDebugInfo_cb hidl_cb)
+{
+    uint32_t len = 0;
+    mDispatch.dump(mDevice, &len, nullptr);
+
+    std::vector<char> buf(len + 1);
+    mDispatch.dump(mDevice, &len, buf.data());
+    buf.resize(len + 1);
+    buf[len] = '\0';
+
+    hidl_string reply;
+    reply.setToExternal(buf.data(), len);
+    hidl_cb(reply);
+
+    return Void();
+}
+
+Return<void> GrallocHal::createDescriptor(
+        const BufferDescriptorInfo& descriptorInfo,
+        createDescriptor_cb hidl_cb)
+{
+    BufferDescriptor descriptor;
+    int32_t err = mDispatch.createDescriptor(mDevice, &descriptor);
+    if (err == GRALLOC1_ERROR_NONE) {
+        err = mDispatch.setDimensions(mDevice, descriptor,
+                descriptorInfo.width, descriptorInfo.height);
+    }
+    if (err == GRALLOC1_ERROR_NONE) {
+        err = mDispatch.setFormat(mDevice, descriptor,
+                static_cast<int32_t>(descriptorInfo.format));
+    }
+    if (err == GRALLOC1_ERROR_NONE) {
+        uint64_t producerUsageMask = descriptorInfo.producerUsageMask;
+        if (producerUsageMask & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN) {
+            producerUsageMask |= GRALLOC1_PRODUCER_USAGE_CPU_READ;
+        }
+        if (producerUsageMask & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN) {
+            producerUsageMask |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE;
+        }
+        err = mDispatch.setProducerUsage(mDevice, descriptor,
+                descriptorInfo.producerUsageMask);
+    }
+    if (err == GRALLOC1_ERROR_NONE) {
+        uint64_t consumerUsageMask = descriptorInfo.consumerUsageMask;
+        if (consumerUsageMask & GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN) {
+            consumerUsageMask |= GRALLOC1_CONSUMER_USAGE_CPU_READ;
+        }
+        err = mDispatch.setConsumerUsage(mDevice, descriptor,
+                consumerUsageMask);
+    }
+
+    hidl_cb(static_cast<Error>(err), descriptor);
+
+    return Void();
+}
+
+Return<Error> GrallocHal::destroyDescriptor(
+        BufferDescriptor descriptor)
+{
+    int32_t err = mDispatch.destroyDescriptor(mDevice, descriptor);
+    return static_cast<Error>(err);
+}
+
+Return<Error> GrallocHal::testAllocate(
+        const hidl_vec<BufferDescriptor>& descriptors)
+{
+    if (!hasCapability(Capability::TEST_ALLOCATE)) {
+        return Error::UNDEFINED;
+    }
+
+    int32_t err = mDispatch.allocate(mDevice, descriptors.size(),
+            &descriptors[0], nullptr);
+    return static_cast<Error>(err);
+}
+
+Return<void> GrallocHal::allocate(
+        const hidl_vec<BufferDescriptor>& descriptors,
+        allocate_cb hidl_cb) {
+    std::vector<buffer_handle_t> buffers(descriptors.size());
+    int32_t err = mDispatch.allocate(mDevice, descriptors.size(),
+            &descriptors[0], buffers.data());
+    if (err != GRALLOC1_ERROR_NONE && err != GRALLOC1_ERROR_NOT_SHARED) {
+        buffers.clear();
+    }
+
+    hidl_vec<Buffer> reply;
+    reply.setToExternal(
+            reinterpret_cast<Buffer*>(buffers.data()),
+            buffers.size());
+    hidl_cb(static_cast<Error>(err), reply);
+
+    return Void();
+}
+
+Return<Error> GrallocHal::free(Buffer buffer)
+{
+    buffer_handle_t handle = reinterpret_cast<buffer_handle_t>(buffer);
+    int32_t err = mDispatch.release(mDevice, handle);
+    return static_cast<Error>(err);
+}
+
+Return<void> GrallocHal::exportHandle(BufferDescriptor /*descriptor*/,
+        Buffer buffer, exportHandle_cb hidl_cb)
+{
+    // do we want to validate?
+    buffer_handle_t handle = reinterpret_cast<buffer_handle_t>(buffer);
+
+    hidl_cb(Error::NONE, handle);
+
+    return Void();
+}
+
+IAllocator* HIDL_FETCH_IAllocator(const char* /* name */) {
+    const hw_module_t* module;
+    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
+    if (err) {
+        ALOGE("failed to get gralloc module");
+        return nullptr;
+    }
+
+    uint8_t major = (module->module_api_version >> 8) & 0xff;
+    if (major != 1) {
+        ALOGE("unknown gralloc module major version %d", major);
+        return nullptr;
+    }
+
+    return new GrallocHal(module);
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace allocator
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/allocator/2.0/default/Gralloc.h b/graphics/allocator/2.0/default/Gralloc.h
new file mode 100644
index 0000000..c79eeaa
--- /dev/null
+++ b/graphics/allocator/2.0/default/Gralloc.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 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_GRAPHICS_ALLOCATOR_V2_0_GRALLOC_H
+#define ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC_H
+
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace implementation {
+
+extern "C" IAllocator* HIDL_FETCH_IAllocator(const char* name);
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace allocator
+} // namespace graphics
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC_H
diff --git a/graphics/allocator/2.0/default/gralloc1-adapter.c b/graphics/allocator/2.0/default/gralloc1-adapter.c
new file mode 100644
index 0000000..724cd47
--- /dev/null
+++ b/graphics/allocator/2.0/default/gralloc1-adapter.c
@@ -0,0 +1,660 @@
+/*
+ * Copyright 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 "Gralloc1Adapter"
+
+#include <stdatomic.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <pthread.h>
+
+#include <cutils/native_handle.h>
+#include <hardware/gralloc1.h>
+#include <sync/sync.h>
+#include <log/log.h>
+
+#include "gralloc1-adapter.h"
+
+struct gralloc1_adapter_module {
+    struct gralloc_module_t base;
+    struct gralloc1_adapter adapter;
+};
+
+struct gralloc1_adapter_device {
+    struct gralloc1_device base;
+
+    struct alloc_device_t* alloc_dev;
+
+    /* fixed size for thread safety */
+    char saved_dump[4096];
+    size_t saved_dump_size;
+};
+
+/* additional data associated with registered buffer_handle_t */
+struct gralloc1_adapter_buffer_data {
+    struct gralloc1_adapter_buffer_info info;
+
+    atomic_int refcount;
+    bool owned;
+};
+
+struct gralloc1_adapter_buffer_descriptor {
+    int width;
+    int height;
+    int format;
+    int producer_usage;
+    int consumer_usage;
+};
+
+static const struct gralloc1_adapter_module* gralloc1_adapter_module(
+        struct gralloc1_device* dev)
+{
+    return (const struct gralloc1_adapter_module*) dev->common.module;
+}
+
+static struct gralloc1_adapter_device* gralloc1_adapter_device(
+        struct gralloc1_device* dev)
+{
+    return (struct gralloc1_adapter_device*) dev;
+}
+
+static struct gralloc1_adapter_buffer_data* lookup_buffer_data(
+        struct gralloc1_device* dev, buffer_handle_t buffer)
+{
+    const struct gralloc1_adapter_module* mod = gralloc1_adapter_module(dev);
+    if (!mod->adapter.is_registered(&mod->base, buffer))
+        return NULL;
+
+    return mod->adapter.get_data(&mod->base, buffer);
+}
+
+static struct gralloc1_adapter_buffer_descriptor* lookup_buffer_descriptor(
+        struct gralloc1_device* dev, gralloc1_buffer_descriptor_t id)
+{
+    /* do we want to validate? */
+    return (struct gralloc1_adapter_buffer_descriptor*) ((uintptr_t) id);
+}
+
+static void device_dump(struct gralloc1_device* device,
+        uint32_t* outSize, char* outBuffer)
+{
+    struct gralloc1_adapter_device* dev = gralloc1_adapter_device(device);
+
+    if (outBuffer) {
+        uint32_t copy = (uint32_t) dev->saved_dump_size;
+        if (*outSize < copy) {
+            copy = *outSize;
+        } else {
+            *outSize = copy;
+        }
+
+        memcpy(outBuffer, dev->saved_dump, copy);
+    } else {
+        /* dump is optional and may not null-terminate */
+        if (dev->alloc_dev->dump) {
+            dev->alloc_dev->dump(dev->alloc_dev, dev->saved_dump,
+                    sizeof(dev->saved_dump) - 1);
+            dev->saved_dump_size = strlen(dev->saved_dump);
+        }
+
+        *outSize = (uint32_t) dev->saved_dump_size;
+    }
+}
+
+static int32_t device_create_descriptor(struct gralloc1_device* device,
+        gralloc1_buffer_descriptor_t* outDescriptor)
+{
+    struct gralloc1_adapter_buffer_descriptor* desc;
+
+    desc = calloc(1, sizeof(*desc));
+    if (!desc) {
+        return GRALLOC1_ERROR_NO_RESOURCES;
+    }
+
+    *outDescriptor = (gralloc1_buffer_descriptor_t) (uintptr_t) desc;
+
+    return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t device_destroy_descriptor(struct gralloc1_device* device,
+        gralloc1_buffer_descriptor_t descriptor)
+{
+    struct gralloc1_adapter_buffer_descriptor* desc =
+        lookup_buffer_descriptor(device, descriptor);
+    if (!desc) {
+        return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+    }
+
+    free(desc);
+
+    return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t device_set_consumer_usage(struct gralloc1_device* device,
+        gralloc1_buffer_descriptor_t descriptor, uint64_t usage)
+{
+    struct gralloc1_adapter_buffer_descriptor* desc =
+        lookup_buffer_descriptor(device, descriptor);
+    if (!desc) {
+        return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+    }
+
+    desc->consumer_usage = (int) usage;
+
+    return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t device_set_dimensions(struct gralloc1_device* device,
+        gralloc1_buffer_descriptor_t descriptor,
+        uint32_t width, uint32_t height)
+{
+    struct gralloc1_adapter_buffer_descriptor* desc =
+        lookup_buffer_descriptor(device, descriptor);
+    if (!desc) {
+        return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+    }
+
+    desc->width = (int) width;
+    desc->height = (int) height;
+
+    return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t device_set_format(struct gralloc1_device* device,
+        gralloc1_buffer_descriptor_t descriptor, int32_t format)
+{
+    struct gralloc1_adapter_buffer_descriptor* desc =
+        lookup_buffer_descriptor(device, descriptor);
+    if (!desc) {
+        return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+    }
+
+    desc->format = format;
+
+    return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t device_set_producer_usage(struct gralloc1_device* device,
+        gralloc1_buffer_descriptor_t descriptor, uint64_t usage)
+{
+    struct gralloc1_adapter_buffer_descriptor* desc =
+        lookup_buffer_descriptor(device, descriptor);
+    if (!desc) {
+        return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+    }
+
+    desc->producer_usage = (int) usage;
+
+    return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t device_get_backing_store(struct gralloc1_device* device,
+        buffer_handle_t buffer, gralloc1_backing_store_t* outStore)
+{
+    /* we never share backing store */
+    *outStore = (gralloc1_backing_store_t) (uintptr_t) buffer;
+
+    return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t device_get_consumer_usage(struct gralloc1_device* device,
+        buffer_handle_t buffer, uint64_t* outUsage)
+{
+    const struct gralloc1_adapter_buffer_data* data =
+        lookup_buffer_data(device, buffer);
+    if (!data) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+    }
+
+    *outUsage = data->info.usage;
+
+    return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t device_get_dimensions(struct gralloc1_device* device,
+        buffer_handle_t buffer, uint32_t* outWidth, uint32_t* outHeight)
+{
+    const struct gralloc1_adapter_buffer_data* data =
+        lookup_buffer_data(device, buffer);
+    if (!data) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+    }
+
+    *outWidth = data->info.width;
+    *outHeight = data->info.height;
+
+    return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t device_get_format(struct gralloc1_device* device,
+        buffer_handle_t buffer, int32_t* outFormat)
+{
+    const struct gralloc1_adapter_buffer_data* data =
+        lookup_buffer_data(device, buffer);
+    if (!data) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+    }
+
+    *outFormat = data->info.format;
+
+    return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t device_get_producer_usage(struct gralloc1_device* device,
+        buffer_handle_t buffer, uint64_t* outUsage)
+{
+    const struct gralloc1_adapter_buffer_data* data =
+        lookup_buffer_data(device, buffer);
+    if (!data) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+    }
+
+    *outUsage = data->info.usage;
+
+    return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t device_get_stride(struct gralloc1_device* device,
+        buffer_handle_t buffer, uint32_t* outStride)
+{
+    const struct gralloc1_adapter_buffer_data* data =
+        lookup_buffer_data(device, buffer);
+    if (!data) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+    }
+
+    *outStride = data->info.stride;
+
+    return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t device_allocate(struct gralloc1_device* device,
+        uint32_t numDescriptors,
+        const gralloc1_buffer_descriptor_t* descriptors,
+        buffer_handle_t* outBuffers)
+{
+    const struct gralloc1_adapter_module* mod =
+        gralloc1_adapter_module(device);
+    struct gralloc1_adapter_device* dev = gralloc1_adapter_device(device);
+    gralloc1_error_t err = GRALLOC1_ERROR_NONE;
+    uint32_t i;
+
+    for (i = 0; i < numDescriptors; i++) {
+        const struct gralloc1_adapter_buffer_descriptor* desc =
+            lookup_buffer_descriptor(device, descriptors[i]);
+        struct gralloc1_adapter_buffer_data* data;
+        buffer_handle_t buffer;
+        int dummy_stride;
+        int ret;
+
+        if (!desc) {
+            err = GRALLOC1_ERROR_BAD_DESCRIPTOR;
+            break;
+        }
+
+        data = calloc(1, sizeof(*data));
+        if (!data) {
+            err = GRALLOC1_ERROR_NO_RESOURCES;
+            break;
+        }
+
+        ret = dev->alloc_dev->alloc(dev->alloc_dev, desc->width, desc->height,
+                desc->format, desc->producer_usage | desc->consumer_usage,
+                &buffer, &dummy_stride);
+        if (ret) {
+            free(data);
+            err = GRALLOC1_ERROR_NO_RESOURCES;
+            break;
+        }
+
+        mod->adapter.get_info(&mod->base, buffer, &data->info);
+        data->refcount = 1;
+        data->owned = true;
+
+        mod->adapter.set_data(&mod->base, buffer, data);
+
+        outBuffers[i] = buffer;
+    }
+
+    if (err != GRALLOC1_ERROR_NONE) {
+        uint32_t j;
+        for (j = 0; j < i; j++) {
+            free(mod->adapter.get_data(&mod->base, outBuffers[i]));
+            dev->alloc_dev->free(dev->alloc_dev, outBuffers[i]);
+        }
+
+        return err;
+    }
+
+    return (numDescriptors > 1) ?
+        GRALLOC1_ERROR_NOT_SHARED : GRALLOC1_ERROR_NONE;
+}
+
+static int32_t device_retain(struct gralloc1_device* device,
+        buffer_handle_t buffer)
+{
+    static pthread_mutex_t register_mutex = PTHREAD_MUTEX_INITIALIZER;
+    const struct gralloc1_adapter_module* mod =
+        gralloc1_adapter_module(device);
+    struct gralloc1_adapter_buffer_data* data;
+
+    pthread_mutex_lock(&register_mutex);
+
+    if (mod->adapter.is_registered(&mod->base, buffer)) {
+        data = mod->adapter.get_data(&mod->base, buffer);
+        data->refcount++;
+    } else {
+        int ret;
+
+        data = calloc(1, sizeof(*data));
+        if (!data) {
+            pthread_mutex_unlock(&register_mutex);
+            return GRALLOC1_ERROR_NO_RESOURCES;
+        }
+
+        ret = mod->base.registerBuffer(&mod->base, buffer);
+        if (ret) {
+            pthread_mutex_unlock(&register_mutex);
+            free(data);
+
+            return GRALLOC1_ERROR_NO_RESOURCES;
+        }
+
+        mod->adapter.get_info(&mod->base, buffer, &data->info);
+        data->refcount = 1;
+        data->owned = false;
+
+        mod->adapter.set_data(&mod->base, buffer, data);
+    }
+
+    pthread_mutex_unlock(&register_mutex);
+
+    return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t device_release(struct gralloc1_device* device,
+        buffer_handle_t buffer)
+{
+    struct gralloc1_adapter_buffer_data* data =
+        lookup_buffer_data(device, buffer);
+    if (!data) {
+        ALOGE("unable to release unregistered buffer %p", buffer);
+        return GRALLOC1_ERROR_BAD_HANDLE;
+    }
+
+    data->refcount--;
+    if (!data->refcount) {
+        if (data->owned) {
+            struct gralloc1_adapter_device* dev =
+                gralloc1_adapter_device(device);
+            dev->alloc_dev->free(dev->alloc_dev, buffer);
+        } else {
+            const struct gralloc1_adapter_module* mod =
+                gralloc1_adapter_module(device);
+            mod->base.unregisterBuffer(&mod->base, buffer);
+
+            native_handle_close(buffer);
+            native_handle_delete((native_handle_t*) buffer);
+        }
+
+        free(data);
+    }
+
+    return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t device_get_num_flex_planes(struct gralloc1_device* device,
+        buffer_handle_t buffer, uint32_t* outNumPlanes)
+{
+    const struct gralloc1_adapter_buffer_data* data =
+        lookup_buffer_data(device, buffer);
+    if (!data) {
+        return GRALLOC1_ERROR_BAD_HANDLE;
+    }
+
+    *outNumPlanes = data->info.num_flex_planes;
+
+    return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t device_lock(struct gralloc1_device* device,
+        buffer_handle_t buffer,
+        uint64_t producerUsage, uint64_t consumerUsage,
+        const gralloc1_rect_t* accessRegion, void** outData,
+        int32_t acquireFence)
+{
+    const struct gralloc1_adapter_module* mod =
+        gralloc1_adapter_module(device);
+    const int usage = (int) (producerUsage | consumerUsage);
+    const struct gralloc1_adapter_buffer_data* data =
+        lookup_buffer_data(device, buffer);
+    int ret;
+
+    if (!data) {
+        ALOGE("unable to lock unregistered buffer %p", buffer);
+        return GRALLOC1_ERROR_BAD_HANDLE;
+    }
+
+    if (mod->adapter.real_module_api_version >=
+            GRALLOC_MODULE_API_VERSION_0_3) {
+        ret = mod->base.lockAsync(&mod->base,
+                buffer, usage,
+                accessRegion->left,
+                accessRegion->top,
+                accessRegion->width,
+                accessRegion->height,
+                outData, acquireFence);
+    } else {
+        if (acquireFence >= 0) {
+            sync_wait(acquireFence, -1);
+        }
+
+        ret = mod->base.lock(&mod->base,
+                buffer, usage,
+                accessRegion->left,
+                accessRegion->top,
+                accessRegion->width,
+                accessRegion->height,
+                outData);
+
+        if (acquireFence >= 0 && !ret) {
+            close(acquireFence);
+        }
+    }
+
+    return (ret) ? GRALLOC1_ERROR_NO_RESOURCES : GRALLOC1_ERROR_NONE;
+}
+
+static int32_t device_lock_flex(struct gralloc1_device* device,
+        buffer_handle_t buffer,
+        uint64_t producerUsage, uint64_t consumerUsage,
+        const gralloc1_rect_t* accessRegion,
+        struct android_flex_layout* outFlexLayout,
+        int32_t acquireFence)
+{
+    const struct gralloc1_adapter_module* mod =
+        gralloc1_adapter_module(device);
+    const int usage = (int) (producerUsage | consumerUsage);
+    const struct gralloc1_adapter_buffer_data* data =
+        lookup_buffer_data(device, buffer);
+    struct android_ycbcr ycbcr;
+    int ret;
+
+    if (!data) {
+        ALOGE("unable to lockFlex unregistered buffer %p", buffer);
+        return GRALLOC1_ERROR_BAD_HANDLE;
+    }
+
+    if (outFlexLayout->num_planes < data->info.num_flex_planes) {
+        return GRALLOC1_ERROR_BAD_VALUE;
+    }
+
+    if (mod->adapter.real_module_api_version >=
+            GRALLOC_MODULE_API_VERSION_0_3 && mod->base.lockAsync_ycbcr) {
+        ret = mod->base.lockAsync_ycbcr(&mod->base,
+                buffer, usage,
+                accessRegion->left,
+                accessRegion->top,
+                accessRegion->width,
+                accessRegion->height,
+                &ycbcr, acquireFence);
+    } else if (mod->base.lock_ycbcr) {
+        if (acquireFence >= 0) {
+            sync_wait(acquireFence, -1);
+        }
+
+        ret = mod->base.lock_ycbcr(&mod->base,
+                buffer, usage,
+                accessRegion->left,
+                accessRegion->top,
+                accessRegion->width,
+                accessRegion->height,
+                &ycbcr);
+
+        if (acquireFence >= 0 && !ret) {
+            close(acquireFence);
+        }
+    } else {
+        return GRALLOC1_ERROR_UNSUPPORTED;
+    }
+
+    if (ret) {
+        return GRALLOC1_ERROR_NO_RESOURCES;
+    }
+
+    mod->adapter.get_flexible_layout(&mod->base, buffer,
+            &ycbcr, outFlexLayout);
+
+    return GRALLOC1_ERROR_NONE;
+}
+
+static int32_t device_unlock(struct gralloc1_device* device,
+        buffer_handle_t buffer, int32_t* outReleaseFence)
+{
+    const struct gralloc1_adapter_module* mod =
+        gralloc1_adapter_module(device);
+    int ret;
+
+    if (mod->adapter.real_module_api_version >=
+            GRALLOC_MODULE_API_VERSION_0_3) {
+        ret = mod->base.unlockAsync(&mod->base, buffer, outReleaseFence);
+    } else {
+        ret = mod->base.unlock(&mod->base, buffer);
+        if (!ret) {
+            *outReleaseFence = -1;
+        }
+    }
+
+    return (ret) ? GRALLOC1_ERROR_BAD_HANDLE : GRALLOC1_ERROR_NONE;
+}
+
+static gralloc1_function_pointer_t device_get_function(
+        struct gralloc1_device* device, int32_t descriptor)
+{
+    switch ((gralloc1_function_descriptor_t) descriptor) {
+#define CASE(id, ptr)              \
+    case GRALLOC1_FUNCTION_ ## id: \
+        return (gralloc1_function_pointer_t) device_ ## ptr
+    CASE(DUMP, dump);
+    CASE(CREATE_DESCRIPTOR, create_descriptor);
+    CASE(DESTROY_DESCRIPTOR, destroy_descriptor);
+    CASE(SET_CONSUMER_USAGE, set_consumer_usage);
+    CASE(SET_DIMENSIONS, set_dimensions);
+    CASE(SET_FORMAT, set_format);
+    CASE(SET_PRODUCER_USAGE, set_producer_usage);
+    CASE(GET_BACKING_STORE, get_backing_store);
+    CASE(GET_CONSUMER_USAGE, get_consumer_usage);
+    CASE(GET_DIMENSIONS, get_dimensions);
+    CASE(GET_FORMAT, get_format);
+    CASE(GET_PRODUCER_USAGE, get_producer_usage);
+    CASE(GET_STRIDE, get_stride);
+    CASE(ALLOCATE, allocate);
+    CASE(RETAIN, retain);
+    CASE(RELEASE, release);
+    CASE(GET_NUM_FLEX_PLANES, get_num_flex_planes);
+    CASE(LOCK, lock);
+    CASE(LOCK_FLEX, lock_flex);
+    CASE(UNLOCK, unlock);
+#undef CASE
+    default: return NULL;
+    }
+}
+
+static void device_get_capabilities(struct gralloc1_device* device,
+        uint32_t* outCount, int32_t* outCapabilities)
+{
+    *outCount = 0;
+}
+
+static int device_close(struct hw_device_t* device)
+{
+    struct gralloc1_adapter_device* dev =
+        (struct gralloc1_adapter_device*) device;
+    int ret;
+
+    ret = dev->alloc_dev->common.close(&dev->alloc_dev->common);
+    if (!ret) {
+        free(dev);
+    }
+
+    return ret;
+}
+
+int gralloc1_adapter_device_open(const struct hw_module_t* module,
+        const char* id, struct hw_device_t** device)
+{
+    const struct gralloc1_adapter_module* mod =
+        (const struct gralloc1_adapter_module*) module;
+    struct alloc_device_t* alloc_dev;
+    struct gralloc1_adapter_device* dev;
+    int ret;
+
+    if (strcmp(id, GRALLOC_HARDWARE_MODULE_ID) != 0) {
+        ALOGE("unknown gralloc1 device id: %s", id);
+        return -EINVAL;
+    }
+
+    ret = module->methods->open(module, GRALLOC_HARDWARE_GPU0,
+            (struct hw_device_t**) &alloc_dev);
+    if (ret) {
+        return ret;
+    }
+
+    dev = malloc(sizeof(*dev));
+    if (!dev) {
+        alloc_dev->common.close(&alloc_dev->common);
+        return -ENOMEM;
+    }
+
+    *dev = (struct gralloc1_adapter_device) {
+        .base = {
+            .common = {
+                .tag = HARDWARE_DEVICE_TAG,
+                .version = HARDWARE_DEVICE_API_VERSION(0, 0),
+                .module = (struct hw_module_t*) mod,
+                .close = device_close,
+            },
+            .getCapabilities = device_get_capabilities,
+            .getFunction = device_get_function,
+        },
+        .alloc_dev = alloc_dev,
+    };
+
+    *device = (struct hw_device_t*) dev;
+
+    return 0;
+}
diff --git a/graphics/allocator/2.0/default/gralloc1-adapter.h b/graphics/allocator/2.0/default/gralloc1-adapter.h
new file mode 100644
index 0000000..f48cd9e
--- /dev/null
+++ b/graphics/allocator/2.0/default/gralloc1-adapter.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright 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_GRALLOC1_ADAPTER_H
+#define ANDROID_HARDWARE_GRALLOC1_ADAPTER_H
+
+#include <stdbool.h>
+#include <hardware/gralloc.h>
+
+__BEGIN_DECLS
+
+struct gralloc1_adapter_buffer_info {
+    int width;
+    int height;
+    int format;
+    int usage;
+
+    int stride;
+    uint32_t num_flex_planes;
+};
+
+/* This struct must be embedded in the HAL's HAL_MODULE_INFO_SYM and must
+ * follow gralloc_module_t immediately. */
+struct gralloc1_adapter {
+    uint16_t real_module_api_version;
+
+    /* Return true if the buffer is registered.  A locally allocated buffer is
+     * always registered.
+     *
+     * This function is called frequently.  It must be thread safe just like
+     * other functions are.
+     */
+    bool (*is_registered)(const struct gralloc_module_t* mod,
+            buffer_handle_t buffer);
+
+    /* Set the adapter data for a registered buffer. */
+    void (*set_data)(const struct gralloc_module_t* mod,
+            buffer_handle_t buffer, void* data);
+
+    /* Get the adapter data for a registered buffer. */
+    void* (*get_data)(const struct gralloc_module_t* mod,
+            buffer_handle_t buffer);
+
+    /* Get the buffer info, such as width, height, etc. */
+    void (*get_info)(const struct gralloc_module_t* mod,
+            buffer_handle_t buffer,
+            struct gralloc1_adapter_buffer_info* info);
+
+    /* Get the flexilble layout matching ycbcr. */
+    void (*get_flexible_layout)(const struct gralloc_module_t* mod,
+            buffer_handle_t buffer, const struct android_ycbcr* ycbcr,
+            struct android_flex_layout* layout);
+};
+
+int gralloc1_adapter_device_open(const struct hw_module_t* module,
+        const char* id, struct hw_device_t** device);
+
+__END_DECLS
+
+#endif /* ANDROID_HARDWARE_GRALLOC1_ADAPTER_H */
diff --git a/graphics/allocator/2.0/types.hal b/graphics/allocator/2.0/types.hal
new file mode 100644
index 0000000..23b7345
--- /dev/null
+++ b/graphics/allocator/2.0/types.hal
@@ -0,0 +1,171 @@
+/*
+ * 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.graphics.allocator@2.0;
+
+enum Error : int32_t {
+    NONE            = 0, /* no error */
+    BAD_DESCRIPTOR  = 1, /* invalid BufferDescriptor */
+    BAD_BUFFER      = 2, /* invalid Buffer */
+    BAD_VALUE       = 3, /* invalid width, height, etc. */
+    NOT_SHARED      = 4, /* buffers not sharing backing store */
+    NO_RESOURCES    = 5, /* temporary failure due to resource contention */
+    UNDEFINED       = 6, /* an operation has no defined meaning */
+    UNSUPPORTED     = 7, /* permanent failure */
+};
+
+enum ProducerUsage : uint64_t {
+    /* bit 0 is reserved */
+
+    /* buffer will be read by CPU occasionally */
+    CPU_READ        = 1ULL << 1,
+    /* buffer will be read by CPU frequently */
+    CPU_READ_OFTEN  = 1ULL << 2,
+
+    /* bit 3 is reserved */
+    /* bit 4 is reserved */
+
+    /* buffer will be written by CPU occasionally */
+    CPU_WRITE       = 1ULL << 5,
+    /* buffer will be written by CPU frequently */
+    CPU_WRITE_OFTEN = 1ULL << 6,
+
+    /* bit 7 is reserved */
+    /* bit 8 is reserved */
+
+    /* buffer will be used as a GPU render target */
+    GPU_RENDER_TARGET = 1ULL << 9,
+
+    /* bit 10 is reserved */
+    /* bit 11 is reserved */
+    /* bit 12 is reserved */
+    /* bit 13 is reserved */
+
+    /*
+     * Buffer is allocated with hardware-level protection against copying the
+     * contents (or information derived from the contents) into unprotected
+     * memory.
+     */
+    PROTECTED         = 1ULL << 14,
+
+    /* bit 15 is reserved */
+    /* bit 16 is reserved */
+
+    /* buffer will be used as a camera HAL output */
+    CAMERA            = 1ULL << 17,
+
+    /* bit 18 is reserved */
+    /* bit 19 is reserved */
+    /* bit 20 is reserved */
+    /* bit 21 is reserved */
+
+    /* buffer will be used as a video decoder output */
+    VIDEO_DECODER     = 1ULL << 22,
+
+    /* bits 23-27 are reserved for future versions */
+    /* bits 28-31 are reserved for vendor extensions */
+
+    /* bits 32-47 are reserved for future versions */
+    /* bits 48-63 are reserved for vendor extensions */
+};
+
+enum ConsumerUsage : uint64_t {
+    /* bit 0 is reserved */
+
+    /* buffer will be read by CPU occasionally */
+    CPU_READ          = 1ULL << 1,
+    /* buffer will be read by CPU frequently */
+    CPU_READ_OFTEN    = 1ULL << 2,
+
+    /* bit 3 is reserved */
+    /* bit 4 is reserved */
+    /* bit 5 is reserved */
+    /* bit 6 is reserved */
+    /* bit 7 is reserved */
+
+    /* buffer will be used as a GPU texture */
+    GPU_TEXTURE       = 1ULL << 8,
+
+    /* bit 9 is reserved */
+    /* bit 10 is reserved */
+
+    /* buffer will be used by hwcomposer HAL */
+    HWCOMPOSER        = 1ULL << 11,
+    /* buffer will be as a hwcomposer HAL client target */
+    CLIENT_TARGET     = 1ULL << 12,
+
+    /* bit 13 is reserved */
+    /* bit 14 is reserved */
+
+    /* buffer will be used as a hwcomposer HAL cursor */
+    CURSOR            = 1ULL << 15,
+
+    /* buffer will be used as a video encoder input */
+    VIDEO_ENCODER     = 1ULL << 16,
+
+    /* bit 17 is reserved */
+
+    /* buffer will be used as a camera HAL input */
+    CAMERA            = 1ULL << 18,
+
+    /* bit 19 is reserved */
+
+    /* buffer will be used as a renderscript allocation */
+    RENDERSCRIPT      = 1ULL << 20,
+
+    /* bit 21 is reserved */
+    /* bit 22 is reserved */
+
+    /* bits 23-27 are reserved for future versions */
+    /* bits 28-31 are reserved for vendor extensions */
+
+    /* bits 32-47 are reserved for future versions */
+    /* bits 48-63 are reserved for vendor extensions */
+};
+
+/*
+ * Copied from android_pixel_format_t.
+ *
+ * TODO(olv) copy comments as well and have android_pixel_format_t generated
+ */
+@export(name="android_pixel_format", value_prefix="HAL_PIXEL_FORMAT_")
+enum PixelFormat : int32_t {
+    RGBA_8888              = 1,
+    RGBX_8888              = 2,
+    RGB_888                = 3,
+    RGB_565                = 4,
+    BGRA_8888              = 5,
+    YV12                   = 0x32315659,
+    Y8                     = 0x20203859,
+    Y16                    = 0x20363159,
+    RAW16                  = 0x20,
+    RAW10                  = 0x25,
+    RAW12                  = 0x26,
+    RAW_OPAQUE             = 0x24,
+    BLOB                   = 0x21,
+    IMPLEMENTATION_DEFINED = 0x22,
+    YCbCr_420_888          = 0x23,
+    YCbCr_422_888          = 0x27,
+    YCbCr_444_888          = 0x28,
+    FLEX_RGB_888           = 0x29,
+    FLEX_RGBA_8888         = 0x2A,
+    YCbCr_422_SP           = 0x10,
+    YCrCb_420_SP           = 0x11,
+    YCbCr_422_I            = 0x14,
+};
+
+typedef uint64_t BufferDescriptor;
+typedef uint64_t Buffer;
diff --git a/graphics/mapper/2.0/Android.bp b/graphics/mapper/2.0/Android.bp
new file mode 100644
index 0000000..3718503
--- /dev/null
+++ b/graphics/mapper/2.0/Android.bp
@@ -0,0 +1,15 @@
+genrule {
+    name: "android.hardware.graphics.mapper@2.0_genc++_headers",
+    cmd: "cp $in $genDir/android/hardware/graphics/mapper/2.0",
+    srcs: ["IMapper.h", "types.h"],
+    out: [
+        "android/hardware/graphics/mapper/2.0/IMapper.h",
+        "android/hardware/graphics/mapper/2.0/types.h",
+    ],
+}
+
+cc_library_static {
+    name: "android.hardware.graphics.mapper@2.0",
+    generated_headers: ["android.hardware.graphics.mapper@2.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.graphics.mapper@2.0_genc++_headers"],
+}
diff --git a/graphics/mapper/2.0/IMapper.h b/graphics/mapper/2.0/IMapper.h
new file mode 100644
index 0000000..23faa80
--- /dev/null
+++ b/graphics/mapper/2.0/IMapper.h
@@ -0,0 +1,388 @@
+/*
+ * Copyright 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_GRAPHICS_MAPPER_V2_0_IMAPPER_H
+#define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_IMAPPER_H
+
+#include <type_traits>
+
+#include <android/hardware/graphics/mapper/2.0/types.h>
+
+extern "C" {
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace mapper {
+namespace V2_0 {
+
+struct Device {
+    struct Rect {
+        int32_t left;
+        int32_t top;
+        int32_t width;
+        int32_t height;
+    };
+    static_assert(std::is_pod<Rect>::value, "Device::Rect is not POD");
+
+    /*
+     * Create a mapper device.
+     *
+     * @return error is NONE upon success. Otherwise,
+     *                  NOT_SUPPORTED when creation will never succeed.
+     *                  BAD_RESOURCES when creation failed at this time.
+     * @return device is the newly created mapper device.
+     */
+    typedef Error (*createDevice)(Device** outDevice);
+
+    /*
+     * Destroy a mapper device.
+     *
+     * @return error is always NONE.
+     * @param device is the mapper device to destroy.
+     */
+    typedef Error (*destroyDevice)(Device* device);
+
+    /*
+     * Adds a reference to the given buffer handle.
+     *
+     * A buffer handle received from a remote process or exported by
+     * IAllocator::exportHandle is unknown to this client-side library. There
+     * is also no guarantee that the buffer's backing store will stay alive.
+     * This function must be called at least once in both cases to intrdouce
+     * the buffer handle to this client-side library and to secure the backing
+     * store. It may also be called more than once to increase the reference
+     * count if two components in the same process want to interact with the
+     * buffer independently.
+     *
+     * @param device is the mapper device.
+     * @param bufferHandle is the buffer to which a reference must be added.
+     * @return error is NONE upon success. Otherwise,
+     *                  BAD_BUFFER when the buffer handle is invalid
+     *                  NO_RESOURCES when it is not possible to add a
+     *                               reference to this buffer at this time
+     */
+    typedef Error (*retain)(Device* device,
+                            const native_handle_t* bufferHandle);
+
+    /*
+     * Removes a reference from the given buffer buffer.
+     *
+     * If no references remain, the buffer handle should be freed with
+     * native_handle_close/native_handle_delete. When the last buffer handle
+     * referring to a particular backing store is freed, that backing store
+     * should also be freed.
+     *
+     * @param device is the mapper device.
+     * @param bufferHandle is the buffer from which a reference must be
+     *        removed.
+     * @return error is NONE upon success. Otherwise,
+     *                  BAD_BUFFER when the buffer handle is invalid.
+     */
+    typedef Error (*release)(Device* device,
+                             const native_handle_t* bufferHandle);
+
+    /*
+     * Gets the width and height of the buffer in pixels.
+     *
+     * See IAllocator::BufferDescriptorInfo for more information.
+     *
+     * @param device is the mapper device.
+     * @param bufferHandle is the buffer from which to get the dimensions.
+     * @return error is NONE upon success. Otherwise,
+     *                  BAD_BUFFER when the buffer handle is invalid.
+     * @return width is the width of the buffer in pixels.
+     * @return height is the height of the buffer in pixels.
+     */
+    typedef Error (*getDimensions)(Device* device,
+                                   const native_handle_t* bufferHandle,
+                                   uint32_t* outWidth,
+                                   uint32_t* outHeight);
+
+    /*
+     * Gets the format of the buffer.
+     *
+     * See IAllocator::BufferDescriptorInfo for more information.
+     *
+     * @param device is the mapper device.
+     * @param bufferHandle is the buffer from which to get format.
+     * @return error is NONE upon success. Otherwise,
+     *                  BAD_BUFFER when the buffer handle is invalid.
+     * @return format is the format of the buffer.
+     */
+    typedef Error (*getFormat)(Device* device,
+                               const native_handle_t* bufferHandle,
+                               PixelFormat* outFormat);
+
+    /*
+     * Gets the producer usage flags which were used to allocate this buffer.
+     *
+     * See IAllocator::BufferDescriptorInfo for more information.
+     *
+     * @param device is the mapper device.
+     * @param bufferHandle is the buffer from which to get the producer usage
+     *        flags.
+     * @return error is NONE upon success. Otherwise,
+     *                  BAD_BUFFER when the buffer handle is invalid.
+     * @return usageMask contains the producer usage flags of the buffer.
+     */
+    typedef Error (*getProducerUsageMask)(Device* device,
+                                          const native_handle_t* bufferHandle,
+                                          uint64_t* outUsageMask);
+
+    /*
+     * Gets the consumer usage flags which were used to allocate this buffer.
+     *
+     * See IAllocator::BufferDescriptorInfo for more information.
+     *
+     * @param device is the mapper device.
+     * @param bufferHandle is the buffer from which to get the consumer usage
+     *        flags.
+     * @return error is NONE upon success. Otherwise,
+     *                  BAD_BUFFER when the buffer handle is invalid.
+     * @return usageMask contains the consumer usage flags of the buffer.
+     */
+    typedef Error (*getConsumerUsageMask)(Device* device,
+                                          const native_handle_t* bufferHandle,
+                                          uint64_t* outUsageMask);
+
+    /*
+     * Gets a value that uniquely identifies the backing store of the given
+     * buffer.
+     *
+     * Buffers which share a backing store should return the same value from
+     * this function. If the buffer is present in more than one process, the
+     * backing store value for that buffer is not required to be the same in
+     * every process.
+     *
+     * @param device is the mapper device.
+     * @param bufferHandle is the buffer from which to get the backing store
+     *        identifier.
+     * @return error is NONE upon success. Otherwise,
+     *                  BAD_BUFFER when the buffer handle is invalid.
+     * @return store is the backing store identifier for this buffer.
+     */
+    typedef Error (*getBackingStore)(Device* device,
+                                     const native_handle_t* bufferHandle,
+                                     BackingStore* outStore);
+
+    /*
+     * Gets the stride of the buffer in pixels.
+     *
+     * The stride is the offset in pixel-sized elements between the same
+     * column in two adjacent rows of pixels. This may not be equal to the
+     * width of the buffer.
+     *
+     * @param device is the mapper device.
+     * @param bufferHandle is the buffer from which to get the stride.
+     * @return error is NONE upon success. Otherwise,
+     *                  BAD_BUFFER when the buffer handle is invalid.
+     *                  UNDEFINED when the notion of a stride is not
+     *                            meaningful for the buffer format.
+     * @return store is the stride in pixels.
+     */
+    typedef Error (*getStride)(Device* device,
+                               const native_handle_t* bufferHandle,
+                               uint32_t* outStride);
+
+    /*
+     * Returns the number of flex layout planes which are needed to represent
+     * the given buffer. This may be used to efficiently allocate only as many
+     * plane structures as necessary before calling into lockFlex.
+     *
+     * If the given buffer cannot be locked as a flex format, this function
+     * may return UNSUPPORTED (as lockFlex would).
+     *
+     * @param device is the mapper device.
+     * @param bufferHandle is the buffer for which the number of planes should
+     *        be queried.
+     * @return error is NONE upon success. Otherwise,
+     *                  BAD_BUFFER when the buffer handle is invalid.
+     *                  UNSUPPORTED when the buffer's format cannot be
+     *                              represented in a flex layout.
+     * @return numPlanes is the number of flex planes required to describe the
+     *         given buffer.
+     */
+    typedef Error (*getNumFlexPlanes)(Device* device,
+                                      const native_handle_t* bufferHandle,
+                                      uint32_t* outNumPlanes);
+
+    /*
+     * Locks the given buffer for the specified CPU usage.
+     *
+     * Exactly one of producerUsageMask and consumerUsageMask must be 0. The
+     * usage which is not 0 must be one of the *Usage::CPU* values, as
+     * applicable. Locking a buffer for a non-CPU usage is not supported.
+     *
+     * Locking the same buffer simultaneously from multiple threads is
+     * permitted, but if any of the threads attempt to lock the buffer for
+     * writing, the behavior is undefined, except that it must not cause
+     * process termination or block the client indefinitely. Leaving the
+     * buffer content in an indeterminate state or returning an error are both
+     * acceptable.
+     *
+     * The client must not modify the content of the buffer outside of
+     * accessRegion, and the device need not guarantee that content outside of
+     * accessRegion is valid for reading. The result of reading or writing
+     * outside of accessRegion is undefined, except that it must not cause
+     * process termination.
+     *
+     * data will be filled with a pointer to the locked buffer memory. This
+     * address will represent the top-left corner of the entire buffer, even
+     * if accessRegion does not begin at the top-left corner.
+     *
+     * acquireFence is a file descriptor referring to a acquire sync fence
+     * object, which will be signaled when it is safe for the device to access
+     * the contents of the buffer (prior to locking). If it is already safe to
+     * access the buffer contents, -1 may be passed instead.
+     *
+     * @param device is the mapper device.
+     * @param bufferHandle is the buffer to lock.
+     * @param producerUsageMask contains the producer usage flags to request;
+     *        either this or consumerUsagemask must be 0, and the other must
+     *        be a CPU usage.
+     * @param consumerUsageMask contains the consumer usage flags to request;
+     *        either this or producerUsageMask must be 0, and the other must
+     *        be a CPU usage.
+     * @param accessRegion is the portion of the buffer that the client
+     *        intends to access.
+     * @param acquireFence is a sync fence file descriptor as described above.
+     * @return error is NONE upon success. Otherwise,
+     *                  BAD_BUFFER when the buffer handle is invalid.
+     *                  BAD_VALUE when neither or both of producerUsageMask
+     *                            and consumerUsageMask were 0, or the usage
+     *                            which was not 0 was not a CPU usage.
+     *                  NO_RESOURCES when the buffer cannot be locked at this
+     *                               time, but locking may succeed at a future
+     *                               time.
+     *                  UNSUPPORTED when the buffer cannot be locked with the
+     *                              given usage, and any future attempts at
+     *                              locking will also fail.
+     * @return data will be filled with a CPU-accessible pointer to the buffer
+     *         data.
+     */
+    typedef Error (*lock)(Device* device,
+                          const native_handle_t* bufferHandle,
+                          uint64_t producerUsageMask,
+                          uint64_t consumerUsageMask,
+                          const Rect* accessRegion,
+                          int32_t acquireFence,
+                          void** outData);
+
+    /*
+     * This is largely the same as lock(), except that instead of returning a
+     * pointer directly to the buffer data, it returns an FlexLayout struct
+     * describing how to access the data planes.
+     *
+     * This function must work on buffers with PixelFormat::YCbCr_*_888 if
+     * supported by the device, as well as with any other formats requested by
+     * multimedia codecs when they are configured with a
+     * flexible-YUV-compatible color format.
+     *
+     * This function may also be called on buffers of other formats, including
+     * non-YUV formats, but if the buffer format is not compatible with a
+     * flexible representation, it may return UNSUPPORTED.
+     *
+     * @param device is the mapper device.
+     * @param bufferHandle is the buffer to lock.
+     * @param producerUsageMask contains the producer usage flags to request;
+     *        either this or consumerUsagemask must be 0, and the other must
+     *        be a CPU usage.
+     * @param consumerUsageMask contains the consumer usage flags to request;
+     *        either this or producerUsageMask must be 0, and the other must
+     *        be a CPU usage.
+     * @param accessRegion is the portion of the buffer that the client
+     *        intends to access.
+     * @param acquireFence is a sync fence file descriptor as described in
+     *        lock().
+     * @return error is NONE upon success. Otherwise,
+     *                  BAD_BUFFER when the buffer handle is invalid.
+     *                  BAD_VALUE when neither or both of producerUsageMask
+     *                            and consumerUsageMask were 0, or the usage
+     *                            which was not 0 was not a CPU usage.
+     *                  NO_RESOURCES when the buffer cannot be locked at this
+     *                               time, but locking may succeed at a future
+     *                               time.
+     *                  UNSUPPORTED when the buffer cannot be locked with the
+     *                              given usage, and any future attempts at
+     *                              locking will also fail.
+     * @return flexLayout will be filled with the description of the planes in
+     *         the buffer.
+     */
+    typedef Error (*lockFlex)(Device* device,
+                              const native_handle_t* bufferHandle,
+                              uint64_t producerUsageMask,
+                              uint64_t consumerUsageMask,
+                              const Rect* accessRegion,
+                              int32_t acquireFence,
+                              FlexLayout* outFlexLayout);
+
+    /*
+     * This function indicates to the device that the client will be done with
+     * the buffer when releaseFence signals.
+     *
+     * releaseFence will be filled with a file descriptor referring to a
+     * release sync fence object, which will be signaled when it is safe to
+     * access the contents of the buffer (after the buffer has been unlocked).
+     * If it is already safe to access the buffer contents, then -1 may be
+     * returned instead.
+     *
+     * This function is used to unlock both buffers locked by lock() and those
+     * locked by lockFlex().
+     *
+     * @param device is the mapper device.
+     * @param bufferHandle is the buffer to unlock.
+     * @return error is NONE upon success. Otherwise,
+     *                  BAD_BUFFER when the buffer handle is invalid.
+     * @return releaseFence is a sync fence file descriptor as described
+     *         above.
+     */
+    typedef Error (*unlock)(Device* device,
+                            const native_handle_t* bufferHandle,
+                            int32_t* outReleaseFence);
+};
+static_assert(std::is_pod<Device>::value, "Device is not POD");
+
+struct IMapper {
+    Device::createDevice createDevice;
+    Device::destroyDevice destroyDevice;
+
+    Device::retain retain;
+    Device::release release;
+    Device::getDimensions getDimensions;
+    Device::getFormat getFormat;
+    Device::getProducerUsageMask getProducerUsageMask;
+    Device::getConsumerUsageMask getConsumerUsageMask;
+    Device::getBackingStore getBackingStore;
+    Device::getStride getStride;
+    Device::getNumFlexPlanes getNumFlexPlanes;
+    Device::lock lock;
+    Device::lockFlex lockFlex;
+    Device::unlock unlock;
+};
+static_assert(std::is_pod<IMapper>::value, "IMapper is not POD");
+
+} // namespace V2_0
+} // namespace mapper
+} // namespace graphics
+} // namespace hardware
+} // namespace android
+
+const void* HALLIB_FETCH_Interface(const char* name);
+
+} // extern "C"
+
+#endif /* ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_IMAPPER_H */
diff --git a/graphics/mapper/2.0/default/Android.bp b/graphics/mapper/2.0/default/Android.bp
new file mode 100644
index 0000000..b738ae8
--- /dev/null
+++ b/graphics/mapper/2.0/default/Android.bp
@@ -0,0 +1,28 @@
+// 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.graphics.mapper.hallib",
+    relative_install_path: "hw",
+    srcs: ["GrallocMapper.cpp"],
+    cppflags: ["-Wall", "-Wextra"],
+    static_libs: ["android.hardware.graphics.mapper@2.0"],
+    shared_libs: [
+        "android.hardware.graphics.allocator@2.0",
+        "libhardware",
+        "libhidl",
+        "libhwbinder",
+        "liblog",
+    ],
+}
diff --git a/graphics/mapper/2.0/default/GrallocMapper.cpp b/graphics/mapper/2.0/default/GrallocMapper.cpp
new file mode 100644
index 0000000..eeca5c7
--- /dev/null
+++ b/graphics/mapper/2.0/default/GrallocMapper.cpp
@@ -0,0 +1,373 @@
+/*
+ * Copyright 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 "GrallocMapperPassthrough"
+
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <hardware/gralloc1.h>
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace mapper {
+namespace V2_0 {
+namespace implementation {
+
+class GrallocDevice : public Device {
+public:
+    GrallocDevice();
+    ~GrallocDevice();
+
+    // IMapper interface
+    Error retain(const native_handle_t* bufferHandle);
+    Error release(const native_handle_t* bufferHandle);
+    Error getDimensions(const native_handle_t* bufferHandle,
+            uint32_t* outWidth, uint32_t* outHeight);
+    Error getFormat(const native_handle_t* bufferHandle,
+            PixelFormat* outFormat);
+    Error getProducerUsageMask(const native_handle_t* bufferHandle,
+            uint64_t* outUsageMask);
+    Error getConsumerUsageMask(const native_handle_t* bufferHandle,
+            uint64_t* outUsageMask);
+    Error getBackingStore(const native_handle_t* bufferHandle,
+            BackingStore* outStore);
+    Error getStride(const native_handle_t* bufferHandle, uint32_t* outStride);
+    Error getNumFlexPlanes(const native_handle_t* bufferHandle,
+            uint32_t* outNumPlanes);
+    Error lock(const native_handle_t* bufferHandle,
+            uint64_t producerUsageMask, uint64_t consumerUsageMask,
+            const Rect* accessRegion, int32_t acquireFence, void** outData);
+    Error lockFlex(const native_handle_t* bufferHandle,
+            uint64_t producerUsageMask, uint64_t consumerUsageMask,
+            const Rect* accessRegion, int32_t acquireFence,
+            FlexLayout* outFlexLayout);
+    Error unlock(const native_handle_t* bufferHandle,
+            int32_t* outReleaseFence);
+
+private:
+    void initDispatch();
+
+    gralloc1_device_t* mDevice;
+
+    struct {
+        GRALLOC1_PFN_RETAIN retain;
+        GRALLOC1_PFN_RELEASE release;
+        GRALLOC1_PFN_GET_DIMENSIONS getDimensions;
+        GRALLOC1_PFN_GET_FORMAT getFormat;
+        GRALLOC1_PFN_GET_PRODUCER_USAGE getProducerUsage;
+        GRALLOC1_PFN_GET_CONSUMER_USAGE getConsumerUsage;
+        GRALLOC1_PFN_GET_BACKING_STORE getBackingStore;
+        GRALLOC1_PFN_GET_STRIDE getStride;
+        GRALLOC1_PFN_GET_NUM_FLEX_PLANES getNumFlexPlanes;
+        GRALLOC1_PFN_LOCK lock;
+        GRALLOC1_PFN_LOCK_FLEX lockFlex;
+        GRALLOC1_PFN_UNLOCK unlock;
+    } mDispatch;
+};
+
+GrallocDevice::GrallocDevice()
+{
+    const hw_module_t* module;
+    int status = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
+    if (status) {
+        LOG_ALWAYS_FATAL("failed to get gralloc module");
+    }
+
+    uint8_t major = (module->module_api_version >> 8) & 0xff;
+    if (major != 1) {
+        LOG_ALWAYS_FATAL("unknown gralloc module major version %d", major);
+    }
+
+    status = gralloc1_open(module, &mDevice);
+    if (status) {
+        LOG_ALWAYS_FATAL("failed to open gralloc1 device");
+    }
+
+    initDispatch();
+}
+
+GrallocDevice::~GrallocDevice()
+{
+    gralloc1_close(mDevice);
+}
+
+void GrallocDevice::initDispatch()
+{
+#define CHECK_FUNC(func, desc) do {                                   \
+    mDispatch.func = reinterpret_cast<decltype(mDispatch.func)>(      \
+        mDevice->getFunction(mDevice, desc));                         \
+    if (!mDispatch.func) {                                            \
+        LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc); \
+    }                                                                 \
+} while (0)
+
+    CHECK_FUNC(retain, GRALLOC1_FUNCTION_RETAIN);
+    CHECK_FUNC(release, GRALLOC1_FUNCTION_RELEASE);
+    CHECK_FUNC(getDimensions, GRALLOC1_FUNCTION_GET_DIMENSIONS);
+    CHECK_FUNC(getFormat, GRALLOC1_FUNCTION_GET_FORMAT);
+    CHECK_FUNC(getProducerUsage, GRALLOC1_FUNCTION_GET_PRODUCER_USAGE);
+    CHECK_FUNC(getConsumerUsage, GRALLOC1_FUNCTION_GET_CONSUMER_USAGE);
+    CHECK_FUNC(getBackingStore, GRALLOC1_FUNCTION_GET_BACKING_STORE);
+    CHECK_FUNC(getStride, GRALLOC1_FUNCTION_GET_STRIDE);
+    CHECK_FUNC(getNumFlexPlanes, GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES);
+    CHECK_FUNC(lock, GRALLOC1_FUNCTION_LOCK);
+    CHECK_FUNC(lockFlex, GRALLOC1_FUNCTION_LOCK_FLEX);
+    CHECK_FUNC(unlock, GRALLOC1_FUNCTION_UNLOCK);
+
+#undef CHECK_FUNC
+}
+
+Error GrallocDevice::retain(const native_handle_t* bufferHandle)
+{
+    int32_t error = mDispatch.retain(mDevice, bufferHandle);
+    return static_cast<Error>(error);
+}
+
+Error GrallocDevice::release(const native_handle_t* bufferHandle)
+{
+    int32_t error = mDispatch.release(mDevice, bufferHandle);
+    return static_cast<Error>(error);
+}
+
+Error GrallocDevice::getDimensions(const native_handle_t* bufferHandle,
+        uint32_t* outWidth, uint32_t* outHeight)
+{
+    int32_t error = mDispatch.getDimensions(mDevice, bufferHandle,
+            outWidth, outHeight);
+    return static_cast<Error>(error);
+}
+
+Error GrallocDevice::getFormat(const native_handle_t* bufferHandle,
+        PixelFormat* outFormat)
+{
+    int32_t error = mDispatch.getFormat(mDevice, bufferHandle,
+            reinterpret_cast<int32_t*>(outFormat));
+    return static_cast<Error>(error);
+}
+
+Error GrallocDevice::getProducerUsageMask(const native_handle_t* bufferHandle,
+        uint64_t* outUsageMask)
+{
+    int32_t error = mDispatch.getProducerUsage(mDevice, bufferHandle,
+            outUsageMask);
+    return static_cast<Error>(error);
+}
+
+Error GrallocDevice::getConsumerUsageMask(const native_handle_t* bufferHandle,
+        uint64_t* outUsageMask)
+{
+    int32_t error = mDispatch.getConsumerUsage(mDevice, bufferHandle,
+            outUsageMask);
+    return static_cast<Error>(error);
+}
+
+Error GrallocDevice::getBackingStore(const native_handle_t* bufferHandle,
+        BackingStore* outStore)
+{
+    int32_t error = mDispatch.getBackingStore(mDevice, bufferHandle,
+            outStore);
+    return static_cast<Error>(error);
+}
+
+Error GrallocDevice::getStride(const native_handle_t* bufferHandle,
+        uint32_t* outStride)
+{
+    int32_t error = mDispatch.getStride(mDevice, bufferHandle, outStride);
+    return static_cast<Error>(error);
+}
+
+Error GrallocDevice::getNumFlexPlanes(const native_handle_t* bufferHandle,
+        uint32_t* outNumPlanes)
+{
+    int32_t error = mDispatch.getNumFlexPlanes(mDevice, bufferHandle,
+            outNumPlanes);
+    return static_cast<Error>(error);
+}
+
+Error GrallocDevice::lock(const native_handle_t* bufferHandle,
+        uint64_t producerUsageMask, uint64_t consumerUsageMask,
+        const Rect* accessRegion, int32_t acquireFence,
+        void** outData)
+{
+    int32_t error = mDispatch.lock(mDevice, bufferHandle,
+            producerUsageMask, consumerUsageMask,
+            reinterpret_cast<const gralloc1_rect_t*>(accessRegion),
+            outData, acquireFence);
+    return static_cast<Error>(error);
+}
+
+Error GrallocDevice::lockFlex(const native_handle_t* bufferHandle,
+        uint64_t producerUsageMask, uint64_t consumerUsageMask,
+        const Rect* accessRegion, int32_t acquireFence,
+        FlexLayout* outFlexLayout)
+{
+    int32_t error = mDispatch.lockFlex(mDevice, bufferHandle,
+            producerUsageMask, consumerUsageMask,
+            reinterpret_cast<const gralloc1_rect_t*>(accessRegion),
+            reinterpret_cast<android_flex_layout_t*>(outFlexLayout),
+            acquireFence);
+    return static_cast<Error>(error);
+}
+
+Error GrallocDevice::unlock(const native_handle_t* bufferHandle,
+        int32_t* outReleaseFence)
+{
+    int32_t error = mDispatch.unlock(mDevice, bufferHandle, outReleaseFence);
+    return static_cast<Error>(error);
+}
+
+class GrallocMapper : public IMapper {
+public:
+    GrallocMapper() : IMapper{
+        .createDevice = createDevice,
+        .destroyDevice = destroyDevice,
+        .retain = retain,
+        .release = release,
+        .getDimensions = getDimensions,
+        .getFormat = getFormat,
+        .getProducerUsageMask = getProducerUsageMask,
+        .getConsumerUsageMask = getConsumerUsageMask,
+        .getBackingStore = getBackingStore,
+        .getStride = getStride,
+        .getNumFlexPlanes = getNumFlexPlanes,
+        .lock = lock,
+        .lockFlex = lockFlex,
+        .unlock = unlock,
+    } {}
+
+    const IMapper* getInterface() const
+    {
+        return static_cast<const IMapper*>(this);
+    }
+
+private:
+    static GrallocDevice* cast(Device* device)
+    {
+        return reinterpret_cast<GrallocDevice*>(device);
+    }
+
+    static Error createDevice(Device** outDevice)
+    {
+        *outDevice = new GrallocDevice;
+        return Error::NONE;
+    }
+
+    static Error destroyDevice(Device* device)
+    {
+        delete cast(device);
+        return Error::NONE;
+    }
+
+    static Error retain(Device* device,
+            const native_handle_t* bufferHandle)
+    {
+        return cast(device)->retain(bufferHandle);
+    }
+
+    static Error release(Device* device,
+            const native_handle_t* bufferHandle)
+    {
+        return cast(device)->release(bufferHandle);
+    }
+
+    static Error getDimensions(Device* device,
+            const native_handle_t* bufferHandle,
+            uint32_t* outWidth, uint32_t* outHeight)
+    {
+        return cast(device)->getDimensions(bufferHandle, outWidth, outHeight);
+    }
+
+    static Error getFormat(Device* device,
+            const native_handle_t* bufferHandle, PixelFormat* outFormat)
+    {
+        return cast(device)->getFormat(bufferHandle, outFormat);
+    }
+
+    static Error getProducerUsageMask(Device* device,
+            const native_handle_t* bufferHandle, uint64_t* outUsageMask)
+    {
+        return cast(device)->getProducerUsageMask(bufferHandle, outUsageMask);
+    }
+
+    static Error getConsumerUsageMask(Device* device,
+            const native_handle_t* bufferHandle, uint64_t* outUsageMask)
+    {
+        return cast(device)->getConsumerUsageMask(bufferHandle, outUsageMask);
+    }
+
+    static Error getBackingStore(Device* device,
+            const native_handle_t* bufferHandle, BackingStore* outStore)
+    {
+        return cast(device)->getBackingStore(bufferHandle, outStore);
+    }
+
+    static Error getStride(Device* device,
+            const native_handle_t* bufferHandle, uint32_t* outStride)
+    {
+        return cast(device)->getStride(bufferHandle, outStride);
+    }
+
+    static Error getNumFlexPlanes(Device* device,
+            const native_handle_t* bufferHandle, uint32_t* outNumPlanes)
+    {
+        return cast(device)->getNumFlexPlanes(bufferHandle, outNumPlanes);
+    }
+
+    static Error lock(Device* device,
+            const native_handle_t* bufferHandle,
+            uint64_t producerUsageMask, uint64_t consumerUsageMask,
+            const Device::Rect* accessRegion, int32_t acquireFence,
+            void** outData)
+    {
+        return cast(device)->lock(bufferHandle,
+                producerUsageMask, consumerUsageMask,
+                accessRegion, acquireFence, outData);
+    }
+
+    static Error lockFlex(Device* device,
+            const native_handle_t* bufferHandle,
+            uint64_t producerUsageMask, uint64_t consumerUsageMask,
+            const Device::Rect* accessRegion, int32_t acquireFence,
+            FlexLayout* outFlexLayout)
+    {
+        return cast(device)->lockFlex(bufferHandle,
+                producerUsageMask, consumerUsageMask,
+                accessRegion, acquireFence, outFlexLayout);
+    }
+
+    static Error unlock(Device* device,
+            const native_handle_t* bufferHandle, int32_t* outReleaseFence)
+    {
+        return cast(device)->unlock(bufferHandle, outReleaseFence);
+    }
+};
+
+extern "C" const void* HALLIB_FETCH_Interface(const char* name)
+{
+    if (strcmp(name, "android.hardware.graphics.mapper@2.0::IMapper") == 0) {
+        static GrallocMapper sGrallocMapper;
+        return sGrallocMapper.getInterface();
+    }
+
+    return nullptr;
+}
+
+} // namespace implementation
+} // namespace V2_0
+} // namespace mapper
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/mapper/2.0/types.h b/graphics/mapper/2.0/types.h
new file mode 100644
index 0000000..63a6b16
--- /dev/null
+++ b/graphics/mapper/2.0/types.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright 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_GRAPHICS_MAPPER_V2_0_TYPES_H
+#define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_TYPES_H
+
+#include <type_traits>
+
+#include <android/hardware/graphics/allocator/2.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace mapper {
+namespace V2_0 {
+
+using android::hardware::graphics::allocator::V2_0::Error;
+using android::hardware::graphics::allocator::V2_0::PixelFormat;
+using android::hardware::graphics::allocator::V2_0::ProducerUsage;
+using android::hardware::graphics::allocator::V2_0::ConsumerUsage;
+
+/*
+ * Structures for describing flexible YUVA/RGBA formats for consumption by
+ * applications. Such flexible formats contain a plane for each component
+ * (e.g.  red, green, blue), where each plane is laid out in a grid-like
+ * pattern occupying unique byte addresses and with consistent byte offsets
+ * between neighboring pixels.
+ *
+ * The FlexLayout structure is used with any pixel format that can be
+ * represented by it, such as:
+ *
+ *  - PixelFormat::YCbCr_*_888
+ *  - PixelFormat::FLEX_RGB*_888
+ *  - PixelFormat::RGB[AX]_888[8],BGRA_8888,RGB_888
+ *  - PixelFormat::YV12,Y8,Y16,YCbCr_422_SP/I,YCrCb_420_SP
+ *  - even implementation defined formats that can be represented by the
+ *    structures
+ *
+ * Vertical increment (aka. row increment or stride) describes the distance in
+ * bytes from the first pixel of one row to the first pixel of the next row
+ * (below) for the component plane. This can be negative.
+ *
+ * Horizontal increment (aka. column or pixel increment) describes the
+ * distance in bytes from one pixel to the next pixel (to the right) on the
+ * same row for the component plane. This can be negative.
+ *
+ * Each plane can be subsampled either vertically or horizontally by a
+ * power-of-two factor.
+ *
+ * The bit-depth of each component can be arbitrary, as long as the pixels are
+ * laid out on whole bytes, in native byte-order, using the most significant
+ * bits of each unit.
+ */
+
+enum class FlexComponent : int32_t {
+    Y          = 1 << 0,  /* luma */
+    Cb         = 1 << 1,  /* chroma blue */
+    Cr         = 1 << 2,  /* chroma red */
+
+    R          = 1 << 10, /* red */
+    G          = 1 << 11, /* green */
+    B          = 1 << 12, /* blue */
+
+    A          = 1 << 30, /* alpha */
+};
+
+inline FlexComponent operator|(FlexComponent lhs, FlexComponent rhs)
+{
+    return static_cast<FlexComponent>(static_cast<int32_t>(lhs) |
+                                      static_cast<int32_t>(rhs));
+}
+
+inline FlexComponent& operator|=(FlexComponent &lhs, FlexComponent rhs)
+{
+    lhs = static_cast<FlexComponent>(static_cast<int32_t>(lhs) |
+                                     static_cast<int32_t>(rhs));
+    return lhs;
+}
+
+enum class FlexFormat : int32_t {
+    /* not a flexible format */
+    INVALID    = 0x0,
+
+    Y          = static_cast<int32_t>(FlexComponent::Y),
+    YCbCr      = static_cast<int32_t>(FlexComponent::Y) |
+                 static_cast<int32_t>(FlexComponent::Cb) |
+                 static_cast<int32_t>(FlexComponent::Cr),
+    YCbCrA     = static_cast<int32_t>(YCbCr) |
+                 static_cast<int32_t>(FlexComponent::A),
+    RGB        = static_cast<int32_t>(FlexComponent::R) |
+                 static_cast<int32_t>(FlexComponent::G) |
+                 static_cast<int32_t>(FlexComponent::B),
+    RGBA       = static_cast<int32_t>(RGB) |
+                 static_cast<int32_t>(FlexComponent::A),
+};
+
+struct FlexPlane {
+    /* pointer to the first byte of the top-left pixel of the plane. */
+    uint8_t *topLeft;
+
+    FlexComponent component;
+
+    /*
+     * bits allocated for the component in each pixel. Must be a positive
+     * multiple of 8.
+     */
+    int32_t bitsPerComponent;
+
+    /*
+     * number of the most significant bits used in the format for this
+     * component. Must be between 1 and bits_per_component, inclusive.
+     */
+    int32_t bitsUsed;
+
+    /* horizontal increment */
+    int32_t hIncrement;
+    /* vertical increment */
+    int32_t vIncrement;
+
+    /* horizontal subsampling. Must be a positive power of 2. */
+    int32_t hSubsampling;
+    /* vertical subsampling. Must be a positive power of 2. */
+    int32_t vSubsampling;
+};
+static_assert(std::is_pod<FlexPlane>::value, "FlexPlane is not POD");
+
+struct FlexLayout {
+    /* the kind of flexible format */
+    FlexFormat format;
+
+    /* number of planes; 0 for FLEX_FORMAT_INVALID */
+    uint32_t numPlanes;
+
+    /*
+     * a plane for each component; ordered in increasing component value order.
+     * E.g. FLEX_FORMAT_RGBA maps 0 -> R, 1 -> G, etc.
+     * Can be NULL for FLEX_FORMAT_INVALID
+     */
+    FlexPlane* planes;
+};
+static_assert(std::is_pod<FlexLayout>::value, "FlexLayout is not POD");
+
+typedef uint64_t BackingStore;
+
+} // namespace V2_0
+} // namespace mapper
+} // namespace graphics
+} // namespace hardware
+} // namespace android
+
+#endif /* ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_TYPES_H */
diff --git a/soundtrigger/2.0/Android.bp b/soundtrigger/2.0/Android.bp
new file mode 100644
index 0000000..10a917b
--- /dev/null
+++ b/soundtrigger/2.0/Android.bp
@@ -0,0 +1,55 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+genrule {
+    name: "android.hardware.soundtrigger@2.0_genc++",
+    tool: "hidl-gen",
+    cmd: "$tool -o $genDir -Lc++ -randroid.hardware:hardware/interfaces android.hardware.soundtrigger@2.0",
+    srcs: [
+        "types.hal",
+        "ISoundTriggerHw.hal",
+        "ISoundTriggerHwCallback.hal",
+    ],
+    out: [
+        "android/hardware/soundtrigger/2.0/types.cpp",
+        "android/hardware/soundtrigger/2.0/SoundTriggerHwAll.cpp",
+        "android/hardware/soundtrigger/2.0/SoundTriggerHwCallbackAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.hardware.soundtrigger@2.0_genc++_headers",
+    tool: "hidl-gen",
+    cmd: "$tool -o $genDir -Lc++ -randroid.hardware:hardware/interfaces android.hardware.soundtrigger@2.0",
+    srcs: [
+        "types.hal",
+        "ISoundTriggerHw.hal",
+        "ISoundTriggerHwCallback.hal",
+    ],
+    out: [
+        "android/hardware/soundtrigger/2.0/types.h",
+        "android/hardware/soundtrigger/2.0/ISoundTriggerHw.h",
+        "android/hardware/soundtrigger/2.0/IHwSoundTriggerHw.h",
+        "android/hardware/soundtrigger/2.0/BnSoundTriggerHw.h",
+        "android/hardware/soundtrigger/2.0/BpSoundTriggerHw.h",
+        "android/hardware/soundtrigger/2.0/BsSoundTriggerHw.h",
+        "android/hardware/soundtrigger/2.0/ISoundTriggerHwCallback.h",
+        "android/hardware/soundtrigger/2.0/IHwSoundTriggerHwCallback.h",
+        "android/hardware/soundtrigger/2.0/BnSoundTriggerHwCallback.h",
+        "android/hardware/soundtrigger/2.0/BpSoundTriggerHwCallback.h",
+        "android/hardware/soundtrigger/2.0/BsSoundTriggerHwCallback.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.hardware.soundtrigger@2.0",
+    generated_sources: ["android.hardware.soundtrigger@2.0_genc++"],
+    generated_headers: ["android.hardware.soundtrigger@2.0_genc++_headers"],
+    export_generated_headers: ["android.hardware.soundtrigger@2.0_genc++_headers"],
+    shared_libs: [
+        "libhidl",
+        "libhwbinder",
+        "libutils",
+        "libcutils",
+        "android.hardware.audio.common@2.0",
+    ],
+}
diff --git a/soundtrigger/2.0/Android.mk b/soundtrigger/2.0/Android.mk
new file mode 100644
index 0000000..1e3f036
--- /dev/null
+++ b/soundtrigger/2.0/Android.mk
@@ -0,0 +1,254 @@
+# This file is autogenerated by hidl-gen. Do not edit manually.
+
+LOCAL_PATH := $(call my-dir)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.soundtrigger@2.0-java
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(local-generated-sources-dir)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_JAVA_LIBRARIES := \
+    android.hardware.audio.common@2.0-java \
+
+
+#
+# Build types.hal (ConfidenceLevel)
+#
+GEN := $(intermediates)/android/hardware/soundtrigger/2.0/ConfidenceLevel.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.soundtrigger@2.0::types.ConfidenceLevel
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (PhraseRecognitionExtra)
+#
+GEN := $(intermediates)/android/hardware/soundtrigger/2.0/PhraseRecognitionExtra.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.soundtrigger@2.0::types.PhraseRecognitionExtra
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (RecognitionMode)
+#
+GEN := $(intermediates)/android/hardware/soundtrigger/2.0/RecognitionMode.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.soundtrigger@2.0::types.RecognitionMode
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (SoundModelType)
+#
+GEN := $(intermediates)/android/hardware/soundtrigger/2.0/SoundModelType.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.soundtrigger@2.0::types.SoundModelType
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build ISoundTriggerHw.hal
+#
+GEN := $(intermediates)/android/hardware/soundtrigger/2.0/ISoundTriggerHw.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/ISoundTriggerHw.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/ISoundTriggerHwCallback.hal
+$(GEN): $(LOCAL_PATH)/ISoundTriggerHwCallback.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.soundtrigger@2.0::ISoundTriggerHw
+
+$(GEN): $(LOCAL_PATH)/ISoundTriggerHw.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build ISoundTriggerHwCallback.hal
+#
+GEN := $(intermediates)/android/hardware/soundtrigger/2.0/ISoundTriggerHwCallback.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/ISoundTriggerHwCallback.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.soundtrigger@2.0::ISoundTriggerHwCallback
+
+$(GEN): $(LOCAL_PATH)/ISoundTriggerHwCallback.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_JAVA_LIBRARY)
+
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.soundtrigger@2.0-java-static
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(local-generated-sources-dir)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android.hardware.audio.common@2.0-java-static \
+
+
+#
+# Build types.hal (ConfidenceLevel)
+#
+GEN := $(intermediates)/android/hardware/soundtrigger/2.0/ConfidenceLevel.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.soundtrigger@2.0::types.ConfidenceLevel
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (PhraseRecognitionExtra)
+#
+GEN := $(intermediates)/android/hardware/soundtrigger/2.0/PhraseRecognitionExtra.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.soundtrigger@2.0::types.PhraseRecognitionExtra
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (RecognitionMode)
+#
+GEN := $(intermediates)/android/hardware/soundtrigger/2.0/RecognitionMode.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.soundtrigger@2.0::types.RecognitionMode
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build types.hal (SoundModelType)
+#
+GEN := $(intermediates)/android/hardware/soundtrigger/2.0/SoundModelType.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.soundtrigger@2.0::types.SoundModelType
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build ISoundTriggerHw.hal
+#
+GEN := $(intermediates)/android/hardware/soundtrigger/2.0/ISoundTriggerHw.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/ISoundTriggerHw.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/ISoundTriggerHwCallback.hal
+$(GEN): $(LOCAL_PATH)/ISoundTriggerHwCallback.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.soundtrigger@2.0::ISoundTriggerHw
+
+$(GEN): $(LOCAL_PATH)/ISoundTriggerHw.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
+# Build ISoundTriggerHwCallback.hal
+#
+GEN := $(intermediates)/android/hardware/soundtrigger/2.0/ISoundTriggerHwCallback.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/ISoundTriggerHwCallback.hal
+$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava -randroid.hardware:hardware/interfaces \
+        android.hardware.soundtrigger@2.0::ISoundTriggerHwCallback
+
+$(GEN): $(LOCAL_PATH)/ISoundTriggerHwCallback.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/soundtrigger/2.0/ISoundTriggerHw.hal b/soundtrigger/2.0/ISoundTriggerHw.hal
new file mode 100644
index 0000000..a1be85d
--- /dev/null
+++ b/soundtrigger/2.0/ISoundTriggerHw.hal
@@ -0,0 +1,215 @@
+/*
+ * Copyright 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.soundtrigger@2.0;
+
+import android.hardware.audio.common@2.0;
+
+import ISoundTriggerHwCallback;
+
+interface ISoundTriggerHw {
+
+    /*
+     * Sound trigger implementation descriptor read by the framework via
+     * getProperties(). Used by SoundTrigger service to report to applications
+     * and manage concurrency and policy.
+     */
+    struct Properties {
+        /* Implementor name */
+        string   implementor;
+        /* Implementation description */
+        string   description;
+        /* Implementation version */
+        uint32_t version;
+        /* Unique implementation ID. The UUID must change with each version of
+           the engine implementation */
+        Uuid     uuid;
+        /* Maximum number of concurrent sound models loaded */
+        uint32_t maxSoundModels;
+        /* Maximum number of key phrases */
+        uint32_t maxKeyPhrases;
+        /* Maximum number of concurrent users detected */
+        uint32_t maxUsers;
+        /* All supported modes. e.g RecognitionMode.VOICE_TRIGGER */
+        uint32_t recognitionModes;
+        /* Supports seamless transition from detection to capture */
+        bool     captureTransition;
+        /* Maximum buffering capacity in ms if captureTransition is true */
+        uint32_t maxBufferMs;
+        /* Supports capture by other use cases while detection is active */
+        bool     concurrentCapture;
+        /* Returns the trigger capture in event */
+        bool     triggerInEvent;
+        /* Rated power consumption when detection is active with TDB
+         * silence/sound/speech ratio */
+        uint32_t powerConsumptionMw;
+    };
+
+
+    /*
+     * Base sound model descriptor. This struct is the header of a larger block
+     * passed to loadSoundModel() and contains the binary data of the
+     * sound model.
+     */
+    struct SoundModel {
+        /* Model type. e.g. SoundModelType.KEYPHRASE */
+        SoundModelType type;
+        /* Unique sound model ID. */
+        Uuid           uuid;
+        /* Unique vendor ID. Identifies the engine the sound model
+         * was build for */
+        Uuid           vendorUuid;
+        /* Opaque data transparent to Android framework */
+        vec<uint8_t>   data;
+    };
+
+    /* Key phrase descriptor */
+    struct Phrase {
+        /* Unique keyphrase ID assigned at enrollment time */
+        uint32_t      id;
+        /* Recognition modes supported by this key phrase */
+        uint32_t      recognitionModes;
+        /* List of users IDs associated with this key phrase */
+        vec<uint32_t> users;
+        /* Locale - Java Locale style (e.g. en_US) */
+        string        locale;
+        /* Phrase text in UTF-8 format. */
+        string        text;
+    };
+
+    /*
+     * Specialized sound model for key phrase detection.
+     * Proprietary representation of key phrases in binary data must match
+     * information indicated by phrases field
+     */
+    struct PhraseSoundModel {
+        /* Common part of sound model descriptor */
+        SoundModel  common;
+        /* List of descriptors for key phrases supported by this sound model */
+        vec<Phrase> phrases;
+    };
+
+    /*
+     * Configuration for sound trigger capture session passed to
+     * startRecognition() method
+     */
+    struct RecognitionConfig {
+        /* IO handle that will be used for capture. N/A if captureRequested
+         * is false */
+        AudioIoHandle   captureHandle;
+        /* Input device requested for detection capture */
+        AudioDevice     captureDevice;
+        /* Capture and buffer audio for this recognition instance */
+        bool            captureRequested;
+        /* Configuration for each key phrase */
+        vec<PhraseRecognitionExtra> phrases;
+        /* Opaque capture configuration data transparent to the framework */
+        vec<uint8_t>    data;
+    };
+
+
+    /*
+     * Retrieve implementation properties.
+     * @return retval Operation completion status: 0 in case of success,
+     *                -ENODEV in case of initialization error.
+     * @return properties A Properties structure containing implementation
+     *                    description and capabilities.
+     */
+    getProperties() generates (int32_t retval, Properties properties);
+
+    /*
+     * Load a sound model. Once loaded, recognition of this model can be
+     * started and stopped. Only one active recognition per model at a time.
+     * The SoundTrigger service must handle concurrent recognition requests by
+     * different users/applications on the same model.
+     * The implementation returns a unique handle used by other functions
+     * (unloadSoundModel(), startRecognition(), etc...
+     * @param soundModel A SoundModel structure describing the sound model to
+     *                   load.
+     * @param callback The callback interface on which the soundmodelCallback()
+     *                 method will be called upon completion.
+     * @param cookie The value of the cookie argument passed to the completion
+     *               callback. This unique context information is assigned and
+     *               used only by the framework.
+     * @return retval Operation completion status: 0 in case of success,
+     *                -EINVAL in case of invalid sound model (e.g 0 data size),
+     *                -ENOSYS in case of invalid operation (e.g max number of
+     *                models exceeded),
+     *                -ENOMEM in case of memory allocation failure,
+     *                -ENODEV in case of initialization error.
+     * @return modelHandle A unique handle assigned by the HAL for use by the
+     *                framework when controlling activity for this sound model.
+     */
+    loadSoundModel(SoundModel soundModel,
+                   ISoundTriggerHwCallback callback,
+                   CallbackCookie cookie)
+            generates (int32_t retval, SoundModelHandle modelHandle);
+
+    /*
+     * Unload a sound model. A sound model may be unloaded to make room for a
+     * new one to overcome implementation limitations.
+     * @param modelHandle the handle of the sound model to unload
+     * @return retval Operation completion status: 0 in case of success,
+     *                -ENOSYS if the model is not loaded,
+     *                -ENODEV in case of initialization error.
+     */
+    unloadSoundModel(SoundModelHandle modelHandle)
+            generates (int32_t retval);
+
+    /*
+     * Start recognition on a given model. Only one recognition active
+     * at a time per model. Once recognition succeeds of fails, the callback
+     * is called.
+     * @param modelHandle the handle of the sound model to use for recognition
+     * @param config A RecognitionConfig structure containing attributes of the
+     *               recognition to perform
+     * @param callback The callback interface on which the recognitionCallback()
+     *                 method must be called upon recognition.
+     * @param cookie The value of the cookie argument passed to the recognition
+     *               callback. This unique context information is assigned and
+     *               used only by the framework.
+     * @return retval Operation completion status: 0 in case of success,
+     *                -EINVAL in case of invalid recognition attributes,
+     *                -ENOSYS in case of invalid model handle,
+     *                -ENOMEM in case of memory allocation failure,
+     *                -ENODEV in case of initialization error.
+     */
+    startRecognition(SoundModelHandle modelHandle,
+                     RecognitionConfig config,
+                     ISoundTriggerHwCallback callback,
+                     CallbackCookie cookie)
+            generates (int32_t retval);
+
+    /*
+     * Stop recognition on a given model.
+     * The implementation must not call the recognition callback when stopped
+     * via this method.
+     * @param modelHandle The handle of the sound model to use for recognition
+     * @return retval Operation completion status: 0 in case of success,
+     *                -ENOSYS in case of invalid model handle,
+     *                -ENODEV in case of initialization error.
+     */
+    stopRecognition(SoundModelHandle modelHandle)
+            generates (int32_t retval);
+
+    /*
+     * Stop recognition on all models.
+     * @return retval Operation completion status: 0 in case of success,
+     *                -ENODEV in case of initialization error.
+     */
+    stopAllRecognitions()
+            generates (int32_t retval);
+};
diff --git a/soundtrigger/2.0/ISoundTriggerHwCallback.hal b/soundtrigger/2.0/ISoundTriggerHwCallback.hal
new file mode 100644
index 0000000..294d451
--- /dev/null
+++ b/soundtrigger/2.0/ISoundTriggerHwCallback.hal
@@ -0,0 +1,103 @@
+/*
+ * Copyright 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.soundtrigger@2.0;
+
+import android.hardware.audio.common@2.0;
+
+interface ISoundTriggerHwCallback {
+    enum RecognitionStatus : uint32_t {
+        SUCCESS  = 0,
+        ABORT    = 1,
+        FAILURE  = 2,
+    };
+
+    enum SoundModelStatus : uint32_t {
+        UPDATED  = 0,
+    };
+
+    /*
+     * Generic recognition event sent via recognition callback
+     */
+    struct RecognitionEvent {
+        /* Recognition status e.g. SUCCESS */
+        RecognitionStatus status;
+        /* Sound model type for this event. e.g SoundModelType.TYPE_KEYPHRASE */
+        SoundModelType    type;
+        /* Handle of loaded sound model which triggered the event */
+        SoundModelHandle  model;
+        /* It is possible to capture audio from this */
+        /* utterance buffered by the implementation */
+        bool              captureAvailable;
+        /* Audio session ID. framework use */
+        int32_t           captureSession;
+        /* Delay in ms between end of model detection and start of audio
+        /* available for capture. A negative value is possible
+         * (e.g. if key phrase is also available for capture */
+        int32_t           captureDelayMs;
+        /* Duration in ms of audio captured before the start of the trigger.
+         * 0 if none. */
+        int32_t           capturePreambleMs;
+        /* The opaque data is the capture of the trigger sound */
+        bool              triggerInData;
+        /* Audio format of either the trigger in event data or to use for
+         * capture of the rest of the utterance */
+        AudioConfig       audioConfig;
+        /* Opaque event data */
+        vec<uint8_t>      data;
+    };
+
+    /*
+     * Specialized recognition event for key phrase recognitions
+     */
+    struct PhraseRecognitionEvent {
+        /* Common part of the recognition event */
+        RecognitionEvent common;
+        /* List of descriptors for each recognized key phrase */
+        vec<PhraseRecognitionExtra> phraseExtras;
+    };
+
+    /*
+     * Event sent via load sound model callback
+     */
+    struct ModelEvent {
+         /* Sound model status e.g. SoundModelStatus.UPDATED */
+        SoundModelStatus status;
+        /* Loaded sound model that triggered the event */
+        SoundModelHandle model;
+        /* Opaque event data, passed transparently by the framework */
+        vec<uint8_t>     data;
+    };
+
+    typedef int32_t CallbackCookie;
+
+    /*
+     * Callback method called by the HAL when the sound recognition triggers
+     * @param event A RecognitionEvent structure containing detailed results
+     *              of the recognition triggered
+     * @param cookie The cookie passed by the framework when recognition was
+     *               started (see ISoundtriggerHw.startRecognition()
+     */
+    recognitionCallback(RecognitionEvent event, CallbackCookie cookie);
+    /*
+     * Callback method called by the HAL when the sound model loading completes
+     * @param event A ModelEvent structure containing detailed results of the
+     *              model loading operation
+     * @param cookie The cookie passed by the framework when loading was
+     *               initiated (see ISoundtriggerHw.loadSoundModel()
+     */
+    soundModelCallback(ModelEvent event, CallbackCookie cookie);
+};
diff --git a/soundtrigger/2.0/types.hal b/soundtrigger/2.0/types.hal
new file mode 100644
index 0000000..059ab32
--- /dev/null
+++ b/soundtrigger/2.0/types.hal
@@ -0,0 +1,75 @@
+/*
+ * Copyright 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.soundtrigger@2.0;
+
+/*
+ * Sound model types modes used in ISoundTriggerHw.SoundModel
+ */
+enum SoundModelType : int32_t {
+    /* use for unspecified sound model type */
+    UNKNOWN   = -1,
+    /* use for key phrase sound models */
+    KEYPHRASE = 0,
+    /* use for all models other than keyphrase */
+    GENERIC   = 1,
+};
+
+typedef int32_t SoundModelHandle;
+
+
+/*
+ * Recognition modes used in ISoundTriggerHw.RecognitionConfig,
+ * ISoundTriggerHw.Properties or PhraseRecognitionExtra
+ */
+enum RecognitionMode : uint32_t {
+    /* simple voice trigger */
+    VOICE_TRIGGER       = (1 << 0),
+    /* trigger only if one user in model identified */
+    USER_IDENTIFICATION = (1 << 1),
+    /* trigger only if one user in mode authenticated */
+    USER_AUTHENTICATION = (1 << 2),
+    /* generic sound trigger */
+    GENERIC_TRIGGER     = (1 << 3),
+};
+
+/*
+ * Confidence level for each user in structure PhraseRecognitionExtra
+ */
+struct ConfidenceLevel {
+    /* user ID */
+    uint32_t userId;
+    /* confidence level in percent (0 - 100): */
+    /* - min level for recognition configuration */
+    /* - detected level for recognition event */
+    uint32_t levelPercent;
+};
+
+/*
+ * Specialized recognition event for key phrase detection
+ */
+struct PhraseRecognitionExtra {
+    /* keyphrase ID */
+    uint32_t id;
+    /* recognition modes used for this keyphrase */
+    uint32_t recognitionModes;
+    /* confidence level for mode RecognitionMode.VOICE_TRIGGER */
+    uint32_t confidenceLevel;
+    /* list of confidence levels per user for
+     * RecognitionMode.USER_IDENTIFICATION and
+     * RecognitionMode.USER_AUTHENTICATION */
+    vec<ConfidenceLevel> levels;
+};