diff --git a/renderscript/1.0/default/Context.cpp b/renderscript/1.0/default/Context.cpp
new file mode 100644
index 0000000..5a09cf9
--- /dev/null
+++ b/renderscript/1.0/default/Context.cpp
@@ -0,0 +1,757 @@
+#define LOG_TAG "android.hardware.renderscript@1.0-impl"
+
+#include "Context.h"
+#include "Device.h"
+
+namespace android {
+namespace hardware {
+namespace renderscript {
+namespace V1_0 {
+namespace implementation {
+
+
+Context::Context(uint32_t sdkVersion, ContextType ct, int32_t flags) {
+    RsDevice _dev = nullptr;
+    uint32_t _version = 0;
+    uint32_t _sdkVersion = sdkVersion;
+    RsContextType _ct = static_cast<RsContextType>(ct);
+    int32_t _flags = flags;
+    mContext = Device::getHal().ContextCreate(_dev, _version, _sdkVersion, _ct, _flags);
+}
+
+
+// Helper functions
+template<typename ReturnType>
+static ReturnType hidl_to_rs(OpaqueHandle src) {
+    return reinterpret_cast<ReturnType>(static_cast<uintptr_t>(src));
+}
+
+template<typename ReturnType, typename SourceType>
+static ReturnType hidl_to_rs(SourceType* src) {
+    return reinterpret_cast<ReturnType>(src);
+}
+
+template<typename RsType, typename HidlType, typename Operation>
+static std::vector<RsType> hidl_to_rs(const hidl_vec<HidlType>& src, Operation operation) {
+    std::vector<RsType> dst(src.size());
+    std::transform(src.begin(), src.end(), dst.begin(), operation);
+    return dst;
+}
+
+template<typename ReturnType, typename SourceType>
+static ReturnType rs_to_hidl(SourceType* src) {
+    return static_cast<ReturnType>(reinterpret_cast<uintptr_t>(src));
+}
+
+template<typename HidlType, typename RsType, typename Operation>
+static hidl_vec<HidlType> rs_to_hidl(const std::vector<RsType>& src, Operation operation) {
+    std::vector<HidlType> dst(src.size());
+    std::transform(src.begin(), src.end(), dst.begin(), operation);
+    return dst;
+}
+
+
+// Methods from ::android::hardware::renderscript::V1_0::IContext follow.
+
+Return<Allocation> Context::allocationAdapterCreate(Type type, Allocation baseAlloc) {
+    RsType _type = hidl_to_rs<RsType>(type);
+    RsAllocation _baseAlloc = hidl_to_rs<RsAllocation>(baseAlloc);
+    RsAllocation _subAlloc = Device::getHal().AllocationAdapterCreate(mContext, _type, _baseAlloc);
+    return rs_to_hidl<Allocation>(_subAlloc);
+}
+
+Return<void> Context::allocationAdapterOffset(Allocation alloc, const hidl_vec<uint32_t>& offsets) {
+    RsAllocation _alloc = hidl_to_rs<RsAllocation>(alloc);
+    const hidl_vec<uint32_t>& _offsets = offsets;
+    Device::getHal().AllocationAdapterOffset(mContext, _alloc, _offsets.data(), _offsets.size());
+    return Void();
+}
+
+Return<Type> Context::allocationGetType(Allocation allocation) {
+    RsAllocation _allocation = hidl_to_rs<RsAllocation>(allocation);
+    const void* _type = Device::getHal().AllocationGetType(mContext, _allocation);
+    return rs_to_hidl<Type>(_type);
+}
+
+Return<Allocation> Context::allocationCreateTyped(Type type, AllocationMipmapControl mips, int32_t usage, Ptr ptr) {
+    RsType _type = hidl_to_rs<RsType>(type);
+    RsAllocationMipmapControl _mips = static_cast<RsAllocationMipmapControl>(mips);
+    uint32_t _usage = usage;
+    uintptr_t _ptr = hidl_to_rs<uintptr_t>(ptr);
+    RsAllocation _allocation = Device::getHal().AllocationCreateTyped(mContext, _type, _mips, _usage, _ptr);
+    return rs_to_hidl<Allocation>(_allocation);
+}
+
+Return<Allocation> Context::allocationCreateFromBitmap(Type type, AllocationMipmapControl mips, const hidl_vec<uint8_t>& bitmap, int32_t usage) {
+    RsType _type = hidl_to_rs<RsType>(type);
+    RsAllocationMipmapControl _mips = static_cast<RsAllocationMipmapControl>(mips);
+    const hidl_vec<uint8_t>& _bitmap = bitmap;
+    uint32_t _usage = usage;
+    RsAllocation _allocation = Device::getHal().AllocationCreateFromBitmap(mContext, _type, _mips, _bitmap.data(), _bitmap.size(), _usage);
+    return rs_to_hidl<Allocation>(_allocation);
+}
+
+Return<Allocation> Context::allocationCubeCreateFromBitmap(Type type, AllocationMipmapControl mips, const hidl_vec<uint8_t>& bitmap, int32_t usage) {
+    RsType _type = hidl_to_rs<RsType>(type);
+    RsAllocationMipmapControl _mips = static_cast<RsAllocationMipmapControl>(mips);
+    const hidl_vec<uint8_t>& _bitmap = bitmap;
+    uint32_t _usage = usage;
+    RsAllocation _allocation = Device::getHal().AllocationCubeCreateFromBitmap(mContext, _type, _mips, _bitmap.data(), _bitmap.size(), _usage);
+    return rs_to_hidl<Allocation>(_allocation);
+}
+
+Return<NativeWindow> Context::allocationGetNativeWindow(Allocation allocation) {
+    RsAllocation _allocation = hidl_to_rs<RsAllocation>(allocation);
+    RsNativeWindow _nativeWindow = Device::getHal().AllocationGetSurface(mContext, _allocation);
+    return rs_to_hidl<NativeWindow>(_nativeWindow);
+}
+
+Return<void> Context::allocationSetNativeWindow(Allocation allocation, NativeWindow nativewindow) {
+    RsAllocation _allocation = hidl_to_rs<RsAllocation>(allocation);
+    RsNativeWindow _nativewindow = hidl_to_rs<RsNativeWindow>(nativewindow);
+    Device::getHal().AllocationSetSurface(mContext, _allocation, _nativewindow);
+    return Void();
+}
+
+Return<void> Context::allocationSetupBufferQueue(Allocation alloc, uint32_t numBuffer) {
+    RsAllocation _alloc = hidl_to_rs<RsAllocation>(alloc);
+    uint32_t _numBuffer = numBuffer;
+    Device::getHal().AllocationSetupBufferQueue(mContext, _alloc, _numBuffer);
+    return Void();
+}
+
+Return<void> Context::allocationShareBufferQueue(Allocation baseAlloc, Allocation subAlloc) {
+    RsAllocation _baseAlloc = hidl_to_rs<RsAllocation>(baseAlloc);
+    RsAllocation _subAlloc = hidl_to_rs<RsAllocation>(subAlloc);
+    Device::getHal().AllocationShareBufferQueue(mContext, _baseAlloc, _subAlloc);
+    return Void();
+}
+
+Return<void> Context::allocationCopyToBitmap(Allocation allocation, Ptr data, Size sizeBytes) {
+    RsAllocation _allocation = hidl_to_rs<RsAllocation>(allocation);
+    void* _data = hidl_to_rs<void*>(data);
+    size_t _sizeBytes = static_cast<size_t>(sizeBytes);
+    Device::getHal().AllocationCopyToBitmap(mContext, _allocation, _data, _sizeBytes);
+    return Void();
+}
+
+Return<void> Context::allocation1DWrite(Allocation allocation, uint32_t offset, uint32_t lod, uint32_t count, const hidl_vec<uint8_t>& data) {
+    RsAllocation _allocation = hidl_to_rs<RsAllocation>(allocation);
+    uint32_t _offset = offset;
+    uint32_t _lod = lod;
+    uint32_t _count = count;
+    const void* _dataPtr = hidl_to_rs<const void*>(data.data());
+    size_t _sizeBytes = data.size();
+    Device::getHal().Allocation1DData(mContext, _allocation, _offset, _lod, _count, _dataPtr, _sizeBytes);
+    return Void();
+}
+
+Return<void> Context::allocationElementWrite(Allocation allocation, uint32_t x, uint32_t y, uint32_t z, uint32_t lod, const hidl_vec<uint8_t>& data, Size compIdx) {
+    RsAllocation _allocation = hidl_to_rs<RsAllocation>(allocation);
+    uint32_t _x = x;
+    uint32_t _y = y;
+    uint32_t _z = z;
+    uint32_t _lod = lod;
+    const void* _dataPtr = hidl_to_rs<const void*>(data.data());
+    size_t _sizeBytes = data.size();
+    size_t _compIdx = static_cast<size_t>(compIdx);
+    Device::getHal().AllocationElementData(mContext, _allocation, _x, _y, _z, _lod, _dataPtr, _sizeBytes, _compIdx);
+    return Void();
+}
+
+Return<void> Context::allocation2DWrite(Allocation allocation, uint32_t xoff, uint32_t yoff, uint32_t lod, AllocationCubemapFace face, uint32_t w, uint32_t h, const hidl_vec<uint8_t>& data, Size stride) {
+    RsAllocation _allocation = hidl_to_rs<RsAllocation>(allocation);
+    uint32_t _xoff = xoff;
+    uint32_t _yoff = yoff;
+    uint32_t _lod = lod;
+    RsAllocationCubemapFace _face = static_cast<RsAllocationCubemapFace>(face);
+    uint32_t _w = w;
+    uint32_t _h = h;
+    const void* _dataPtr = hidl_to_rs<const void*>(data.data());
+    size_t _sizeBytes = data.size();
+    size_t _stride = static_cast<size_t>(stride);
+    Device::getHal().Allocation2DData(mContext, _allocation, _xoff, _yoff, _lod, _face, _w, _h, _dataPtr, _sizeBytes, _stride);
+    return Void();
+}
+
+Return<void> Context::allocation3DWrite(Allocation allocation, uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t lod, uint32_t w, uint32_t h, uint32_t d, const hidl_vec<uint8_t>& data, Size stride) {
+    RsAllocation _allocation = hidl_to_rs<RsAllocation>(allocation);
+    uint32_t _xoff = xoff;
+    uint32_t _yoff = yoff;
+    uint32_t _zoff = zoff;
+    uint32_t _lod = lod;
+    uint32_t _w = w;
+    uint32_t _h = h;
+    uint32_t _d = d;
+    const void* _dataPtr = hidl_to_rs<const void*>(data.data());
+    size_t _sizeBytes = data.size();
+    size_t _stride = static_cast<size_t>(stride);
+    Device::getHal().Allocation3DData(mContext, _allocation, _xoff, _yoff, _zoff, _lod, _w, _h, _d, _dataPtr, _sizeBytes, _stride);
+    return Void();
+}
+
+Return<void> Context::allocationGenerateMipmaps(Allocation allocation) {
+    RsAllocation _allocation = hidl_to_rs<RsAllocation>(allocation);
+    Device::getHal().AllocationGenerateMipmaps(mContext, _allocation);
+    return Void();
+}
+
+Return<void> Context::allocationRead(Allocation allocation, Ptr data, Size sizeBytes) {
+    RsAllocation _allocation = hidl_to_rs<RsAllocation>(allocation);
+    void* _data = hidl_to_rs<void*>(data);
+    size_t _sizeBytes = static_cast<size_t>(sizeBytes);
+    Device::getHal().AllocationRead(mContext, _allocation, _data, _sizeBytes);
+    return Void();
+}
+
+Return<void> Context::allocation1DRead(Allocation allocation, uint32_t xoff, uint32_t lod, uint32_t count, Ptr data, Size sizeBytes) {
+    RsAllocation _allocation = hidl_to_rs<RsAllocation>(allocation);
+    uint32_t _xoff = xoff;
+    uint32_t _lod = lod;
+    uint32_t _count = count;
+    void* _data = hidl_to_rs<void*>(data);
+    size_t _sizeBytes = static_cast<size_t>(sizeBytes);
+    Device::getHal().Allocation1DRead(mContext, _allocation, _xoff, _lod, _count, _data, _sizeBytes);
+    return Void();
+}
+
+Return<void> Context::allocationElementRead(Allocation allocation, uint32_t x, uint32_t y, uint32_t z, uint32_t lod, Ptr data, Size sizeBytes, Size compIdx) {
+    RsAllocation _allocation = hidl_to_rs<RsAllocation>(allocation);
+    uint32_t _x = x;
+    uint32_t _y = y;
+    uint32_t _z = z;
+    uint32_t _lod = lod;
+    void* _data = hidl_to_rs<void*>(data);
+    size_t _sizeBytes = static_cast<size_t>(sizeBytes);
+    size_t _compIdx = static_cast<size_t>(compIdx);
+    Device::getHal().AllocationElementRead(mContext, _allocation, _x, _y, _z, _lod, _data, _sizeBytes, _compIdx);
+    return Void();
+}
+
+Return<void> Context::allocation2DRead(Allocation allocation, uint32_t xoff, uint32_t yoff, uint32_t lod, AllocationCubemapFace face, uint32_t w, uint32_t h, Ptr data, Size sizeBytes, Size stride) {
+    RsAllocation _allocation = hidl_to_rs<RsAllocation>(allocation);
+    uint32_t _xoff = xoff;
+    uint32_t _yoff = yoff;
+    uint32_t _lod = lod;
+    RsAllocationCubemapFace _face = static_cast<RsAllocationCubemapFace>(face);
+    uint32_t _w = w;
+    uint32_t _h = h;
+    void* _data = hidl_to_rs<void*>(data);
+    size_t _sizeBytes = static_cast<size_t>(sizeBytes);
+    size_t _stride = static_cast<size_t>(stride);
+    Device::getHal().Allocation2DRead(mContext, _allocation, _xoff, _yoff, _lod, _face, _w, _h, _data, _sizeBytes, _stride);
+    return Void();
+}
+
+Return<void> Context::allocation3DRead(Allocation allocation, uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t lod, uint32_t w, uint32_t h, uint32_t d, Ptr data, Size sizeBytes, Size stride) {
+    RsAllocation _allocation = hidl_to_rs<RsAllocation>(allocation);
+    uint32_t _xoff = xoff;
+    uint32_t _yoff = yoff;
+    uint32_t _zoff = zoff;
+    uint32_t _lod = lod;
+    uint32_t _w = w;
+    uint32_t _h = h;
+    uint32_t _d = d;
+    void* _dataPtr = hidl_to_rs<void*>(data);
+    size_t _sizeBytes = static_cast<size_t>(sizeBytes);
+    size_t _stride = static_cast<size_t>(stride);
+    Device::getHal().Allocation3DRead(mContext, _allocation, _xoff, _yoff, _zoff, _lod, _w, _h, _d, _dataPtr, _sizeBytes, _stride);
+    return Void();
+}
+
+Return<void> Context::allocationSyncAll(Allocation allocation, AllocationUsageType usageType) {
+    RsAllocation _allocation = hidl_to_rs<RsAllocation>(allocation);
+    RsAllocationUsageType _usageType = static_cast<RsAllocationUsageType>(usageType);
+    Device::getHal().AllocationSyncAll(mContext, _allocation, _usageType);
+    return Void();
+}
+
+Return<void> Context::allocationResize1D(Allocation allocation, uint32_t dimX) {
+    RsAllocation _allocation = hidl_to_rs<RsAllocation>(allocation);
+    uint32_t _dimX = dimX;
+    Device::getHal().AllocationResize1D(mContext, _allocation, _dimX);
+    return Void();
+}
+
+Return<void> Context::allocationCopy2DRange(Allocation dstAlloc, uint32_t dstXoff, uint32_t dstYoff, uint32_t dstMip, AllocationCubemapFace dstFace, uint32_t width, uint32_t height, Allocation srcAlloc, uint32_t srcXoff, uint32_t srcYoff, uint32_t srcMip, AllocationCubemapFace srcFace) {
+    RsAllocation _dstAlloc = hidl_to_rs<RsAllocation>(dstAlloc);
+    uint32_t _dstXoff = dstXoff;
+    uint32_t _dstYoff = dstYoff;
+    uint32_t _dstMip = dstMip;
+    RsAllocationCubemapFace _dstFace = static_cast<RsAllocationCubemapFace>(dstFace);
+    uint32_t _width = width;
+    uint32_t _height = height;
+    RsAllocation _srcAlloc = hidl_to_rs<RsAllocation>(srcAlloc);
+    uint32_t _srcXoff = srcXoff;
+    uint32_t _srcYoff = srcYoff;
+    uint32_t _srcMip = srcMip;
+    RsAllocationCubemapFace _srcFace = static_cast<RsAllocationCubemapFace>(srcFace);
+    Device::getHal().AllocationCopy2DRange(mContext, _dstAlloc, _dstXoff, _dstYoff, _dstMip, _dstFace, _width, _height, _srcAlloc, _srcXoff, _srcYoff, _srcMip, _srcFace);
+    return Void();
+}
+
+Return<void> Context::allocationCopy3DRange(Allocation dstAlloc, uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff, uint32_t dstMip, uint32_t width, uint32_t height, uint32_t depth, Allocation srcAlloc, uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff, uint32_t srcMip) {
+    RsAllocation _dstAlloc = hidl_to_rs<RsAllocation>(dstAlloc);
+    uint32_t _dstXoff = dstXoff;
+    uint32_t _dstYoff = dstYoff;
+    uint32_t _dstZoff = dstZoff;
+    uint32_t _dstMip = dstMip;
+    uint32_t _width = width;
+    uint32_t _height = height;
+    uint32_t _depth = depth;
+    RsAllocation _srcAlloc = hidl_to_rs<RsAllocation>(srcAlloc);
+    uint32_t _srcXoff = srcXoff;
+    uint32_t _srcYoff = srcYoff;
+    uint32_t _srcZoff = srcZoff;
+    uint32_t _srcMip = srcMip;
+    Device::getHal().AllocationCopy3DRange(mContext, _dstAlloc, _dstXoff, _dstYoff, _dstZoff, _dstMip, _width, _height, _depth, _srcAlloc, _srcXoff, _srcYoff, _srcZoff, _srcMip);
+    return Void();
+}
+
+Return<void> Context::allocationIoSend(Allocation allocation) {
+    RsAllocation _allocation = hidl_to_rs<RsAllocation>(allocation);
+    Device::getHal().AllocationIoSend(mContext, _allocation);
+    return Void();
+}
+
+Return<void> Context::allocationIoReceive(Allocation allocation) {
+    RsAllocation _allocation = hidl_to_rs<RsAllocation>(allocation);
+    Device::getHal().AllocationIoReceive(mContext, _allocation);
+    return Void();
+}
+
+Return<void> Context::allocationGetPointer(Allocation allocation, uint32_t lod, AllocationCubemapFace face, uint32_t z, allocationGetPointer_cb _hidl_cb) {
+    RsAllocation _allocation = hidl_to_rs<RsAllocation>(allocation);
+    uint32_t _lod = lod;
+    RsAllocationCubemapFace _face = static_cast<RsAllocationCubemapFace>(face);
+    uint32_t _z = z;
+    uint32_t _array = 0;
+    size_t _stride = 0;
+    void* _dataPtr = Device::getHal().AllocationGetPointer(mContext, _allocation, _lod, _face, _z, _array, &_stride, sizeof(size_t));
+    Ptr dataPtr = reinterpret_cast<Ptr>(_dataPtr);
+    Size stride = static_cast<Size>(_stride);
+    _hidl_cb(dataPtr, stride);
+    return Void();
+}
+
+Return<void> Context::elementGetNativeMetadata(Element element, elementGetNativeMetadata_cb _hidl_cb) {
+    RsElement _element = hidl_to_rs<RsElement>(element);
+    std::vector<uint32_t> _elemData(5);
+    Device::getHal().ElementGetNativeData(mContext, _element, _elemData.data(), _elemData.size());
+    hidl_vec<uint32_t> elemData = _elemData;
+    _hidl_cb(elemData);
+    return Void();
+}
+
+Return<void> Context::elementGetSubElements(Element element, Size numSubElem, elementGetSubElements_cb _hidl_cb) {
+    RsElement _element = hidl_to_rs<RsElement>(element);
+    uint32_t _numSubElem = static_cast<uint32_t>(numSubElem);
+    std::vector<uintptr_t> _ids(_numSubElem);
+    std::vector<const char*> _names(_numSubElem);
+    std::vector<size_t> _arraySizes(_numSubElem);
+    Device::getHal().ElementGetSubElements(mContext, _element, _ids.data(), _names.data(), _arraySizes.data(), _numSubElem);
+    hidl_vec<Element>     ids        = rs_to_hidl<Element>(_ids,       [](uintptr_t val) { return static_cast<Element>(val); });
+    hidl_vec<hidl_string> names      = rs_to_hidl<hidl_string>(_names, [](const char* val) { return val; });
+    hidl_vec<Size>        arraySizes = rs_to_hidl<Size>(_arraySizes,   [](size_t val) { return static_cast<Size>(val); });
+    _hidl_cb(ids, names, arraySizes);
+    return Void();
+}
+
+Return<Element> Context::elementCreate(DataType dt, DataKind dk, bool norm, uint32_t size) {
+    RsDataType _dt = static_cast<RsDataType>(dt);
+    RsDataKind _dk = static_cast<RsDataKind>(dk);
+    bool _norm = norm;
+    uint32_t _size = size;
+    RsElement _element = Device::getHal().ElementCreate(mContext, _dt, _dk, _norm, _size);
+    return rs_to_hidl<Element>(_element);
+}
+
+Return<Element> Context::elementComplexCreate(const hidl_vec<Element>& eins, const hidl_vec<hidl_string>& names, const hidl_vec<Size>& arraySizes) {
+    std::vector<RsElement>   _eins           = hidl_to_rs<RsElement>(eins,      [](Element val) { return hidl_to_rs<RsElement>(val); });
+    std::vector<const char*> _namesPtr       = hidl_to_rs<const char*>(names,   [](const hidl_string& val) { return val.c_str(); });
+    std::vector<size_t>      _nameLengthsPtr = hidl_to_rs<size_t>(names,        [](const hidl_string& val) { return val.size(); });
+    std::vector<uint32_t>    _arraySizes     = hidl_to_rs<uint32_t>(arraySizes, [](Size val) { return static_cast<uint32_t>(val); });
+    RsElement _element = Device::getHal().ElementCreate2(mContext, _eins.data(), _eins.size(), _namesPtr.data(), _namesPtr.size(), _nameLengthsPtr.data(), _arraySizes.data(), _arraySizes.size());
+    return rs_to_hidl<Element>(_element);
+}
+
+Return<void> Context::typeGetNativeMetadata(Type type, typeGetNativeMetadata_cb _hidl_cb) {
+    RsType _type = hidl_to_rs<RsType>(type);
+    std::vector<uintptr_t> _metadata(6);
+    Device::getHal().TypeGetNativeData(mContext, _type, _metadata.data(), _metadata.size());
+    hidl_vec<OpaqueHandle> metadata = rs_to_hidl<OpaqueHandle>(_metadata, [](uintptr_t val) { return static_cast<OpaqueHandle>(val); });
+    _hidl_cb(metadata);
+    return Void();
+}
+
+Return<Type> Context::typeCreate(Element element, uint32_t dimX, uint32_t dimY, uint32_t dimZ, bool mipmaps, bool faces, YuvFormat yuv) {
+    RsElement _element = hidl_to_rs<RsElement>(element);
+    uint32_t _dimX = dimX;
+    uint32_t _dimY = dimY;
+    uint32_t _dimZ = dimZ;
+    bool _mipmaps = mipmaps;
+    bool _faces = faces;
+    RsYuvFormat _yuv = static_cast<RsYuvFormat>(yuv);
+    RsType _type = Device::getHal().TypeCreate(mContext, _element, _dimX, _dimY, _dimZ, _mipmaps, _faces, _yuv);
+    return rs_to_hidl<Type>(_type);
+}
+
+Return<void> Context::contextDestroy() {
+    Device::getHal().ContextDestroy(mContext);
+    mContext = nullptr;
+    return Void();
+}
+
+Return<void> Context::contextGetMessage(Ptr data, Size size, contextGetMessage_cb _hidl_cb) {
+    void* _data = hidl_to_rs<void*>(data);
+    size_t _size = static_cast<size_t>(size);
+    size_t _receiveLen = 0;
+    uint32_t _subID = 0;
+    RsMessageToClientType _messageType = Device::getHal().ContextGetMessage(mContext, _data, _size, &_receiveLen, sizeof(size_t), &_subID, sizeof(uint32_t));
+    MessageToClientType messageType = static_cast<MessageToClientType>(_messageType);
+    Size receiveLen = static_cast<Size>(_receiveLen);
+    _hidl_cb(messageType, receiveLen);
+    return Void();
+}
+
+Return<void> Context::contextPeekMessage(contextPeekMessage_cb _hidl_cb) {
+    size_t _receiveLen = 0;
+    uint32_t _subID = 0;
+    RsMessageToClientType _messageType = Device::getHal().ContextPeekMessage(mContext, &_receiveLen, sizeof(size_t), &_subID, sizeof(uint32_t));
+    MessageToClientType messageType = static_cast<MessageToClientType>(_messageType);
+    Size receiveLen = static_cast<Size>(_receiveLen);
+    uint32_t subID = _subID;
+    _hidl_cb(messageType, receiveLen, subID);
+    return Void();
+}
+
+Return<void> Context::contextSendMessage(uint32_t id, const hidl_vec<uint8_t>& data) {
+    uint32_t _id = id;
+    const uint8_t* _dataPtr = data.data();
+    size_t _dataSize = data.size();
+    Device::getHal().ContextSendMessage(mContext, _id, _dataPtr, _dataSize);
+    return Void();
+}
+
+Return<void> Context::contextInitToClient() {
+    Device::getHal().ContextInitToClient(mContext);
+    return Void();
+}
+
+Return<void> Context::contextDeinitToClient() {
+    Device::getHal().ContextDeinitToClient(mContext);
+    return Void();
+}
+
+Return<void> Context::contextFinish() {
+    Device::getHal().ContextFinish(mContext);
+    return Void();
+}
+
+Return<void> Context::contextLog() {
+    uint32_t _bits = 0;
+    Device::getHal().ContextDump(mContext, _bits);
+    return Void();
+}
+
+Return<void> Context::contextSetPriority(ThreadPriorities priority) {
+    RsThreadPriorities _priority = static_cast<RsThreadPriorities>(priority);
+    Device::getHal().ContextSetPriority(mContext, _priority);
+    return Void();
+}
+
+Return<void> Context::contextSetCacheDir(const hidl_string& cacheDir) {
+    Device::getHal().ContextSetCacheDir(mContext, cacheDir.c_str(), cacheDir.size());
+    return Void();
+}
+
+Return<void> Context::assignName(ObjectBase obj, const hidl_string& name) {
+    RsObjectBase _obj = hidl_to_rs<RsObjectBase>(obj);
+    const hidl_string& _name = name;
+    Device::getHal().AssignName(mContext, _obj, _name.c_str(), _name.size());
+    return Void();
+}
+
+Return<void> Context::getName(ObjectBase obj, getName_cb _hidl_cb) {
+    void* _obj = hidl_to_rs<void*>(obj);
+    const char* _name = nullptr;
+    Device::getHal().GetName(mContext, _obj, &_name);
+    hidl_string name = _name;
+    _hidl_cb(name);
+    return Void();
+}
+
+Return<Closure> Context::closureCreate(ScriptKernelID kernelID, Allocation returnValue, const hidl_vec<ScriptFieldID>& fieldIDS, const hidl_vec<int64_t>& values, const hidl_vec<int32_t>& sizes, const hidl_vec<Closure>& depClosures, const hidl_vec<ScriptFieldID>& depFieldIDS) {
+    RsScriptKernelID _kernelID = hidl_to_rs<RsScriptKernelID>(kernelID);
+    RsAllocation _returnValue = hidl_to_rs<RsAllocation>(returnValue);
+    std::vector<RsScriptFieldID> _fieldIDS = hidl_to_rs<RsScriptFieldID>(fieldIDS, [](ScriptFieldID val) { return hidl_to_rs<RsScriptFieldID>(val); });
+    int64_t* _valuesPtr = const_cast<int64_t*>(values.data());
+    size_t _valuesLength = values.size();
+    std::vector<int>             _sizes       = hidl_to_rs<int>(sizes,                   [](int32_t val) { return static_cast<int>(val); });
+    std::vector<RsClosure>       _depClosures = hidl_to_rs<RsClosure>(depClosures,       [](Closure val) { return hidl_to_rs<RsClosure>(val); });
+    std::vector<RsScriptFieldID> _depFieldIDS = hidl_to_rs<RsScriptFieldID>(depFieldIDS, [](ScriptFieldID val) { return hidl_to_rs<RsScriptFieldID>(val); });
+    RsClosure _closure = Device::getHal().ClosureCreate(mContext, _kernelID, _returnValue, _fieldIDS.data(), _fieldIDS.size(), _valuesPtr, _valuesLength, _sizes.data(), _sizes.size(), _depClosures.data(), _depClosures.size(), _depFieldIDS.data(), _depFieldIDS.size());
+    return rs_to_hidl<Closure>(_closure);
+}
+
+Return<Closure> Context::invokeClosureCreate(ScriptInvokeID invokeID, const hidl_vec<uint8_t>& params, const hidl_vec<ScriptFieldID>& fieldIDS, const hidl_vec<int64_t>& values, const hidl_vec<int32_t>& sizes) {
+    RsScriptInvokeID _invokeID = hidl_to_rs<RsScriptInvokeID>(invokeID);
+    const void* _paramsPtr = params.data();
+    size_t _paramsSize = params.size();
+    std::vector<RsScriptFieldID> _fieldIDS = hidl_to_rs<RsScriptFieldID>(fieldIDS, [](ScriptFieldID val) { return hidl_to_rs<RsScriptFieldID>(val); });
+    const int64_t* _valuesPtr = values.data();
+    size_t _valuesLength = values.size();
+    std::vector<int> _sizes = hidl_to_rs<int>(sizes, [](int32_t val) { return static_cast<int>(val); });
+    RsClosure _closure = Device::getHal().InvokeClosureCreate(mContext, _invokeID, _paramsPtr, _paramsSize, _fieldIDS.data(), _fieldIDS.size(), _valuesPtr, _valuesLength, _sizes.data(), _sizes.size());
+    return rs_to_hidl<Closure>(_closure);
+}
+
+Return<void> Context::closureSetArg(Closure closure, uint32_t index, Ptr value, int32_t size) {
+    RsClosure _closure = hidl_to_rs<RsClosure>(closure);
+    uint32_t _index = index;
+    uintptr_t _value = hidl_to_rs<uintptr_t>(value);
+    int _size = static_cast<int>(size);
+    Device::getHal().ClosureSetArg(mContext, _closure, _index, _value, _size);
+    return Void();
+}
+
+Return<void> Context::closureSetGlobal(Closure closure, ScriptFieldID fieldID, int64_t value, int32_t size) {
+    RsClosure _closure = hidl_to_rs<RsClosure>(closure);
+    RsScriptFieldID _fieldID = hidl_to_rs<RsScriptFieldID>(fieldID);
+    int64_t _value = value;
+    int _size = static_cast<int>(size);
+    Device::getHal().ClosureSetGlobal(mContext, _closure, _fieldID, _value, _size);
+    return Void();
+}
+
+Return<ScriptKernelID> Context::scriptKernelIDCreate(Script script, int32_t slot, int32_t sig) {
+    RsScript _script = hidl_to_rs<RsScript>(script);
+    int _slot = static_cast<int>(slot);
+    int _sig = static_cast<int>(sig);
+    RsScriptKernelID _scriptKernelID = Device::getHal().ScriptKernelIDCreate(mContext, _script, _slot, _sig);
+    return rs_to_hidl<ScriptKernelID>(_scriptKernelID);
+}
+
+Return<ScriptInvokeID> Context::scriptInvokeIDCreate(Script script, int32_t slot) {
+    RsScript _script = hidl_to_rs<RsScript>(script);
+    int _slot = static_cast<int>(slot);
+    RsScriptInvokeID _scriptInvokeID = Device::getHal().ScriptInvokeIDCreate(mContext, _script, _slot);
+    return rs_to_hidl<ScriptInvokeID>(_scriptInvokeID);
+}
+
+Return<ScriptFieldID> Context::scriptFieldIDCreate(Script script, int32_t slot) {
+    RsScript _script = hidl_to_rs<RsScript>(script);
+    int _slot = static_cast<int>(slot);
+    RsScriptFieldID _scriptFieldID = Device::getHal().ScriptFieldIDCreate(mContext, _script, _slot);
+    return rs_to_hidl<ScriptFieldID>(_scriptFieldID);
+}
+
+Return<ScriptGroup> Context::scriptGroupCreate(const hidl_vec<ScriptKernelID>& kernels, const hidl_vec<ScriptKernelID>& srcK, const hidl_vec<ScriptKernelID>& dstK, const hidl_vec<ScriptFieldID>& dstF, const hidl_vec<Type>& types) {
+    std::vector<RsScriptKernelID> _kernels = hidl_to_rs<RsScriptKernelID>(kernels, [](ScriptFieldID val) { return hidl_to_rs<RsScriptKernelID>(val); });
+    std::vector<RsScriptKernelID> _srcK    = hidl_to_rs<RsScriptKernelID>(srcK,    [](ScriptFieldID val) { return hidl_to_rs<RsScriptKernelID>(val); });
+    std::vector<RsScriptKernelID> _dstK    = hidl_to_rs<RsScriptKernelID>(dstK,    [](ScriptFieldID val) { return hidl_to_rs<RsScriptKernelID>(val); });
+    std::vector<RsScriptFieldID>  _dstF    = hidl_to_rs<RsScriptFieldID>(dstF,     [](ScriptFieldID val) { return hidl_to_rs<RsScriptFieldID>(val); });
+    std::vector<RsType>           _types   = hidl_to_rs<RsType>(types,             [](Type val) { return hidl_to_rs<RsType>(val); });
+    RsScriptGroup _scriptGroup = Device::getHal().ScriptGroupCreate(mContext, _kernels.data(), _kernels.size(), _srcK.data(), _srcK.size(), _dstK.data(), _dstK.size(), _dstF.data(), _dstF.size(), _types.data(), _types.size());
+    return rs_to_hidl<ScriptGroup>(_scriptGroup);
+}
+
+Return<ScriptGroup2> Context::scriptGroup2Create(const hidl_string& name, const hidl_string& cacheDir, const hidl_vec<Closure>& closures) {
+    const hidl_string& _name = name;
+    const hidl_string& _cacheDir = cacheDir;
+    std::vector<RsClosure> _closures = hidl_to_rs<RsClosure>(closures, [](Closure val) { return hidl_to_rs<RsClosure>(val); });
+    RsScriptGroup2 _scriptGroup2 = Device::getHal().ScriptGroup2Create(mContext, _name.c_str(), _name.size(), _cacheDir.c_str(), _cacheDir.size(), _closures.data(), _closures.size());
+    return rs_to_hidl<ScriptGroup2>(_scriptGroup2);
+}
+
+Return<void> Context::scriptGroupSetOutput(ScriptGroup sg, ScriptKernelID kid, Allocation alloc) {
+    RsScriptGroup _sg = hidl_to_rs<RsScriptGroup>(sg);
+    RsScriptKernelID _kid = hidl_to_rs<RsScriptKernelID>(kid);
+    RsAllocation _alloc = hidl_to_rs<RsAllocation>(alloc);
+    Device::getHal().ScriptGroupSetOutput(mContext, _sg, _kid, _alloc);
+    return Void();
+}
+
+Return<void> Context::scriptGroupSetInput(ScriptGroup sg, ScriptKernelID kid, Allocation alloc) {
+    RsScriptGroup _sg = hidl_to_rs<RsScriptGroup>(sg);
+    RsScriptKernelID _kid = hidl_to_rs<RsScriptKernelID>(kid);
+    RsAllocation _alloc = hidl_to_rs<RsAllocation>(alloc);
+    Device::getHal().ScriptGroupSetInput(mContext, _sg, _kid, _alloc);
+    return Void();
+}
+
+Return<void> Context::scriptGroupExecute(ScriptGroup sg) {
+    RsScriptGroup _sg = hidl_to_rs<RsScriptGroup>(sg);
+    Device::getHal().ScriptGroupExecute(mContext, _sg);
+    return Void();
+}
+
+Return<void> Context::objDestroy(ObjectBase obj) {
+    RsAsyncVoidPtr _obj = hidl_to_rs<RsAsyncVoidPtr>(obj);
+    Device::getHal().ObjDestroy(mContext, _obj);
+    return Void();
+}
+
+Return<Sampler> Context::samplerCreate(SamplerValue magFilter, SamplerValue minFilter, SamplerValue wrapS, SamplerValue wrapT, SamplerValue wrapR, float aniso) {
+    RsSamplerValue _magFilter = static_cast<RsSamplerValue>(magFilter);
+    RsSamplerValue _minFilter = static_cast<RsSamplerValue>(minFilter);
+    RsSamplerValue _wrapS = static_cast<RsSamplerValue>(wrapS);
+    RsSamplerValue _wrapT = static_cast<RsSamplerValue>(wrapT);
+    RsSamplerValue _wrapR = static_cast<RsSamplerValue>(wrapR);
+    float _aniso = static_cast<float>(aniso);
+    RsSampler _sampler = Device::getHal().SamplerCreate(mContext, _magFilter, _minFilter, _wrapS, _wrapT, _wrapR, _aniso);
+    return rs_to_hidl<Sampler>(_sampler);
+}
+
+Return<void> Context::scriptBindAllocation(Script script, Allocation allocation, uint32_t slot) {
+    RsScript _script = hidl_to_rs<RsScript>(script);
+    RsAllocation _allocation = hidl_to_rs<RsAllocation>(allocation);
+    uint32_t _slot = slot;
+    Device::getHal().ScriptBindAllocation(mContext, _script, _allocation, _slot);
+    return Void();
+}
+
+Return<void> Context::scriptSetTimeZone(Script script, const hidl_string& timeZone) {
+    RsScript _script = hidl_to_rs<RsScript>(script);
+    const hidl_string& _timeZone = timeZone;
+    Device::getHal().ScriptSetTimeZone(mContext, _script, _timeZone.c_str(), _timeZone.size());
+    return Void();
+}
+
+Return<void> Context::scriptInvoke(Script vs, uint32_t slot) {
+    RsScript _vs = hidl_to_rs<RsScript>(vs);
+    uint32_t _slot = slot;
+    Device::getHal().ScriptInvoke(mContext, _vs, _slot);
+    return Void();
+}
+
+Return<void> Context::scriptInvokeV(Script vs, uint32_t slot, const hidl_vec<uint8_t>& data) {
+    RsScript _vs = hidl_to_rs<RsScript>(vs);
+    uint32_t _slot = slot;
+    const void* _dataPtr = hidl_to_rs<const void*>(data.data());
+    size_t _len = data.size();
+    Device::getHal().ScriptInvokeV(mContext, _vs, _slot, _dataPtr, _len);
+    return Void();
+}
+
+Return<void> Context::scriptForEach(Script vs, uint32_t slot, const hidl_vec<Allocation>& vains, Allocation vaout, const hidl_vec<uint8_t>& params, Ptr sc) {
+    RsScript _vs = hidl_to_rs<RsScript>(vs);
+    uint32_t _slot = slot;
+    std::vector<RsAllocation> _vains = hidl_to_rs<RsAllocation>(vains, [](Allocation val) { return hidl_to_rs<RsAllocation>(val); });
+    RsAllocation _vaout = hidl_to_rs<RsAllocation>(vaout);
+    const void* _paramsPtr = hidl_to_rs<const void*>(params.data());
+    size_t _paramLen = params.size();
+    const RsScriptCall* _sc = hidl_to_rs<const RsScriptCall*>(sc);
+    size_t _scLen = _sc != nullptr ? sizeof(ScriptCall) : 0;
+    Device::getHal().ScriptForEachMulti(mContext, _vs, _slot, _vains.data(), _vains.size(), _vaout, _paramsPtr, _paramLen, _sc, _scLen);
+    return Void();
+}
+
+Return<void> Context::scriptReduce(Script vs, uint32_t slot, const hidl_vec<Allocation>& vains, Allocation vaout, Ptr sc) {
+    RsScript _vs = hidl_to_rs<RsScript>(vs);
+    uint32_t _slot = slot;
+    std::vector<RsAllocation> _vains = hidl_to_rs<RsAllocation>(vains, [](Allocation val) { return hidl_to_rs<RsAllocation>(val); });
+    RsAllocation _vaout = hidl_to_rs<RsAllocation>(vaout);
+    const RsScriptCall* _sc = hidl_to_rs<const RsScriptCall*>(sc);
+    size_t _scLen = _sc != nullptr ? sizeof(ScriptCall) : 0;
+    Device::getHal().ScriptReduce(mContext, _vs, _slot, _vains.data(), _vains.size(), _vaout, _sc, _scLen);
+    return Void();
+}
+
+Return<void> Context::scriptSetVarI(Script vs, uint32_t slot, int32_t value) {
+    RsScript _vs = hidl_to_rs<RsScript>(vs);
+    uint32_t _slot = slot;
+    int _value = static_cast<int>(value);
+    Device::getHal().ScriptSetVarI(mContext, _vs, _slot, _value);
+    return Void();
+}
+
+Return<void> Context::scriptSetVarObj(Script vs, uint32_t slot, ObjectBase obj) {
+    RsScript _vs = hidl_to_rs<RsScript>(vs);
+    uint32_t _slot = slot;
+    RsObjectBase _obj = hidl_to_rs<RsObjectBase>(obj);
+    Device::getHal().ScriptSetVarObj(mContext, _vs, _slot, _obj);
+    return Void();
+}
+
+Return<void> Context::scriptSetVarJ(Script vs, uint32_t slot, int64_t value) {
+    RsScript _vs = hidl_to_rs<RsScript>(vs);
+    uint32_t _slot = slot;
+    int64_t _value = static_cast<int64_t>(value);
+    Device::getHal().ScriptSetVarJ(mContext, _vs, _slot, _value);
+    return Void();
+}
+
+Return<void> Context::scriptSetVarF(Script vs, uint32_t slot, float value) {
+    RsScript _vs = hidl_to_rs<RsScript>(vs);
+    uint32_t _slot = slot;
+    float _value = value;
+    Device::getHal().ScriptSetVarF(mContext, _vs, _slot, _value);
+    return Void();
+}
+
+Return<void> Context::scriptSetVarD(Script vs, uint32_t slot, double value) {
+    RsScript _vs = hidl_to_rs<RsScript>(vs);
+    uint32_t _slot = slot;
+    double _value = value;
+    Device::getHal().ScriptSetVarD(mContext, _vs, _slot, _value);
+    return Void();
+}
+
+Return<void> Context::scriptSetVarV(Script vs, uint32_t slot, const hidl_vec<uint8_t>& data) {
+    RsScript _vs = hidl_to_rs<RsScript>(vs);
+    uint32_t _slot = slot;
+    const void* _dataPtr = hidl_to_rs<const void*>(data.data());
+    size_t _len = data.size();
+    Device::getHal().ScriptSetVarV(mContext, _vs, _slot, _dataPtr, _len);
+    return Void();
+}
+
+Return<void> Context::scriptGetVarV(Script vs, uint32_t slot, Size len, scriptGetVarV_cb _hidl_cb) {
+    RsScript _vs = hidl_to_rs<RsScript>(vs);
+    uint32_t _slot = slot;
+    size_t _len = static_cast<size_t>(len);
+    std::vector<uint8_t> _data(static_cast<size_t>(len));
+    Device::getHal().ScriptGetVarV(mContext, _vs, _slot, _data.data(), _data.size());
+    hidl_vec<uint8_t> data = _data;
+    _hidl_cb(data);
+    return Void();
+}
+
+Return<void> Context::scriptSetVarVE(Script vs, uint32_t slot, const hidl_vec<uint8_t>& data, Element ve, const hidl_vec<uint32_t>& dims) {
+    RsScript _vs = hidl_to_rs<RsScript>(vs);
+    uint32_t _slot = slot;
+    const void* _dataPtr = hidl_to_rs<const void*>(data.data());
+    size_t _len = data.size();
+    RsElement _ve = hidl_to_rs<RsElement>(ve);
+    const uint32_t* _dimsPtr = dims.data();
+    size_t _dimLen = dims.size();
+    Device::getHal().ScriptSetVarVE(mContext, _vs, _slot, _dataPtr, _len, _ve, _dimsPtr, _dimLen);
+    return Void();
+}
+
+Return<Script> Context::scriptCCreate(const hidl_string& resName, const hidl_string& cacheDir, const hidl_vec<uint8_t>& text) {
+    const hidl_string& _resName = resName;
+    const hidl_string& _cacheDir = cacheDir;
+    const char* _textPtr = hidl_to_rs<const char*>(text.data());
+    size_t _textSize = text.size();
+    RsScript _script = Device::getHal().ScriptCCreate(mContext, _resName.c_str(), _resName.size(), _cacheDir.c_str(), _cacheDir.size(), _textPtr, _textSize);
+    return rs_to_hidl<Script>(_script);
+}
+
+Return<Script> Context::scriptIntrinsicCreate(ScriptIntrinsicID id, Element elem) {
+    RsScriptIntrinsicID _id = static_cast<RsScriptIntrinsicID>(id);
+    RsElement _elem = hidl_to_rs<RsElement>(elem);
+    RsScript _script = Device::getHal().ScriptIntrinsicCreate(mContext, _id, _elem);
+    return rs_to_hidl<Script>(_script);
+}
+
+
+// Methods from ::android::hidl::base::V1_0::IBase follow.
+
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace renderscript
+}  // namespace hardware
+}  // namespace android
