19266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber/*
29266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber * Copyright (C) 2016 The Android Open Source Project
39266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber *
49266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
59266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber * you may not use this file except in compliance with the License.
69266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber * You may obtain a copy of the License at
79266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber *
89266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
99266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber *
109266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber * Unless required by applicable law or agreed to in writing, software
119266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
129266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber * See the License for the specific language governing permissions and
149266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber * limitations under the License.
159266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber */
169266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
179266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber//#define LOG_NDEBUG 0
189266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber#define LOG_TAG "android_os_HwBlob"
199266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber#include <android-base/logging.h>
209266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
219266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber#include "android_os_HwBlob.h"
229266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
239266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber#include "android_os_HwParcel.h"
249266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
259266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber#include <JNIHelp.h>
269266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber#include <android_runtime/AndroidRuntime.h>
27aa2c32f92b199cb40b808554ced67af1edaffef5Martijn Coenen#include <hidl/Status.h>
289266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber#include <nativehelper/ScopedLocalRef.h>
299266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
309266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber#include "core_jni_helpers.h"
319266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
329266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberusing android::AndroidRuntime;
339266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberusing android::hardware::hidl_string;
349266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
359266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber#define PACKAGE_PATH    "android/os"
369266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber#define CLASS_NAME      "HwBlob"
379266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber#define CLASS_PATH      PACKAGE_PATH "/" CLASS_NAME
389266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
399266f9928d5b3431982cd04f4d6946b70f40766aAndreas Hubernamespace android {
409266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
419266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatic struct fields_t {
429266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    jfieldID contextID;
439266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    jmethodID constructID;
449266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
459266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber} gFields;
469266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
479266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber// static
489266f9928d5b3431982cd04f4d6946b70f40766aAndreas Hubervoid JHwBlob::InitClass(JNIEnv *env) {
499266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    ScopedLocalRef<jclass> clazz(
509266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber            env, FindClassOrDie(env, CLASS_PATH));
519266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
529266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    gFields.contextID =
539266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        GetFieldIDOrDie(env, clazz.get(), "mNativeContext", "J");
549266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
559266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    gFields.constructID = GetMethodIDOrDie(env, clazz.get(), "<init>", "(I)V");
569266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
579266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
589266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber// static
599266f9928d5b3431982cd04f4d6946b70f40766aAndreas Hubersp<JHwBlob> JHwBlob::SetNativeContext(
609266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        JNIEnv *env, jobject thiz, const sp<JHwBlob> &context) {
619266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    sp<JHwBlob> old = (JHwBlob *)env->GetLongField(thiz, gFields.contextID);
629266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
639266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if (context != NULL) {
649266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        context->incStrong(NULL /* id */);
659266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
669266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
679266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if (old != NULL) {
689266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        old->decStrong(NULL /* id */);
699266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
709266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
719266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    env->SetLongField(thiz, gFields.contextID, (long)context.get());
729266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
739266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return old;
749266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
759266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
769266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber// static
779266f9928d5b3431982cd04f4d6946b70f40766aAndreas Hubersp<JHwBlob> JHwBlob::GetNativeContext(JNIEnv *env, jobject thiz) {
789266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return (JHwBlob *)env->GetLongField(thiz, gFields.contextID);
799266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
809266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
819266f9928d5b3431982cd04f4d6946b70f40766aAndreas HuberJHwBlob::JHwBlob(JNIEnv *env, jobject thiz, size_t size)
829266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    : mBuffer(nullptr),
839266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber      mSize(size),
849266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber      mOwnsBuffer(true),
859266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber      mHandle(0) {
869266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    jclass clazz = env->GetObjectClass(thiz);
879266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    CHECK(clazz != NULL);
889266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
899266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    mClass = (jclass)env->NewGlobalRef(clazz);
909266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    mObject = env->NewWeakGlobalRef(thiz);
919266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
929266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if (size > 0) {
939266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        mBuffer = malloc(size);
949266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
959266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
969266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
979266f9928d5b3431982cd04f4d6946b70f40766aAndreas HuberJHwBlob::~JHwBlob() {
989266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if (mOwnsBuffer) {
999266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        free(mBuffer);
1009266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        mBuffer = nullptr;
1019266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
1029266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1039266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    JNIEnv *env = AndroidRuntime::getJNIEnv();
1049266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1059266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    env->DeleteWeakGlobalRef(mObject);
1069266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    mObject = NULL;
1079266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1089266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    env->DeleteGlobalRef(mClass);
1099266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    mClass = NULL;
1109266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
1119266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1129266f9928d5b3431982cd04f4d6946b70f40766aAndreas Hubervoid JHwBlob::setTo(const void *ptr, size_t handle) {
1139266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    CHECK_EQ(mSize, 0u);
1149266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    CHECK(mBuffer == nullptr);
1159266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1169266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    mBuffer = const_cast<void *>(ptr);
1179266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    mSize = SIZE_MAX;  // XXX
1189266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    mOwnsBuffer = false;
1199266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    mHandle = handle;
1209266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
1219266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1229266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatus_t JHwBlob::getHandle(size_t *handle) const {
1239266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if (mOwnsBuffer) {
1249266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        return INVALID_OPERATION;
1259266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
1269266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1279266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    *handle = mHandle;
1289266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1299266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return OK;
1309266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
1319266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1329266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatus_t JHwBlob::read(size_t offset, void *data, size_t size) const {
1339266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if (offset + size > mSize) {
1349266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        return -ERANGE;
1359266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
1369266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1379266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    memcpy(data, (const uint8_t *)mBuffer + offset, size);
1389266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1399266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return OK;
1409266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
1419266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1429266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatus_t JHwBlob::write(size_t offset, const void *data, size_t size) {
1439266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if (offset + size > mSize) {
1449266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        return -ERANGE;
1459266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
1469266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1479266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    memcpy((uint8_t *)mBuffer + offset, data, size);
1489266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1499266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return OK;
1509266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
1519266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1529266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatus_t JHwBlob::getString(size_t offset, const hidl_string **s) const {
1539266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if ((offset + sizeof(hidl_string)) > mSize) {
1549266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        return -ERANGE;
1559266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
1569266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1579266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    *s = reinterpret_cast<const hidl_string *>(
1589266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber            (const uint8_t *)mBuffer + offset);
1599266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1609266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return OK;
1619266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
1629266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1639266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberconst void *JHwBlob::data() const {
1649266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return mBuffer;
1659266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
1669266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1679266f9928d5b3431982cd04f4d6946b70f40766aAndreas Hubersize_t JHwBlob::size() const {
1689266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return mSize;
1699266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
1709266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1719266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatus_t JHwBlob::putBlob(size_t offset, const sp<JHwBlob> &blob) {
1729266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    size_t index = mSubBlobs.add();
1739266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    BlobInfo *info = &mSubBlobs.editItemAt(index);
1749266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1759266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    info->mOffset = offset;
1769266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    info->mBlob = blob;
1779266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1789266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    const void *data = blob->data();
1799266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1809266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return write(offset, &data, sizeof(data));
1819266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
1829266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1839266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatus_t JHwBlob::writeToParcel(hardware::Parcel *parcel) const {
1849266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    size_t handle;
1859266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    status_t err = parcel->writeBuffer(data(), size(), &handle);
1869266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1879266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if (err != OK) {
1889266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        return err;
1899266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
1909266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1919266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    for (size_t i = 0; i < mSubBlobs.size(); ++i) {
1929266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        const BlobInfo &info = mSubBlobs[i];
1939266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1949266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        err = info.mBlob->writeEmbeddedToParcel(parcel, handle, info.mOffset);
1959266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
1969266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        if (err != OK) {
1979266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber            return err;
1989266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        }
1999266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
2009266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2019266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return OK;
2029266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
2039266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2049266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatus_t JHwBlob::writeEmbeddedToParcel(
2059266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        hardware::Parcel *parcel,
2069266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        size_t parentHandle,
2079266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        size_t parentOffset) const {
2089266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    size_t handle;
2099266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    status_t err = parcel->writeEmbeddedBuffer(
2109266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber            data(), size(), &handle, parentHandle, parentOffset);
2119266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2129266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if (err != OK) {
2139266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        return err;
2149266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
2159266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2169266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    for (size_t i = 0; i < mSubBlobs.size(); ++i) {
2179266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        const BlobInfo &info = mSubBlobs[i];
2189266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2199266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        err = info.mBlob->writeEmbeddedToParcel(parcel, handle, info.mOffset);
2209266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2219266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        if (err != OK) {
2229266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber            return err;
2239266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        }
2249266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
2259266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2269266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return OK;
2279266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
2289266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2299266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber// static
2309266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberjobject JHwBlob::NewObject(JNIEnv *env, const void *ptr, size_t handle) {
2319266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    jobject obj = JHwBlob::NewObject(env, 0 /* size */);
2329266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    JHwBlob::GetNativeContext(env, obj)->setTo(ptr, handle);
2339266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2349266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return obj;
2359266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
2369266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2379266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber// static
2389266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberjobject JHwBlob::NewObject(JNIEnv *env, size_t size) {
2399266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    ScopedLocalRef<jclass> clazz(env, FindClassOrDie(env, CLASS_PATH));
2409266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2419266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    jmethodID constructID =
2429266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        GetMethodIDOrDie(env, clazz.get(), "<init>", "(I)V");
2439266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2449266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    // XXX Again cannot refer to gFields.constructID because InitClass may
2459266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    // not have been called yet.
2469266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2479266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return env->NewObject(clazz.get(), constructID, size);
2489266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
2499266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2509266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}  // namespace android
2519266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2529266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber////////////////////////////////////////////////////////////////////////////////
2539266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2549266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberusing namespace android;
2559266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2569266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatic void releaseNativeContext(void *nativeContext) {
2579266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    sp<JHwBlob> parcel = (JHwBlob *)nativeContext;
2589266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2599266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if (parcel != NULL) {
2609266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        parcel->decStrong(NULL /* id */);
2619266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
2629266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
2639266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2649266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatic jlong JHwBlob_native_init(JNIEnv *env) {
2659266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    JHwBlob::InitClass(env);
2669266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2679266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return reinterpret_cast<jlong>(&releaseNativeContext);
2689266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
2699266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2709266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatic void JHwBlob_native_setup(
2719266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        JNIEnv *env, jobject thiz, jint size) {
2729266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    sp<JHwBlob> context = new JHwBlob(env, thiz, size);
2739266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2749266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    JHwBlob::SetNativeContext(env, thiz, context);
2759266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
2769266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2779266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber#define DEFINE_BLOB_GETTER(Suffix,Type)                                        \
2789266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatic Type JHwBlob_native_get ## Suffix(                                      \
2799266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        JNIEnv *env, jobject thiz, jlong offset) {                             \
2809266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);                   \
2819266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber                                                                               \
2829266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    Type x;                                                                    \
2839266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    status_t err = blob->read(offset, &x, sizeof(x));                          \
2849266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber                                                                               \
2859266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if (err != OK) {                                                           \
2869266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        signalExceptionForError(env, err);                                     \
2879266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        return 0;                                                              \
2889266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }                                                                          \
2899266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber                                                                               \
2909266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return x;                                                                  \
2919266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
2929266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2939266f9928d5b3431982cd04f4d6946b70f40766aAndreas HuberDEFINE_BLOB_GETTER(Int8,jbyte)
2949266f9928d5b3431982cd04f4d6946b70f40766aAndreas HuberDEFINE_BLOB_GETTER(Int16,jshort)
2959266f9928d5b3431982cd04f4d6946b70f40766aAndreas HuberDEFINE_BLOB_GETTER(Int32,jint)
2969266f9928d5b3431982cd04f4d6946b70f40766aAndreas HuberDEFINE_BLOB_GETTER(Int64,jlong)
2979266f9928d5b3431982cd04f4d6946b70f40766aAndreas HuberDEFINE_BLOB_GETTER(Float,jfloat)
2989266f9928d5b3431982cd04f4d6946b70f40766aAndreas HuberDEFINE_BLOB_GETTER(Double,jdouble)
2999266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3009266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatic jboolean JHwBlob_native_getBool(
3019266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        JNIEnv *env, jobject thiz, jlong offset) {
3029266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
3039266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3049266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    bool x;
3059266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    status_t err = blob->read(offset, &x, sizeof(x));
3069266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3079266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if (err != OK) {
3089266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        signalExceptionForError(env, err);
3099266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        return 0;
3109266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
3119266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3129266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return (jboolean)x;
3139266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
3149266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3159266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatic jstring JHwBlob_native_getString(
3169266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        JNIEnv *env, jobject thiz, jlong offset) {
3179266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
3189266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3199266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    const hidl_string *s;
3209266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    status_t err = blob->getString(offset, &s);
3219266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3229266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if (err != OK) {
3239266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        signalExceptionForError(env, err);
3249266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        return nullptr;
3259266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
3269266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3279266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return env->NewStringUTF(s->c_str());
3289266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
3299266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3309266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber#define DEFINE_BLOB_PUTTER(Suffix,Type)                                        \
3319266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatic void JHwBlob_native_put ## Suffix(                                      \
3329266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        JNIEnv *env, jobject thiz, jlong offset, Type x) {                     \
3339266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber                                                                               \
3349266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);                   \
3359266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber                                                                               \
3369266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    status_t err = blob->write(offset, &x, sizeof(x));                         \
3379266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber                                                                               \
3389266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if (err != OK) {                                                           \
3399266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        signalExceptionForError(env, err);                                     \
3409266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }                                                                          \
3419266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
3429266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3439266f9928d5b3431982cd04f4d6946b70f40766aAndreas HuberDEFINE_BLOB_PUTTER(Int8,jbyte)
3449266f9928d5b3431982cd04f4d6946b70f40766aAndreas HuberDEFINE_BLOB_PUTTER(Int16,jshort)
3459266f9928d5b3431982cd04f4d6946b70f40766aAndreas HuberDEFINE_BLOB_PUTTER(Int32,jint)
3469266f9928d5b3431982cd04f4d6946b70f40766aAndreas HuberDEFINE_BLOB_PUTTER(Int64,jlong)
3479266f9928d5b3431982cd04f4d6946b70f40766aAndreas HuberDEFINE_BLOB_PUTTER(Float,jfloat)
3489266f9928d5b3431982cd04f4d6946b70f40766aAndreas HuberDEFINE_BLOB_PUTTER(Double,jdouble)
3499266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3509266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatic void JHwBlob_native_putBool(
3519266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        JNIEnv *env, jobject thiz, jlong offset, jboolean x) {
3529266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3539266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
3549266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3559266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    bool b = (bool)x;
3569266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    status_t err = blob->write(offset, &b, sizeof(b));
3579266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3589266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if (err != OK) {
3599266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        signalExceptionForError(env, err);
3609266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
3619266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
3629266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3639266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatic void JHwBlob_native_putString(
3649266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        JNIEnv *env, jobject thiz, jlong offset, jstring stringObj) {
3659266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if (stringObj == nullptr) {
3669266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        jniThrowException(env, "java/lang/NullPointerException", nullptr);
3679266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        return;
3689266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
3699266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3709266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    const char *s = env->GetStringUTFChars(stringObj, nullptr);
3719266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3729266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if (s == nullptr) {
3739266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        return;
3749266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
3759266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3769266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    size_t size = strlen(s) + 1;
3779266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    ScopedLocalRef<jobject> subBlobObj(env, JHwBlob::NewObject(env, size));
3789266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    sp<JHwBlob> subBlob = JHwBlob::GetNativeContext(env, subBlobObj.get());
3799266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    subBlob->write(0 /* offset */, s, size);
3809266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3819266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    env->ReleaseStringUTFChars(stringObj, s);
3829266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    s = nullptr;
3839266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3849266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    hidl_string tmp;
3857e6031116248237303ce361bea4db96f2ee4ff4cAndreas Huber    tmp.setToExternal(static_cast<const char *>(subBlob->data()), size - 1);
3869266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3879266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
3889266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    blob->write(offset, &tmp, sizeof(tmp));
3899266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    blob->putBlob(offset + hidl_string::kOffsetOfBuffer, subBlob);
3909266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
3919266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3929266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatic void JHwBlob_native_putBlob(
3939266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        JNIEnv *env, jobject thiz, jlong offset, jobject blobObj) {
3949266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if (blobObj == nullptr) {
3959266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        jniThrowException(env, "java/lang/NullPointerException", nullptr);
3969266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        return;
3979266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
3989266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
3999266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
4009266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    sp<JHwBlob> subBlob = JHwBlob::GetNativeContext(env, blobObj);
4019266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
4029266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    blob->putBlob(offset, subBlob);
4039266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
4049266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
4059266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatic jlong JHwBlob_native_handle(JNIEnv *env, jobject thiz) {
4069266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    size_t handle;
4079266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    status_t err = JHwBlob::GetNativeContext(env, thiz)->getHandle(&handle);
4089266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
4099266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if (err != OK) {
4109266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        signalExceptionForError(env, err);
4119266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        return 0;
4129266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
4139266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
4149266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return handle;
4159266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
4169266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
4179266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatic JNINativeMethod gMethods[] = {
4189266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    { "native_init", "()J", (void *)JHwBlob_native_init },
4199266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    { "native_setup", "(I)V", (void *)JHwBlob_native_setup },
4209266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
4219266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    { "getBool", "(J)Z", (void *)JHwBlob_native_getBool },
4229266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    { "getInt8", "(J)B", (void *)JHwBlob_native_getInt8 },
4239266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    { "getInt16", "(J)S", (void *)JHwBlob_native_getInt16 },
4249266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    { "getInt32", "(J)I", (void *)JHwBlob_native_getInt32 },
4259266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    { "getInt64", "(J)J", (void *)JHwBlob_native_getInt64 },
4269266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    { "getFloat", "(J)F", (void *)JHwBlob_native_getFloat },
4279266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    { "getDouble", "(J)D", (void *)JHwBlob_native_getDouble },
4289266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    { "getString", "(J)Ljava/lang/String;", (void *)JHwBlob_native_getString },
4299266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
4309266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    { "putBool", "(JZ)V", (void *)JHwBlob_native_putBool },
4319266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    { "putInt8", "(JB)V", (void *)JHwBlob_native_putInt8 },
4329266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    { "putInt16", "(JS)V", (void *)JHwBlob_native_putInt16 },
4339266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    { "putInt32", "(JI)V", (void *)JHwBlob_native_putInt32 },
4349266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    { "putInt64", "(JJ)V", (void *)JHwBlob_native_putInt64 },
4359266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    { "putFloat", "(JF)V", (void *)JHwBlob_native_putFloat },
4369266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    { "putDouble", "(JD)V", (void *)JHwBlob_native_putDouble },
4379266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    { "putString", "(JLjava/lang/String;)V", (void *)JHwBlob_native_putString },
4389266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
4399266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    { "putBlob", "(JL" PACKAGE_PATH "/HwBlob;)V",
4409266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        (void *)JHwBlob_native_putBlob },
4419266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
4429266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    { "handle", "()J", (void *)JHwBlob_native_handle },
4439266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber};
4449266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
4459266f9928d5b3431982cd04f4d6946b70f40766aAndreas Hubernamespace android {
4469266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
4479266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberint register_android_os_HwBlob(JNIEnv *env) {
4489266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return RegisterMethodsOrDie(env, CLASS_PATH, gMethods, NELEM(gMethods));
4499266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
4509266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
4519266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}  // namespace android
4529266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
453