blob: 0fb29111d0438c0a18eae05732165a2a7108bbeb [file] [log] [blame]
Andreas Huber9266f992016-08-25 11:21:21 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "android_os_HwBlob"
19#include <android-base/logging.h>
20
21#include "android_os_HwBlob.h"
22
23#include "android_os_HwParcel.h"
Nirav Atre9850dd92018-07-24 17:03:44 -070024#include "android_os_NativeHandle.h"
Andreas Huber9266f992016-08-25 11:21:21 -070025
Steven Moreland2279b252017-07-19 09:50:45 -070026#include <nativehelper/JNIHelp.h>
Andreas Huber9266f992016-08-25 11:21:21 -070027#include <android_runtime/AndroidRuntime.h>
Martijn Coenenaa2c32f2016-09-01 01:37:05 +020028#include <hidl/Status.h>
Andreas Huber9266f992016-08-25 11:21:21 -070029#include <nativehelper/ScopedLocalRef.h>
Andreas Huber2631df72017-11-01 10:19:44 -070030#include <nativehelper/ScopedPrimitiveArray.h>
Andreas Huber9266f992016-08-25 11:21:21 -070031
32#include "core_jni_helpers.h"
33
34using android::AndroidRuntime;
Nirav Atre9850dd92018-07-24 17:03:44 -070035using android::hardware::hidl_handle;
Andreas Huber9266f992016-08-25 11:21:21 -070036using android::hardware::hidl_string;
37
38#define PACKAGE_PATH "android/os"
39#define CLASS_NAME "HwBlob"
40#define CLASS_PATH PACKAGE_PATH "/" CLASS_NAME
41
42namespace android {
43
44static struct fields_t {
45 jfieldID contextID;
46 jmethodID constructID;
47
48} gFields;
49
50// static
51void JHwBlob::InitClass(JNIEnv *env) {
52 ScopedLocalRef<jclass> clazz(
53 env, FindClassOrDie(env, CLASS_PATH));
54
55 gFields.contextID =
56 GetFieldIDOrDie(env, clazz.get(), "mNativeContext", "J");
57
58 gFields.constructID = GetMethodIDOrDie(env, clazz.get(), "<init>", "(I)V");
59}
60
61// static
62sp<JHwBlob> JHwBlob::SetNativeContext(
63 JNIEnv *env, jobject thiz, const sp<JHwBlob> &context) {
64 sp<JHwBlob> old = (JHwBlob *)env->GetLongField(thiz, gFields.contextID);
65
Andreas Huber0eb37e02017-10-31 11:51:50 -070066 if (context != nullptr) {
67 context->incStrong(nullptr /* id */);
Andreas Huber9266f992016-08-25 11:21:21 -070068 }
69
Andreas Huber0eb37e02017-10-31 11:51:50 -070070 if (old != nullptr) {
71 old->decStrong(nullptr /* id */);
Andreas Huber9266f992016-08-25 11:21:21 -070072 }
73
74 env->SetLongField(thiz, gFields.contextID, (long)context.get());
75
76 return old;
77}
78
79// static
80sp<JHwBlob> JHwBlob::GetNativeContext(JNIEnv *env, jobject thiz) {
81 return (JHwBlob *)env->GetLongField(thiz, gFields.contextID);
82}
83
84JHwBlob::JHwBlob(JNIEnv *env, jobject thiz, size_t size)
85 : mBuffer(nullptr),
86 mSize(size),
Nirav Atre9850dd92018-07-24 17:03:44 -070087 mType(BlobType::GENERIC),
Andreas Huber9266f992016-08-25 11:21:21 -070088 mOwnsBuffer(true),
89 mHandle(0) {
Andreas Huber9266f992016-08-25 11:21:21 -070090 if (size > 0) {
Steven Moreland45ec7bb2019-04-18 16:32:42 -070091 mBuffer = calloc(size, 1);
Andreas Huber9266f992016-08-25 11:21:21 -070092 }
93}
94
95JHwBlob::~JHwBlob() {
96 if (mOwnsBuffer) {
97 free(mBuffer);
98 mBuffer = nullptr;
99 }
Andreas Huber9266f992016-08-25 11:21:21 -0700100}
101
102void JHwBlob::setTo(const void *ptr, size_t handle) {
103 CHECK_EQ(mSize, 0u);
104 CHECK(mBuffer == nullptr);
105
106 mBuffer = const_cast<void *>(ptr);
107 mSize = SIZE_MAX; // XXX
108 mOwnsBuffer = false;
109 mHandle = handle;
110}
111
112status_t JHwBlob::getHandle(size_t *handle) const {
113 if (mOwnsBuffer) {
114 return INVALID_OPERATION;
115 }
116
117 *handle = mHandle;
118
119 return OK;
120}
121
122status_t JHwBlob::read(size_t offset, void *data, size_t size) const {
123 if (offset + size > mSize) {
124 return -ERANGE;
125 }
126
127 memcpy(data, (const uint8_t *)mBuffer + offset, size);
128
129 return OK;
130}
131
132status_t JHwBlob::write(size_t offset, const void *data, size_t size) {
133 if (offset + size > mSize) {
134 return -ERANGE;
135 }
136
137 memcpy((uint8_t *)mBuffer + offset, data, size);
138
139 return OK;
140}
141
142status_t JHwBlob::getString(size_t offset, const hidl_string **s) const {
143 if ((offset + sizeof(hidl_string)) > mSize) {
144 return -ERANGE;
145 }
146
147 *s = reinterpret_cast<const hidl_string *>(
148 (const uint8_t *)mBuffer + offset);
149
150 return OK;
151}
152
153const void *JHwBlob::data() const {
154 return mBuffer;
155}
156
Andreas Huber0eb37e02017-10-31 11:51:50 -0700157void *JHwBlob::data() {
158 return mBuffer;
159}
160
Andreas Huber9266f992016-08-25 11:21:21 -0700161size_t JHwBlob::size() const {
162 return mSize;
163}
164
Nirav Atre9850dd92018-07-24 17:03:44 -0700165void JHwBlob::specializeBlobTo(BlobType type) {
166 CHECK_EQ(static_cast<int>(mType), static_cast<int>(BlobType::GENERIC));
167 mType = type;
168}
169
170JHwBlob::BlobType JHwBlob::type() const {
171 return mType;
172}
173
Andreas Huber9266f992016-08-25 11:21:21 -0700174status_t JHwBlob::putBlob(size_t offset, const sp<JHwBlob> &blob) {
175 size_t index = mSubBlobs.add();
176 BlobInfo *info = &mSubBlobs.editItemAt(index);
177
178 info->mOffset = offset;
179 info->mBlob = blob;
180
181 const void *data = blob->data();
182
183 return write(offset, &data, sizeof(data));
184}
185
186status_t JHwBlob::writeToParcel(hardware::Parcel *parcel) const {
Nirav Atre9850dd92018-07-24 17:03:44 -0700187 CHECK_EQ(static_cast<int>(mType), static_cast<int>(BlobType::GENERIC));
188
189 size_t handle = 0;
Andreas Huber9266f992016-08-25 11:21:21 -0700190 status_t err = parcel->writeBuffer(data(), size(), &handle);
191
192 if (err != OK) {
193 return err;
194 }
195
Nirav Atre9850dd92018-07-24 17:03:44 -0700196 return writeSubBlobsToParcel(parcel, handle);
Andreas Huber9266f992016-08-25 11:21:21 -0700197}
198
199status_t JHwBlob::writeEmbeddedToParcel(
200 hardware::Parcel *parcel,
201 size_t parentHandle,
202 size_t parentOffset) const {
Nirav Atre9850dd92018-07-24 17:03:44 -0700203 size_t handle = 0;
204 status_t err = OK;
205
206 switch (mType) {
207 case BlobType::GENERIC: {
208 err = parcel->writeEmbeddedBuffer(data(), size(), &handle, parentHandle, parentOffset);
209 break;
210 }
211 case BlobType::NATIVE_HANDLE: {
212 err = parcel->writeEmbeddedNativeHandle(
213 static_cast<const native_handle *>(data()), parentHandle, parentOffset);
214
215 CHECK(mSubBlobs.empty());
216 break;
217 }
218 default: { err = INVALID_OPERATION; }
219 }
Andreas Huber9266f992016-08-25 11:21:21 -0700220
221 if (err != OK) {
222 return err;
223 }
224
Nirav Atre9850dd92018-07-24 17:03:44 -0700225 return writeSubBlobsToParcel(parcel, handle);
226}
227
228status_t JHwBlob::writeSubBlobsToParcel(hardware::Parcel *parcel,
229 size_t parentHandle) const {
Andreas Huber9266f992016-08-25 11:21:21 -0700230 for (size_t i = 0; i < mSubBlobs.size(); ++i) {
231 const BlobInfo &info = mSubBlobs[i];
Nirav Atre9850dd92018-07-24 17:03:44 -0700232 status_t err = info.mBlob->writeEmbeddedToParcel(parcel, parentHandle, info.mOffset);
Andreas Huber9266f992016-08-25 11:21:21 -0700233
234 if (err != OK) {
235 return err;
236 }
237 }
238
239 return OK;
240}
241
242// static
243jobject JHwBlob::NewObject(JNIEnv *env, const void *ptr, size_t handle) {
244 jobject obj = JHwBlob::NewObject(env, 0 /* size */);
245 JHwBlob::GetNativeContext(env, obj)->setTo(ptr, handle);
246
247 return obj;
248}
249
250// static
251jobject JHwBlob::NewObject(JNIEnv *env, size_t size) {
252 ScopedLocalRef<jclass> clazz(env, FindClassOrDie(env, CLASS_PATH));
253
254 jmethodID constructID =
255 GetMethodIDOrDie(env, clazz.get(), "<init>", "(I)V");
256
257 // XXX Again cannot refer to gFields.constructID because InitClass may
258 // not have been called yet.
259
260 return env->NewObject(clazz.get(), constructID, size);
261}
262
263} // namespace android
264
265////////////////////////////////////////////////////////////////////////////////
266
267using namespace android;
268
269static void releaseNativeContext(void *nativeContext) {
270 sp<JHwBlob> parcel = (JHwBlob *)nativeContext;
271
Andreas Huber0eb37e02017-10-31 11:51:50 -0700272 if (parcel != nullptr) {
273 parcel->decStrong(nullptr /* id */);
Andreas Huber9266f992016-08-25 11:21:21 -0700274 }
275}
276
Nirav Atre9850dd92018-07-24 17:03:44 -0700277static jlong JHwBlob_native_init(JNIEnv *env, jclass /*clazz*/) {
Andreas Huber9266f992016-08-25 11:21:21 -0700278 JHwBlob::InitClass(env);
279
280 return reinterpret_cast<jlong>(&releaseNativeContext);
281}
282
283static void JHwBlob_native_setup(
284 JNIEnv *env, jobject thiz, jint size) {
285 sp<JHwBlob> context = new JHwBlob(env, thiz, size);
286
287 JHwBlob::SetNativeContext(env, thiz, context);
288}
289
290#define DEFINE_BLOB_GETTER(Suffix,Type) \
291static Type JHwBlob_native_get ## Suffix( \
292 JNIEnv *env, jobject thiz, jlong offset) { \
293 sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz); \
294 \
295 Type x; \
296 status_t err = blob->read(offset, &x, sizeof(x)); \
297 \
298 if (err != OK) { \
299 signalExceptionForError(env, err); \
300 return 0; \
301 } \
302 \
303 return x; \
304}
305
306DEFINE_BLOB_GETTER(Int8,jbyte)
307DEFINE_BLOB_GETTER(Int16,jshort)
308DEFINE_BLOB_GETTER(Int32,jint)
309DEFINE_BLOB_GETTER(Int64,jlong)
310DEFINE_BLOB_GETTER(Float,jfloat)
311DEFINE_BLOB_GETTER(Double,jdouble)
312
313static jboolean JHwBlob_native_getBool(
314 JNIEnv *env, jobject thiz, jlong offset) {
315 sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
316
317 bool x;
318 status_t err = blob->read(offset, &x, sizeof(x));
319
320 if (err != OK) {
321 signalExceptionForError(env, err);
322 return 0;
323 }
324
325 return (jboolean)x;
326}
327
328static jstring JHwBlob_native_getString(
329 JNIEnv *env, jobject thiz, jlong offset) {
330 sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
331
332 const hidl_string *s;
333 status_t err = blob->getString(offset, &s);
334
335 if (err != OK) {
336 signalExceptionForError(env, err);
337 return nullptr;
338 }
339
340 return env->NewStringUTF(s->c_str());
341}
342
Ytai Ben-Tsvi4659e182019-11-06 09:53:34 -0800343static jlong JHwBlob_native_getFieldHandle(JNIEnv* env,
344 jobject thiz,
345 jlong offset) {
346 sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
347
348 return reinterpret_cast<jlong>(blob->data()) + offset;
349}
350
Andreas Huber0eb37e02017-10-31 11:51:50 -0700351#define DEFINE_BLOB_ARRAY_COPIER(Suffix,Type,NewType) \
352static void JHwBlob_native_copyTo ## Suffix ## Array( \
353 JNIEnv *env, \
354 jobject thiz, \
355 jlong offset, \
356 Type ## Array array, \
357 jint size) { \
358 if (array == nullptr) { \
359 jniThrowException(env, "java/lang/NullPointerException", nullptr); \
360 return; \
361 } \
362 \
363 if (env->GetArrayLength(array) < size) { \
364 signalExceptionForError(env, BAD_VALUE); \
365 return; \
366 } \
367 \
368 sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz); \
369 \
370 if ((offset + size * sizeof(Type)) > blob->size()) { \
371 signalExceptionForError(env, -ERANGE); \
372 return; \
373 } \
374 \
375 env->Set ## NewType ## ArrayRegion( \
376 array, \
377 0 /* start */, \
378 size, \
379 reinterpret_cast<const Type *>( \
380 static_cast<const uint8_t *>(blob->data()) + offset)); \
381}
382
Andreas Huber2631df72017-11-01 10:19:44 -0700383DEFINE_BLOB_ARRAY_COPIER(Int8,jbyte,Byte)
384DEFINE_BLOB_ARRAY_COPIER(Int16,jshort,Short)
385DEFINE_BLOB_ARRAY_COPIER(Int32,jint,Int)
386DEFINE_BLOB_ARRAY_COPIER(Int64,jlong,Long)
387DEFINE_BLOB_ARRAY_COPIER(Float,jfloat,Float)
388DEFINE_BLOB_ARRAY_COPIER(Double,jdouble,Double)
389
Andreas Huber0eb37e02017-10-31 11:51:50 -0700390static void JHwBlob_native_copyToBoolArray(
391 JNIEnv *env,
392 jobject thiz,
393 jlong offset,
394 jbooleanArray array,
395 jint size) {
396 if (array == nullptr) {
397 jniThrowException(env, "java/lang/NullPointerException", nullptr);
398 return;
399 }
400
401 if (env->GetArrayLength(array) < size) {
402 signalExceptionForError(env, BAD_VALUE);
403 return;
404 }
405
406 sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
407
408 if ((offset + size * sizeof(bool)) > blob->size()) {
409 signalExceptionForError(env, -ERANGE);
410 return;
411 }
412
413 const bool *src =
414 reinterpret_cast<const bool *>(
415 static_cast<const uint8_t *>(blob->data()) + offset);
416
417 jboolean *dst = env->GetBooleanArrayElements(array, nullptr /* isCopy */);
418
419 for (jint i = 0; i < size; ++i) {
420 dst[i] = src[i];
421 }
422
423 env->ReleaseBooleanArrayElements(array, dst, 0 /* mode */);
424 dst = nullptr;
425}
426
Andreas Huber9266f992016-08-25 11:21:21 -0700427#define DEFINE_BLOB_PUTTER(Suffix,Type) \
428static void JHwBlob_native_put ## Suffix( \
429 JNIEnv *env, jobject thiz, jlong offset, Type x) { \
430 \
431 sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz); \
432 \
433 status_t err = blob->write(offset, &x, sizeof(x)); \
434 \
435 if (err != OK) { \
436 signalExceptionForError(env, err); \
437 } \
438}
439
440DEFINE_BLOB_PUTTER(Int8,jbyte)
441DEFINE_BLOB_PUTTER(Int16,jshort)
442DEFINE_BLOB_PUTTER(Int32,jint)
443DEFINE_BLOB_PUTTER(Int64,jlong)
444DEFINE_BLOB_PUTTER(Float,jfloat)
445DEFINE_BLOB_PUTTER(Double,jdouble)
446
447static void JHwBlob_native_putBool(
448 JNIEnv *env, jobject thiz, jlong offset, jboolean x) {
449
450 sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
451
452 bool b = (bool)x;
453 status_t err = blob->write(offset, &b, sizeof(b));
454
455 if (err != OK) {
456 signalExceptionForError(env, err);
457 }
458}
459
460static void JHwBlob_native_putString(
461 JNIEnv *env, jobject thiz, jlong offset, jstring stringObj) {
462 if (stringObj == nullptr) {
463 jniThrowException(env, "java/lang/NullPointerException", nullptr);
464 return;
465 }
466
467 const char *s = env->GetStringUTFChars(stringObj, nullptr);
468
469 if (s == nullptr) {
470 return;
471 }
472
473 size_t size = strlen(s) + 1;
474 ScopedLocalRef<jobject> subBlobObj(env, JHwBlob::NewObject(env, size));
475 sp<JHwBlob> subBlob = JHwBlob::GetNativeContext(env, subBlobObj.get());
476 subBlob->write(0 /* offset */, s, size);
477
478 env->ReleaseStringUTFChars(stringObj, s);
479 s = nullptr;
480
481 hidl_string tmp;
Andreas Huber7e603112017-02-06 11:49:26 -0800482 tmp.setToExternal(static_cast<const char *>(subBlob->data()), size - 1);
Andreas Huber9266f992016-08-25 11:21:21 -0700483
484 sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
485 blob->write(offset, &tmp, sizeof(tmp));
486 blob->putBlob(offset + hidl_string::kOffsetOfBuffer, subBlob);
487}
488
Nirav Atre9850dd92018-07-24 17:03:44 -0700489static void JHwBlob_native_putNativeHandle(JNIEnv *env, jobject thiz,
490 jlong offset, jobject jHandle) {
491 std::unique_ptr<native_handle_t, int(*)(native_handle_t*)> nativeHandle(
492 JNativeHandle::MakeCppNativeHandle(env, jHandle, nullptr /* storage */),
493 native_handle_delete);
494
495 size_t size = 0;
496 if (nativeHandle != nullptr) {
497 size = sizeof(native_handle_t) + nativeHandle->numFds * sizeof(int)
498 + nativeHandle->numInts * sizeof(int);
499 }
500
501 ScopedLocalRef<jobject> subBlobObj(env, JHwBlob::NewObject(env, size));
502 sp<JHwBlob> subBlob = JHwBlob::GetNativeContext(env, subBlobObj.get());
503 subBlob->specializeBlobTo(JHwBlob::BlobType::NATIVE_HANDLE);
504 subBlob->write(0 /* offset */, nativeHandle.get(), size);
505
506 hidl_handle cppHandle;
507 cppHandle.setTo(static_cast<native_handle_t *>(subBlob->data()), false /* shouldOwn */);
508
509 sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
510 blob->write(offset, &cppHandle, sizeof(cppHandle));
511 blob->putBlob(offset + hidl_handle::kOffsetOfNativeHandle, subBlob);
512}
513
Andreas Huber0eb37e02017-10-31 11:51:50 -0700514#define DEFINE_BLOB_ARRAY_PUTTER(Suffix,Type,NewType) \
515static void JHwBlob_native_put ## Suffix ## Array( \
516 JNIEnv *env, jobject thiz, jlong offset, Type ## Array array) { \
Andreas Huber2631df72017-11-01 10:19:44 -0700517 Scoped ## NewType ## ArrayRO autoArray(env, array); \
Andreas Huber0eb37e02017-10-31 11:51:50 -0700518 \
519 if (array == nullptr) { \
Andreas Huber2631df72017-11-01 10:19:44 -0700520 /* NullpointerException already pending */ \
Andreas Huber0eb37e02017-10-31 11:51:50 -0700521 return; \
522 } \
523 \
524 sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz); \
525 \
Andreas Huber2631df72017-11-01 10:19:44 -0700526 status_t err = blob->write( \
527 offset, autoArray.get(), autoArray.size() * sizeof(Type)); \
Andreas Huber0eb37e02017-10-31 11:51:50 -0700528 \
529 if (err != OK) { \
530 signalExceptionForError(env, err); \
531 } \
532}
533
534DEFINE_BLOB_ARRAY_PUTTER(Int8,jbyte,Byte)
535DEFINE_BLOB_ARRAY_PUTTER(Int16,jshort,Short)
536DEFINE_BLOB_ARRAY_PUTTER(Int32,jint,Int)
537DEFINE_BLOB_ARRAY_PUTTER(Int64,jlong,Long)
538DEFINE_BLOB_ARRAY_PUTTER(Float,jfloat,Float)
539DEFINE_BLOB_ARRAY_PUTTER(Double,jdouble,Double)
540
541static void JHwBlob_native_putBoolArray(
542 JNIEnv *env, jobject thiz, jlong offset, jbooleanArray array) {
Andreas Huber2631df72017-11-01 10:19:44 -0700543 ScopedBooleanArrayRO autoArray(env, array);
Andreas Huber0eb37e02017-10-31 11:51:50 -0700544
545 if (array == nullptr) {
Andreas Huber2631df72017-11-01 10:19:44 -0700546 /* NullpointerException already pending */
Andreas Huber0eb37e02017-10-31 11:51:50 -0700547 return;
548 }
549
550 sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
551
Andreas Huber2631df72017-11-01 10:19:44 -0700552 if ((offset + autoArray.size() * sizeof(bool)) > blob->size()) {
Andreas Huber0eb37e02017-10-31 11:51:50 -0700553 signalExceptionForError(env, -ERANGE);
554 return;
555 }
556
Andreas Huber2631df72017-11-01 10:19:44 -0700557 const jboolean *src = autoArray.get();
Andreas Huber0eb37e02017-10-31 11:51:50 -0700558
559 bool *dst = reinterpret_cast<bool *>(
560 static_cast<uint8_t *>(blob->data()) + offset);
561
Andreas Huber2631df72017-11-01 10:19:44 -0700562 for (size_t i = 0; i < autoArray.size(); ++i) {
Andreas Huber0eb37e02017-10-31 11:51:50 -0700563 dst[i] = src[i];
564 }
Andreas Huber0eb37e02017-10-31 11:51:50 -0700565}
566
Andreas Huber9266f992016-08-25 11:21:21 -0700567static void JHwBlob_native_putBlob(
568 JNIEnv *env, jobject thiz, jlong offset, jobject blobObj) {
569 if (blobObj == nullptr) {
570 jniThrowException(env, "java/lang/NullPointerException", nullptr);
571 return;
572 }
573
574 sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, thiz);
575 sp<JHwBlob> subBlob = JHwBlob::GetNativeContext(env, blobObj);
576
577 blob->putBlob(offset, subBlob);
578}
579
580static jlong JHwBlob_native_handle(JNIEnv *env, jobject thiz) {
581 size_t handle;
582 status_t err = JHwBlob::GetNativeContext(env, thiz)->getHandle(&handle);
583
584 if (err != OK) {
585 signalExceptionForError(env, err);
586 return 0;
587 }
588
589 return handle;
590}
591
592static JNINativeMethod gMethods[] = {
593 { "native_init", "()J", (void *)JHwBlob_native_init },
594 { "native_setup", "(I)V", (void *)JHwBlob_native_setup },
595
596 { "getBool", "(J)Z", (void *)JHwBlob_native_getBool },
597 { "getInt8", "(J)B", (void *)JHwBlob_native_getInt8 },
598 { "getInt16", "(J)S", (void *)JHwBlob_native_getInt16 },
599 { "getInt32", "(J)I", (void *)JHwBlob_native_getInt32 },
600 { "getInt64", "(J)J", (void *)JHwBlob_native_getInt64 },
601 { "getFloat", "(J)F", (void *)JHwBlob_native_getFloat },
602 { "getDouble", "(J)D", (void *)JHwBlob_native_getDouble },
603 { "getString", "(J)Ljava/lang/String;", (void *)JHwBlob_native_getString },
Ytai Ben-Tsvi4659e182019-11-06 09:53:34 -0800604 { "getFieldHandle", "(J)J", (void*) JHwBlob_native_getFieldHandle},
Andreas Huber9266f992016-08-25 11:21:21 -0700605
Andreas Huber0eb37e02017-10-31 11:51:50 -0700606 { "copyToBoolArray", "(J[ZI)V", (void *)JHwBlob_native_copyToBoolArray },
607 { "copyToInt8Array", "(J[BI)V", (void *)JHwBlob_native_copyToInt8Array },
608 { "copyToInt16Array", "(J[SI)V", (void *)JHwBlob_native_copyToInt16Array },
609 { "copyToInt32Array", "(J[II)V", (void *)JHwBlob_native_copyToInt32Array },
610 { "copyToInt64Array", "(J[JI)V", (void *)JHwBlob_native_copyToInt64Array },
611 { "copyToFloatArray", "(J[FI)V", (void *)JHwBlob_native_copyToFloatArray },
612 { "copyToDoubleArray", "(J[DI)V", (void *)JHwBlob_native_copyToDoubleArray },
613
Andreas Huber9266f992016-08-25 11:21:21 -0700614 { "putBool", "(JZ)V", (void *)JHwBlob_native_putBool },
615 { "putInt8", "(JB)V", (void *)JHwBlob_native_putInt8 },
616 { "putInt16", "(JS)V", (void *)JHwBlob_native_putInt16 },
617 { "putInt32", "(JI)V", (void *)JHwBlob_native_putInt32 },
618 { "putInt64", "(JJ)V", (void *)JHwBlob_native_putInt64 },
619 { "putFloat", "(JF)V", (void *)JHwBlob_native_putFloat },
620 { "putDouble", "(JD)V", (void *)JHwBlob_native_putDouble },
621 { "putString", "(JLjava/lang/String;)V", (void *)JHwBlob_native_putString },
Nirav Atre9850dd92018-07-24 17:03:44 -0700622 { "putNativeHandle", "(JL" PACKAGE_PATH "/NativeHandle;)V",
623 (void*)JHwBlob_native_putNativeHandle },
Andreas Huber9266f992016-08-25 11:21:21 -0700624
Andreas Huber0eb37e02017-10-31 11:51:50 -0700625 { "putBoolArray", "(J[Z)V", (void *)JHwBlob_native_putBoolArray },
626 { "putInt8Array", "(J[B)V", (void *)JHwBlob_native_putInt8Array },
627 { "putInt16Array", "(J[S)V", (void *)JHwBlob_native_putInt16Array },
628 { "putInt32Array", "(J[I)V", (void *)JHwBlob_native_putInt32Array },
629 { "putInt64Array", "(J[J)V", (void *)JHwBlob_native_putInt64Array },
630 { "putFloatArray", "(J[F)V", (void *)JHwBlob_native_putFloatArray },
631 { "putDoubleArray", "(J[D)V", (void *)JHwBlob_native_putDoubleArray },
632
Andreas Huber9266f992016-08-25 11:21:21 -0700633 { "putBlob", "(JL" PACKAGE_PATH "/HwBlob;)V",
634 (void *)JHwBlob_native_putBlob },
635
636 { "handle", "()J", (void *)JHwBlob_native_handle },
637};
638
639namespace android {
640
641int register_android_os_HwBlob(JNIEnv *env) {
642 return RegisterMethodsOrDie(env, CLASS_PATH, gMethods, NELEM(gMethods));
643}
644
645} // namespace android
646