blob: 151dbfce7af327d034afe6c5d97f253b75c8a93f [file] [log] [blame]
Andreas Huberdab5fc62016-08-15 09:25:02 -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_HwParcel"
19#include <android-base/logging.h>
20
21#include "android_os_HwParcel.h"
22
Ytai Ben-Tsvi4659e182019-11-06 09:53:34 -080023#include "android_os_HidlMemory.h"
Andreas Huberdab5fc62016-08-15 09:25:02 -070024#include "android_os_HwBinder.h"
Andreas Huber9266f992016-08-25 11:21:21 -070025#include "android_os_HwBlob.h"
Nirav Atre9850dd92018-07-24 17:03:44 -070026#include "android_os_NativeHandle.h"
Andreas Huberdab5fc62016-08-15 09:25:02 -070027#include "android_os_HwRemoteBinder.h"
28
Steven Moreland2279b252017-07-19 09:50:45 -070029#include <nativehelper/JNIHelp.h>
Andreas Huberdab5fc62016-08-15 09:25:02 -070030#include <android_runtime/AndroidRuntime.h>
Ytai Ben-Tsvi4659e182019-11-06 09:53:34 -080031#include <hidl/HidlBinderSupport.h>
32#include <hidl/HidlSupport.h>
Yifan Hongddf31f62016-11-15 16:02:40 -080033#include <hidl/HidlTransportSupport.h>
Martijn Coenenaa2c32f2016-09-01 01:37:05 +020034#include <hidl/Status.h>
Andreas Huberdab5fc62016-08-15 09:25:02 -070035#include <nativehelper/ScopedLocalRef.h>
36
37#include "core_jni_helpers.h"
38
39using android::AndroidRuntime;
40
Nirav Atre9850dd92018-07-24 17:03:44 -070041using ::android::hardware::hidl_handle;
Andreas Huberdab5fc62016-08-15 09:25:02 -070042using ::android::hardware::hidl_string;
43using ::android::hardware::hidl_vec;
44
45#define PACKAGE_PATH "android/os"
46#define CLASS_NAME "HwParcel"
47#define CLASS_PATH PACKAGE_PATH "/" CLASS_NAME
48
49namespace android {
50
51static struct fields_t {
52 jfieldID contextID;
53 jmethodID constructID;
54
55} gFields;
56
Steven Morelande62b1f32016-12-20 15:55:48 -080057void signalExceptionForError(JNIEnv *env, status_t err, bool canThrowRemoteException) {
Andreas Huberdab5fc62016-08-15 09:25:02 -070058 switch (err) {
59 case OK:
60 break;
61
62 case NO_MEMORY:
63 {
64 jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
65 break;
66 }
67
68 case INVALID_OPERATION:
69 {
70 jniThrowException(
71 env, "java/lang/UnsupportedOperationException", NULL);
72 break;
73 }
74
75 case BAD_VALUE:
76 {
77 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
78 break;
79 }
80
Andreas Huber9266f992016-08-25 11:21:21 -070081 case -ERANGE:
Andreas Huberdab5fc62016-08-15 09:25:02 -070082 case BAD_INDEX:
83 {
84 jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
85 break;
86 }
87
88 case BAD_TYPE:
89 {
90 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
91 break;
92 }
93
94 case NAME_NOT_FOUND:
95 {
96 jniThrowException(env, "java/util/NoSuchElementException", NULL);
97 break;
98 }
99
100 case PERMISSION_DENIED:
101 {
102 jniThrowException(env, "java/lang/SecurityException", NULL);
103 break;
104 }
105
106 case NO_INIT:
107 {
108 jniThrowException(
109 env, "java/lang/RuntimeException", "Not initialized");
110 break;
111 }
112
113 case ALREADY_EXISTS:
114 {
115 jniThrowException(
116 env, "java/lang/RuntimeException", "Item already exists");
117 break;
118 }
119
120 default:
121 {
Steven Morelande62b1f32016-12-20 15:55:48 -0800122 std::stringstream ss;
123 ss << "HwBinder Error: (" << err << ")";
124
Andreas Huberdab5fc62016-08-15 09:25:02 -0700125 jniThrowException(
Steven Morelande62b1f32016-12-20 15:55:48 -0800126 env,
127 canThrowRemoteException ? "android/os/RemoteException" : "java/lang/RuntimeException",
128 ss.str().c_str());
Andreas Huberdab5fc62016-08-15 09:25:02 -0700129
130 break;
131 }
132 }
133}
134
135// static
136void JHwParcel::InitClass(JNIEnv *env) {
137 ScopedLocalRef<jclass> clazz(
138 env, FindClassOrDie(env, CLASS_PATH));
139
140 gFields.contextID =
141 GetFieldIDOrDie(env, clazz.get(), "mNativeContext", "J");
142
143 gFields.constructID = GetMethodIDOrDie(env, clazz.get(), "<init>", "(Z)V");
144}
145
146// static
147sp<JHwParcel> JHwParcel::SetNativeContext(
148 JNIEnv *env, jobject thiz, const sp<JHwParcel> &context) {
149 sp<JHwParcel> old = (JHwParcel *)env->GetLongField(thiz, gFields.contextID);
150
151 if (context != NULL) {
152 context->incStrong(NULL /* id */);
153 }
154
155 if (old != NULL) {
156 old->decStrong(NULL /* id */);
157 }
158
159 env->SetLongField(thiz, gFields.contextID, (long)context.get());
160
161 return old;
162}
163
164// static
165sp<JHwParcel> JHwParcel::GetNativeContext(JNIEnv *env, jobject thiz) {
166 return (JHwParcel *)env->GetLongField(thiz, gFields.contextID);
167}
168
169JHwParcel::JHwParcel(JNIEnv *env, jobject thiz)
170 : mParcel(NULL),
171 mOwnsParcel(false),
172 mTransactCallback(nullptr),
173 mWasSent(false) {
Andreas Huberdab5fc62016-08-15 09:25:02 -0700174}
175
176JHwParcel::~JHwParcel() {
177 JNIEnv *env = AndroidRuntime::getJNIEnv();
178
179 mStorage.release(env);
180
181 setParcel(NULL, false /* assumeOwnership */);
Andreas Huberdab5fc62016-08-15 09:25:02 -0700182}
183
184hardware::Parcel *JHwParcel::getParcel() {
185 return mParcel;
186}
187
188EphemeralStorage *JHwParcel::getStorage() {
189 return &mStorage;
190}
191
192void JHwParcel::setParcel(hardware::Parcel *parcel, bool assumeOwnership) {
193 if (mParcel && mOwnsParcel) {
194 delete mParcel;
195 }
196
197 mParcel = parcel;
198 mOwnsParcel = assumeOwnership;
199}
200
201// static
202jobject JHwParcel::NewObject(JNIEnv *env) {
203 ScopedLocalRef<jclass> clazz(env, FindClassOrDie(env, CLASS_PATH));
204
Andreas Huber9266f992016-08-25 11:21:21 -0700205 jmethodID constructID =
206 GetMethodIDOrDie(env, clazz.get(), "<init>", "(Z)V");
207
208 return env->NewObject(clazz.get(), constructID, false /* allocate */);
Andreas Huberdab5fc62016-08-15 09:25:02 -0700209}
210
211void JHwParcel::setTransactCallback(
212 ::android::hardware::IBinder::TransactCallback cb) {
213 mTransactCallback = cb;
214}
215
216void JHwParcel::send() {
217 CHECK(mTransactCallback != nullptr);
218 CHECK(mParcel != nullptr);
219
220 mTransactCallback(*mParcel);
221 mTransactCallback = nullptr;
222
223 mWasSent = true;
224}
225
226bool JHwParcel::wasSent() const {
227 return mWasSent;
228}
229
230} // namespace android
231
232////////////////////////////////////////////////////////////////////////////////
233
234using namespace android;
235
236static void releaseNativeContext(void *nativeContext) {
237 sp<JHwParcel> parcel = (JHwParcel *)nativeContext;
238
239 if (parcel != NULL) {
240 parcel->decStrong(NULL /* id */);
241 }
242}
243
244static jlong JHwParcel_native_init(JNIEnv *env) {
245 JHwParcel::InitClass(env);
246
247 return reinterpret_cast<jlong>(&releaseNativeContext);
248}
249
250static void JHwParcel_native_setup(
251 JNIEnv *env, jobject thiz, jboolean allocate) {
252 sp<JHwParcel> context = new JHwParcel(env, thiz);
253
254 if (allocate) {
255 context->setParcel(new hardware::Parcel, true /* assumeOwnership */);
256 }
257
258 JHwParcel::SetNativeContext(env, thiz, context);
259}
260
261static void JHwParcel_native_writeInterfaceToken(
262 JNIEnv *env, jobject thiz, jstring interfaceNameObj) {
263 if (interfaceNameObj == NULL) {
264 jniThrowException(env, "java/lang/NullPointerException", NULL);
265 return;
266 }
267
268 const jchar *interfaceName = env->GetStringCritical(interfaceNameObj, NULL);
269 if (interfaceName) {
Steven Morelandab2fca22016-11-11 12:33:41 -0800270 String8 nameCopy = String8(String16(
Andreas Huber9f026862016-11-03 15:46:04 -0700271 reinterpret_cast<const char16_t *>(interfaceName),
Steven Morelandab2fca22016-11-11 12:33:41 -0800272 env->GetStringLength(interfaceNameObj)));
Andreas Huberdab5fc62016-08-15 09:25:02 -0700273
274 env->ReleaseStringCritical(interfaceNameObj, interfaceName);
275 interfaceName = NULL;
276
Andreas Huber9f026862016-11-03 15:46:04 -0700277 hardware::Parcel *parcel =
278 JHwParcel::GetNativeContext(env, thiz)->getParcel();
279
Steven Morelandab2fca22016-11-11 12:33:41 -0800280 status_t err = parcel->writeInterfaceToken(nameCopy.string());
Andreas Huberdab5fc62016-08-15 09:25:02 -0700281 signalExceptionForError(env, err);
282 }
283}
284
285static void JHwParcel_native_enforceInterface(
286 JNIEnv *env, jobject thiz, jstring interfaceNameObj) {
287 // XXX original binder Parcel enforceInterface implementation does some
288 // mysterious things regarding strictModePolicy(), figure out if we need
289 // that here as well.
290 if (interfaceNameObj == NULL) {
291 jniThrowException(env, "java/lang/NullPointerException", NULL);
292 return;
293 }
294
295 const jchar *interfaceName = env->GetStringCritical(interfaceNameObj, NULL);
296 if (interfaceName) {
Steven Morelandab2fca22016-11-11 12:33:41 -0800297 String8 interfaceNameCopy = String8(String16(
Andreas Huber9f026862016-11-03 15:46:04 -0700298 reinterpret_cast<const char16_t *>(interfaceName),
Steven Morelandab2fca22016-11-11 12:33:41 -0800299 env->GetStringLength(interfaceNameObj)));
Andreas Huberdab5fc62016-08-15 09:25:02 -0700300
301 env->ReleaseStringCritical(interfaceNameObj, interfaceName);
302 interfaceName = NULL;
303
Andreas Huber9f026862016-11-03 15:46:04 -0700304 hardware::Parcel *parcel =
305 JHwParcel::GetNativeContext(env, thiz)->getParcel();
306
Steven Morelandab2fca22016-11-11 12:33:41 -0800307 bool valid = parcel->enforceInterface(interfaceNameCopy.string());
Andreas Huber9f026862016-11-03 15:46:04 -0700308
Andreas Huberdab5fc62016-08-15 09:25:02 -0700309 if (!valid) {
310 jniThrowException(
311 env,
312 "java/lang/SecurityException",
313 "HWBinder invocation to an incorrect interface");
314 }
315 }
316}
317
318#define DEFINE_PARCEL_WRITER(Suffix,Type) \
319static void JHwParcel_native_write ## Suffix( \
320 JNIEnv *env, jobject thiz, Type val) { \
321 hardware::Parcel *parcel = \
322 JHwParcel::GetNativeContext(env, thiz)->getParcel(); \
323 \
324 status_t err = parcel->write ## Suffix(val); \
325 signalExceptionForError(env, err); \
326}
327
328#define DEFINE_PARCEL_READER(Suffix,Type) \
329static Type JHwParcel_native_read ## Suffix( \
330 JNIEnv *env, jobject thiz) { \
331 hardware::Parcel *parcel = \
332 JHwParcel::GetNativeContext(env, thiz)->getParcel(); \
333 \
334 Type val; \
335 status_t err = parcel->read ## Suffix(&val); \
336 signalExceptionForError(env, err); \
337 \
338 return val; \
339}
340
Andreas Huber86635bb2016-08-24 16:19:03 -0700341DEFINE_PARCEL_WRITER(Bool,jboolean)
Andreas Huberdab5fc62016-08-15 09:25:02 -0700342DEFINE_PARCEL_WRITER(Int8,jbyte)
343DEFINE_PARCEL_WRITER(Int16,jshort)
344DEFINE_PARCEL_WRITER(Int32,jint)
345DEFINE_PARCEL_WRITER(Int64,jlong)
346DEFINE_PARCEL_WRITER(Float,jfloat)
347DEFINE_PARCEL_WRITER(Double,jdouble)
348
349DEFINE_PARCEL_READER(Int8,jbyte)
350DEFINE_PARCEL_READER(Int16,jshort)
351DEFINE_PARCEL_READER(Int32,jint)
352DEFINE_PARCEL_READER(Int64,jlong)
353DEFINE_PARCEL_READER(Float,jfloat)
354DEFINE_PARCEL_READER(Double,jdouble)
355
Andreas Huber86635bb2016-08-24 16:19:03 -0700356static jboolean JHwParcel_native_readBool(JNIEnv *env, jobject thiz) {
357 hardware::Parcel *parcel =
358 JHwParcel::GetNativeContext(env, thiz)->getParcel();
359
360 bool val;
361 status_t err = parcel->readBool(&val);
362 signalExceptionForError(env, err);
363
364 return (jboolean)val;
365}
366
Andreas Huberdab5fc62016-08-15 09:25:02 -0700367static void JHwParcel_native_writeStatus(
368 JNIEnv *env, jobject thiz, jint statusCode) {
369 using hardware::Status;
370
371 Status status;
372 switch (statusCode) {
373 case 0: // kStatusSuccess
374 status = Status::ok();
375 break;
376 case -1: // kStatusError
377 status = Status::fromStatusT(UNKNOWN_ERROR);
378 break;
379 default:
380 CHECK(!"Should not be here");
381 }
382
383 hardware::Parcel *parcel =
384 JHwParcel::GetNativeContext(env, thiz)->getParcel();
385
Yifan Hongddf31f62016-11-15 16:02:40 -0800386 status_t err = ::android::hardware::writeToParcel(status, parcel);
Andreas Huberdab5fc62016-08-15 09:25:02 -0700387 signalExceptionForError(env, err);
388}
389
390static void JHwParcel_native_verifySuccess(JNIEnv *env, jobject thiz) {
391 using hardware::Status;
392
393 hardware::Parcel *parcel =
394 JHwParcel::GetNativeContext(env, thiz)->getParcel();
395
396 Status status;
Yifan Hongddf31f62016-11-15 16:02:40 -0800397 status_t err = ::android::hardware::readFromParcel(&status, *parcel);
Andreas Huberdab5fc62016-08-15 09:25:02 -0700398 signalExceptionForError(env, err);
Steven Moreland2ef0cbd2018-01-17 13:26:35 -0800399
400 if (!status.isOk()) {
401 signalExceptionForError(env, UNKNOWN_ERROR, true /* canThrowRemoteException */);
402 }
Andreas Huberdab5fc62016-08-15 09:25:02 -0700403}
404
Martijn Coenen3d726d12017-03-16 18:46:42 +0100405static void JHwParcel_native_release(
406 JNIEnv *env, jobject thiz) {
407 JHwParcel::GetNativeContext(env, thiz)->setParcel(NULL, false /* assumeOwnership */);
408}
409
Andreas Huberdab5fc62016-08-15 09:25:02 -0700410static void JHwParcel_native_releaseTemporaryStorage(
411 JNIEnv *env, jobject thiz) {
412 JHwParcel::GetNativeContext(env, thiz)->getStorage()->release(env);
413}
414
415static void JHwParcel_native_send(JNIEnv *env, jobject thiz) {
416 JHwParcel::GetNativeContext(env, thiz)->send();
417}
418
419static void JHwParcel_native_writeString(
420 JNIEnv *env, jobject thiz, jstring valObj) {
421 if (valObj == NULL) {
422 jniThrowException(env, "java/lang/NullPointerException", NULL);
423 return;
424 }
425
426 sp<JHwParcel> impl = JHwParcel::GetNativeContext(env, thiz);
427
428 const hidl_string *s =
429 impl->getStorage()->allocTemporaryString(env, valObj);
430
431 hardware::Parcel *parcel = impl->getParcel();
432
433 size_t parentHandle;
434 status_t err = parcel->writeBuffer(s, sizeof(*s), &parentHandle);
435
436 if (err == OK) {
Yifan Hong3bb65782016-11-11 17:20:54 -0800437 err = ::android::hardware::writeEmbeddedToParcel(
438 *s, parcel, parentHandle, 0 /* parentOffset */);
Andreas Huberdab5fc62016-08-15 09:25:02 -0700439 }
440
441 signalExceptionForError(env, err);
442}
443
Nirav Atre9850dd92018-07-24 17:03:44 -0700444static void JHwParcel_native_writeNativeHandle(JNIEnv *env, jobject thiz, jobject valObj) {
445 sp<JHwParcel> impl = JHwParcel::GetNativeContext(env, thiz);
446
447 EphemeralStorage *storage = impl->getStorage();
448 native_handle_t *handle = JNativeHandle::MakeCppNativeHandle(env, valObj, storage);
449
450 hardware::Parcel *parcel = impl->getParcel();
451 status_t err = parcel->writeNativeHandleNoDup(handle);
452
453 signalExceptionForError(env, err);
454}
455
Andreas Huberdab5fc62016-08-15 09:25:02 -0700456#define DEFINE_PARCEL_VECTOR_WRITER(Suffix,Type) \
457static void JHwParcel_native_write ## Suffix ## Vector( \
458 JNIEnv *env, jobject thiz, Type ## Array valObj) { \
459 if (valObj == NULL) { \
460 jniThrowException(env, "java/lang/NullPointerException", NULL); \
461 return; \
462 } \
463 \
464 sp<JHwParcel> impl = JHwParcel::GetNativeContext(env, thiz); \
465 \
466 const hidl_vec<Type> *vec = \
467 impl->getStorage()->allocTemporary ## Suffix ## Vector(env, valObj); \
468 \
469 hardware::Parcel *parcel = impl->getParcel(); \
470 \
471 size_t parentHandle; \
472 status_t err = parcel->writeBuffer(vec, sizeof(*vec), &parentHandle); \
473 \
474 if (err == OK) { \
475 size_t childHandle; \
476 \
Yifan Hong3bb65782016-11-11 17:20:54 -0800477 err = ::android::hardware::writeEmbeddedToParcel( \
478 *vec, \
Andreas Huberdab5fc62016-08-15 09:25:02 -0700479 parcel, \
480 parentHandle, \
481 0 /* parentOffset */, \
482 &childHandle); \
483 } \
484 \
485 signalExceptionForError(env, err); \
486}
487
Andreas Huberdab5fc62016-08-15 09:25:02 -0700488DEFINE_PARCEL_VECTOR_WRITER(Int8,jbyte)
489DEFINE_PARCEL_VECTOR_WRITER(Int16,jshort)
490DEFINE_PARCEL_VECTOR_WRITER(Int32,jint)
491DEFINE_PARCEL_VECTOR_WRITER(Int64,jlong)
492DEFINE_PARCEL_VECTOR_WRITER(Float,jfloat)
493DEFINE_PARCEL_VECTOR_WRITER(Double,jdouble)
494
Andreas Huber86635bb2016-08-24 16:19:03 -0700495static void JHwParcel_native_writeBoolVector(
496 JNIEnv *env, jobject thiz, jbooleanArray valObj) {
497 if (valObj == NULL) {
498 jniThrowException(env, "java/lang/NullPointerException", NULL);
499 return;
500 }
501
502 sp<JHwParcel> impl = JHwParcel::GetNativeContext(env, thiz);
503
Andreas Huber9266f992016-08-25 11:21:21 -0700504 void *vecPtr =
505 impl->getStorage()->allocTemporaryStorage(sizeof(hidl_vec<bool>));
506
507 hidl_vec<bool> *vec = new (vecPtr) hidl_vec<bool>;
Andreas Huber86635bb2016-08-24 16:19:03 -0700508
509 jsize len = env->GetArrayLength(valObj);
510
511 jboolean *src = env->GetBooleanArrayElements(valObj, nullptr);
512
513 bool *dst =
514 (bool *)impl->getStorage()->allocTemporaryStorage(len * sizeof(bool));
515
516 for (jsize i = 0; i < len; ++i) {
517 dst[i] = src[i];
518 }
519
520 env->ReleaseBooleanArrayElements(valObj, src, 0 /* mode */);
521 src = nullptr;
522
523 vec->setToExternal(dst, len);
524
525 hardware::Parcel *parcel = impl->getParcel();
526
527 size_t parentHandle;
528 status_t err = parcel->writeBuffer(vec, sizeof(*vec), &parentHandle);
529
530 if (err == OK) {
531 size_t childHandle;
532
Yifan Hong3bb65782016-11-11 17:20:54 -0800533 err = ::android::hardware::writeEmbeddedToParcel(
534 *vec,
Andreas Huber86635bb2016-08-24 16:19:03 -0700535 parcel,
536 parentHandle,
537 0 /* parentOffset */,
538 &childHandle);
539 }
540
541 signalExceptionForError(env, err);
542}
543
Nirav Atre9850dd92018-07-24 17:03:44 -0700544template<typename T>
545static void WriteHidlVector(JNIEnv *env, jobject thiz, const hidl_vec<T> &vec) {
546 hardware::Parcel *parcel = JHwParcel::GetNativeContext(env, thiz)->getParcel();
547
548 size_t parentHandle;
549 status_t err = parcel->writeBuffer(&vec, sizeof(vec), &parentHandle);
550
551 if (err == OK) {
552 size_t childHandle;
553 err = ::android::hardware::writeEmbeddedToParcel(
554 vec,
555 parcel,
556 parentHandle,
557 0 /* parentOffset */,
558 &childHandle);
559
560 for (size_t i = 0; (err == OK) && (i < vec.size()); ++i) {
561 err = ::android::hardware::writeEmbeddedToParcel(
562 vec[i],
563 parcel,
564 childHandle,
565 i * sizeof(T));
566 }
567 }
568
569 signalExceptionForError(env, err);
570}
571
572static void JHwParcel_native_writeStringVector(
573 JNIEnv *env, jobject thiz, jobjectArray arrayObj) {
574 if (arrayObj == nullptr) {
575 jniThrowException(env, "java/lang/NullPointerException", nullptr);
576 return;
577 }
578
579 sp<JHwParcel> impl = JHwParcel::GetNativeContext(env, thiz);
580 EphemeralStorage *storage = impl->getStorage();
581
582 void *vecPtr = storage->allocTemporaryStorage(sizeof(hidl_vec<hidl_string>));
583 hidl_vec<hidl_string> *vec = new (vecPtr) hidl_vec<hidl_string>();
584
585 jsize len = env->GetArrayLength(arrayObj);
586 hidl_string *strings = storage->allocStringArray(len);
587 vec->setToExternal(strings, len, false /* shouldOwn */);
588
589 for (jsize i = 0; i < len; ++i) {
590 ScopedLocalRef<jstring> stringObj(env, (jstring) env->GetObjectArrayElement(arrayObj, i));
591
592 const hidl_string *s = storage->allocTemporaryString(env, stringObj.get());
593 strings[i].setToExternal(s->c_str(), s->size());
594 }
595
596 WriteHidlVector(env, thiz, *vec);
597}
598
599static void JHwParcel_native_writeNativeHandleVector(
600 JNIEnv *env, jobject thiz, jobjectArray jHandleArray) {
601 if (jHandleArray == nullptr) {
602 jniThrowException(env, "java/lang/NullPointerException", nullptr);
603 return;
604 }
605
606 sp<JHwParcel> impl = JHwParcel::GetNativeContext(env, thiz);
607 EphemeralStorage *storage = impl->getStorage();
608
609 void *vecPtr = storage->allocTemporaryStorage(sizeof(hidl_vec<hidl_handle>));
610 hidl_vec<hidl_handle> *vec = new (vecPtr) hidl_vec<hidl_handle>();
611
612 jsize len = env->GetArrayLength(jHandleArray);
613 hidl_handle *handles = static_cast<hidl_handle *>(
614 storage->allocTemporaryStorage(len * sizeof(hidl_handle)));
615
616 vec->setToExternal(handles, len, false /* shouldOwn */);
617 for (jsize i = 0; i < len; i++) {
618 ScopedLocalRef<jobject> jHandle(env, env->GetObjectArrayElement(jHandleArray, i));
619
620 native_handle_t* handle = JNativeHandle::MakeCppNativeHandle(env, jHandle.get(), storage);
621
622 new (&(handles[i])) hidl_handle();
623 handles[i].setTo(handle, false /* shouldOwn */);
624 }
625
626 WriteHidlVector(env, thiz, *vec);
627}
628
Andreas Huberdab5fc62016-08-15 09:25:02 -0700629static void JHwParcel_native_writeStrongBinder(
630 JNIEnv *env, jobject thiz, jobject binderObj) {
631 sp<hardware::IBinder> binder;
632 if (binderObj != NULL) {
Nirav Atre9850dd92018-07-24 17:03:44 -0700633 ScopedLocalRef<jclass> hwBinderKlass(env, FindClassOrDie(env, PACKAGE_PATH "/HwBinder"));
Andreas Huberdab5fc62016-08-15 09:25:02 -0700634
635 ScopedLocalRef<jclass> hwRemoteBinderKlass(
636 env, FindClassOrDie(env, PACKAGE_PATH "/HwRemoteBinder"));
637
638 if (env->IsInstanceOf(binderObj, hwBinderKlass.get())) {
Andreas Huber56bdb8a2017-06-16 14:56:12 -0700639 binder = JHwBinder::GetNativeBinder(env, binderObj);
Andreas Huberdab5fc62016-08-15 09:25:02 -0700640 } else if (env->IsInstanceOf(binderObj, hwRemoteBinderKlass.get())) {
641 binder = JHwRemoteBinder::GetNativeContext(
642 env, binderObj)->getBinder();
643 } else {
644 signalExceptionForError(env, INVALID_OPERATION);
645 return;
646 }
647 }
648
649 hardware::Parcel *parcel =
650 JHwParcel::GetNativeContext(env, thiz)->getParcel();
651
652 status_t err = parcel->writeStrongBinder(binder);
653 signalExceptionForError(env, err);
654}
655
Ytai Ben-Tsvi4659e182019-11-06 09:53:34 -0800656static void JHwParcel_native_writeHidlMemory(
657 JNIEnv *env, jobject thiz, jobject jmem) {
658
659 if (jmem == nullptr) {
660 jniThrowException(env, "java/lang/NullPointerException", nullptr);
661 return;
662 }
663
664 status_t err = OK;
665
666 // Convert the Java object to its C++ counterpart.
667 const hardware::hidl_memory* cmem = JHidlMemory::fromJava(env, jmem);
668 if (cmem == nullptr) {
669 err = BAD_VALUE;
670 }
671
672 if (err == OK) {
673 // Write it to the parcel.
674 hardware::Parcel* parcel =
675 JHwParcel::GetNativeContext(env, thiz)->getParcel();
676
677 size_t parentHandle;
678 err = parcel->writeBuffer(cmem, sizeof(*cmem), &parentHandle);
679 if (err == OK) {
680 err = hardware::writeEmbeddedToParcel(*cmem, parcel, parentHandle, 0);
681 }
682 }
683 signalExceptionForError(env, err);
684}
685
Andreas Huberdab5fc62016-08-15 09:25:02 -0700686static jstring MakeStringObjFromHidlString(JNIEnv *env, const hidl_string &s) {
687 String16 utf16String(s.c_str(), s.size());
688
689 return env->NewString(
690 reinterpret_cast<const jchar *>(utf16String.string()),
691 utf16String.size());
692}
693
694static jstring JHwParcel_native_readString(JNIEnv *env, jobject thiz) {
695 hardware::Parcel *parcel =
696 JHwParcel::GetNativeContext(env, thiz)->getParcel();
697
698 size_t parentHandle;
699
Martijn Coenen24c82272017-01-11 12:35:56 +0100700 const hidl_string *s;
Martijn Coenen7c006392017-04-18 15:54:43 -0700701 status_t err = parcel->readBuffer(sizeof(*s), &parentHandle,
Martijn Coenen24c82272017-01-11 12:35:56 +0100702 reinterpret_cast<const void**>(&s));
Andreas Huberdab5fc62016-08-15 09:25:02 -0700703
Martijn Coenen24c82272017-01-11 12:35:56 +0100704 if (err != OK) {
705 signalExceptionForError(env, err);
Andreas Huberdab5fc62016-08-15 09:25:02 -0700706 return NULL;
707 }
708
Martijn Coenen24c82272017-01-11 12:35:56 +0100709 err = ::android::hardware::readEmbeddedFromParcel(
Martijn Coenen7c006392017-04-18 15:54:43 -0700710 const_cast<hidl_string &>(*s),
Andreas Huberdab5fc62016-08-15 09:25:02 -0700711 *parcel, parentHandle, 0 /* parentOffset */);
712
713 if (err != OK) {
714 signalExceptionForError(env, err);
715 return NULL;
716 }
717
718 return MakeStringObjFromHidlString(env, *s);
719}
720
Nirav Atre9850dd92018-07-24 17:03:44 -0700721static jobject ReadNativeHandle(JNIEnv *env, jobject thiz, jboolean embedded,
722 jlong parentHandle, jlong offset) {
723 hardware::Parcel *parcel =
724 JHwParcel::GetNativeContext(env, thiz)->getParcel();
725
726 const native_handle_t *handle = nullptr;
727 status_t err = OK;
728
729 if (embedded) {
730 err = parcel->readNullableEmbeddedNativeHandle(parentHandle, offset, &handle);
731 } else {
732 err = parcel->readNullableNativeHandleNoDup(&handle);
733 }
734
735 if (err != OK) {
736 signalExceptionForError(env, err);
737 return nullptr;
738 }
739
740 return JNativeHandle::MakeJavaNativeHandleObj(env, handle);
741}
742
743static jobject JHwParcel_native_readNativeHandle(JNIEnv *env, jobject thiz) {
744 return ReadNativeHandle(env, thiz, false /*embedded*/, 0L /*parentHandle*/, 0L /*offset*/);
745}
746
747static jobject JHwParcel_native_readEmbeddedNativeHandle(
748 JNIEnv *env, jobject thiz, jlong parentHandle, jlong offset) {
749 return ReadNativeHandle(env, thiz, true /*embedded*/, parentHandle, offset);
750}
751
Andreas Huberdab5fc62016-08-15 09:25:02 -0700752#define DEFINE_PARCEL_VECTOR_READER(Suffix,Type,NewType) \
753static Type ## Array JHwParcel_native_read ## Suffix ## Vector( \
754 JNIEnv *env, jobject thiz) { \
755 hardware::Parcel *parcel = \
756 JHwParcel::GetNativeContext(env, thiz)->getParcel(); \
Andreas Huberdab5fc62016-08-15 09:25:02 -0700757 size_t parentHandle; \
758 \
Martijn Coenen24c82272017-01-11 12:35:56 +0100759 const hidl_vec<Type> *vec; \
Martijn Coenen7c006392017-04-18 15:54:43 -0700760 status_t err = parcel->readBuffer(sizeof(*vec), &parentHandle, \
Martijn Coenen24c82272017-01-11 12:35:56 +0100761 reinterpret_cast<const void**>(&vec)); \
Andreas Huberdab5fc62016-08-15 09:25:02 -0700762 \
Martijn Coenen24c82272017-01-11 12:35:56 +0100763 if (err != OK) { \
764 signalExceptionForError(env, err); \
Andreas Huberdab5fc62016-08-15 09:25:02 -0700765 return NULL; \
766 } \
767 \
768 size_t childHandle; \
769 \
Martijn Coenen24c82272017-01-11 12:35:56 +0100770 err = ::android::hardware::readEmbeddedFromParcel( \
Martijn Coenen7c006392017-04-18 15:54:43 -0700771 const_cast<hidl_vec<Type> &>(*vec), \
Andreas Huberdab5fc62016-08-15 09:25:02 -0700772 *parcel, \
773 parentHandle, \
774 0 /* parentOffset */, \
775 &childHandle); \
776 \
777 if (err != OK) { \
778 signalExceptionForError(env, err); \
779 return NULL; \
780 } \
781 \
782 Type ## Array valObj = env->New ## NewType ## Array(vec->size()); \
783 env->Set ## NewType ## ArrayRegion(valObj, 0, vec->size(), &(*vec)[0]); \
784 \
785 return valObj; \
786}
787
Andreas Huberdab5fc62016-08-15 09:25:02 -0700788DEFINE_PARCEL_VECTOR_READER(Int8,jbyte,Byte)
789DEFINE_PARCEL_VECTOR_READER(Int16,jshort,Short)
790DEFINE_PARCEL_VECTOR_READER(Int32,jint,Int)
791DEFINE_PARCEL_VECTOR_READER(Int64,jlong,Long)
792DEFINE_PARCEL_VECTOR_READER(Float,jfloat,Float)
793DEFINE_PARCEL_VECTOR_READER(Double,jdouble,Double)
794
Nirav Atre9850dd92018-07-24 17:03:44 -0700795static jbooleanArray JHwParcel_native_readBoolVector(JNIEnv *env, jobject thiz) {
796 hardware::Parcel *parcel = JHwParcel::GetNativeContext(env, thiz)->getParcel();
Andreas Huber86635bb2016-08-24 16:19:03 -0700797
798 size_t parentHandle;
799
Martijn Coenen24c82272017-01-11 12:35:56 +0100800 const hidl_vec<bool> *vec;
Martijn Coenen7c006392017-04-18 15:54:43 -0700801 status_t err = parcel->readBuffer(sizeof(*vec), &parentHandle,
Martijn Coenen24c82272017-01-11 12:35:56 +0100802 reinterpret_cast<const void**>(&vec));
Andreas Huber86635bb2016-08-24 16:19:03 -0700803
Martijn Coenen24c82272017-01-11 12:35:56 +0100804 if (err != OK) {
805 signalExceptionForError(env, err);
Andreas Huber86635bb2016-08-24 16:19:03 -0700806 return NULL;
807 }
808
809 size_t childHandle;
810
Martijn Coenen24c82272017-01-11 12:35:56 +0100811 err = ::android::hardware::readEmbeddedFromParcel(
Martijn Coenen7c006392017-04-18 15:54:43 -0700812 const_cast<hidl_vec<bool> &>(*vec),
Andreas Huber86635bb2016-08-24 16:19:03 -0700813 *parcel,
814 parentHandle,
815 0 /* parentOffset */,
816 &childHandle);
817
818 if (err != OK) {
819 signalExceptionForError(env, err);
820 return NULL;
821 }
822
823 jbooleanArray valObj = env->NewBooleanArray(vec->size());
824
825 for (size_t i = 0; i < vec->size(); ++i) {
826 jboolean x = (*vec)[i];
827 env->SetBooleanArrayRegion(valObj, i, 1, &x);
828 }
829
830 return valObj;
831}
832
Andreas Huberdab5fc62016-08-15 09:25:02 -0700833static jobjectArray MakeStringArray(
834 JNIEnv *env, const hidl_string *array, size_t size) {
835 ScopedLocalRef<jclass> stringKlass(
836 env,
837 env->FindClass("java/lang/String"));
838
839 // XXX Why can't I use ScopedLocalRef<> for the arrayObj and the stringObjs?
840
841 jobjectArray arrayObj = env->NewObjectArray(size, stringKlass.get(), NULL);
842
843 for (size_t i = 0; i < size; ++i) {
844 jstring stringObj = MakeStringObjFromHidlString(env, array[i]);
845
846 env->SetObjectArrayElement(
847 arrayObj,
848 i,
849 stringObj);
850 }
851
852 return arrayObj;
853}
854
Nirav Atre9850dd92018-07-24 17:03:44 -0700855template<typename T>
856static const hidl_vec<T> *ReadHidlVector(JNIEnv *env, jobject thiz) {
857 const hidl_vec<T> *vec;
Andreas Huberdab5fc62016-08-15 09:25:02 -0700858
Nirav Atre9850dd92018-07-24 17:03:44 -0700859 hardware::Parcel *parcel = JHwParcel::GetNativeContext(env, thiz)->getParcel();
Andreas Huberdab5fc62016-08-15 09:25:02 -0700860
861 size_t parentHandle;
Nirav Atre9850dd92018-07-24 17:03:44 -0700862 status_t err = parcel->readBuffer(sizeof(hidl_vec<T>),
863 &parentHandle, reinterpret_cast<const void **>(&vec));
Andreas Huberdab5fc62016-08-15 09:25:02 -0700864
865 if (err == OK) {
866 size_t childHandle;
Nirav Atre9850dd92018-07-24 17:03:44 -0700867 err = ::android::hardware::readEmbeddedFromParcel(
868 const_cast<hidl_vec<T> &>(*vec),
869 *parcel, parentHandle,
Andreas Huberdab5fc62016-08-15 09:25:02 -0700870 0 /* parentOffset */,
871 &childHandle);
872
Nirav Atre9850dd92018-07-24 17:03:44 -0700873 for (size_t i = 0; (err == OK) && (i < vec->size()); i++) {
874 err = android::hardware::readEmbeddedFromParcel(
875 const_cast<T &>((*vec)[i]),
876 *parcel,
Andreas Huberdab5fc62016-08-15 09:25:02 -0700877 childHandle,
Nirav Atre9850dd92018-07-24 17:03:44 -0700878 i * sizeof(T) /* parentOffset */);
Andreas Huberdab5fc62016-08-15 09:25:02 -0700879 }
880 }
881
Nirav Atre9850dd92018-07-24 17:03:44 -0700882 if (err != OK) {
883 signalExceptionForError(env, err);
884 return nullptr;
885 }
886
887 return vec;
888}
889
890static jobjectArray JHwParcel_native_readStringVector(
891 JNIEnv *env, jobject thiz) {
892 const hidl_vec<hidl_string> *vec = ReadHidlVector<hidl_string>(env, thiz);
893 return MakeStringArray(env, &(*vec)[0], vec->size());
894}
895
896static jobjectArray JHwParcel_native_readNativeHandleVector(
897 JNIEnv *env, jobject thiz) {
898 const hidl_vec<hidl_handle> *vec = ReadHidlVector<hidl_handle>(env, thiz);
899
900 jsize length = vec->size();
901 jobjectArray objArray = JNativeHandle::AllocJavaNativeHandleObjArray(
902 env, length);
903
904 for (jsize i = 0; i < length; i++) {
905 jobject jHandle = JNativeHandle::MakeJavaNativeHandleObj(env, (*vec)[i].getNativeHandle());
906
907 env->SetObjectArrayElement(objArray, i, jHandle);
908 }
909
910 return objArray;
Andreas Huberdab5fc62016-08-15 09:25:02 -0700911}
912
Ytai Ben-Tsvi4659e182019-11-06 09:53:34 -0800913static status_t readEmbeddedHidlMemory(JNIEnv* env,
914 hardware::Parcel* parcel,
915 const hardware::hidl_memory& mem,
916 size_t parentHandle,
917 size_t parentOffset,
918 jobject* result) {
919 status_t err = hardware::readEmbeddedFromParcel(mem,
920 *parcel,
921 parentHandle,
922 parentOffset);
923 if (err == OK) {
924 // Convert to Java.
925 *result = JHidlMemory::toJava(env, mem);
926 if (*result == nullptr) {
927 err = BAD_VALUE;
928 }
929 }
930 return err;
931}
932
933static jobject JHwParcel_native_readHidlMemory(
934 JNIEnv* env, jobject thiz) {
935 hardware::Parcel* parcel =
936 JHwParcel::GetNativeContext(env, thiz)->getParcel();
937
938 jobject result = nullptr;
939
940 const hardware::hidl_memory* mem;
941 size_t parentHandle;
942
943 status_t err = parcel->readBuffer(sizeof(*mem),
944 &parentHandle,
945 reinterpret_cast<const void**>(&mem));
946 if (err == OK) {
947 err = readEmbeddedHidlMemory(env,
948 parcel,
949 *mem,
950 parentHandle,
951 0,
952 &result);
953 }
954
955 signalExceptionForError(env, err);
956 return result;
957}
958
959static jobject JHwParcel_native_readEmbeddedHidlMemory(
960 JNIEnv* env,
961 jobject thiz,
962 jlong fieldHandle,
963 jlong parentHandle,
964 jlong offset) {
965 hardware::Parcel* parcel =
966 JHwParcel::GetNativeContext(env, thiz)->getParcel();
967
968 jobject result = nullptr;
969 const hardware::hidl_memory* mem =
970 reinterpret_cast<const hardware::hidl_memory*>(fieldHandle);
971 status_t err = readEmbeddedHidlMemory(env,
972 parcel,
973 *mem,
974 parentHandle,
975 offset,
976 &result);
977 signalExceptionForError(env, err);
978 return result;
979}
980
Andreas Huberdab5fc62016-08-15 09:25:02 -0700981static jobject JHwParcel_native_readStrongBinder(JNIEnv *env, jobject thiz) {
982 hardware::Parcel *parcel =
983 JHwParcel::GetNativeContext(env, thiz)->getParcel();
984
985 sp<hardware::IBinder> binder = parcel->readStrongBinder();
986
Steven Moreland47942d92019-04-08 19:22:11 -0700987 if (binder == nullptr) {
988 return nullptr;
989 }
990
991 if (!validateCanUseHwBinder(binder)) {
992 return nullptr;
Andreas Huberdab5fc62016-08-15 09:25:02 -0700993 }
994
995 return JHwRemoteBinder::NewObject(env, binder);
996}
997
Martijn Coenen7c006392017-04-18 15:54:43 -0700998static jobject JHwParcel_native_readBuffer(JNIEnv *env, jobject thiz,
999 jlong expectedSize) {
Andreas Huber9266f992016-08-25 11:21:21 -07001000 hardware::Parcel *parcel =
1001 JHwParcel::GetNativeContext(env, thiz)->getParcel();
1002
1003 size_t handle;
Martijn Coenen24c82272017-01-11 12:35:56 +01001004 const void *ptr;
Martijn Coenen7c006392017-04-18 15:54:43 -07001005
1006 if (expectedSize < 0) {
1007 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1008 return nullptr;
1009 }
1010
1011 status_t status = parcel->readBuffer(expectedSize, &handle, &ptr);
Andreas Huber9266f992016-08-25 11:21:21 -07001012
Martijn Coenen24c82272017-01-11 12:35:56 +01001013 if (status != OK) {
Andreas Huber9266f992016-08-25 11:21:21 -07001014 jniThrowException(env, "java/util/NoSuchElementException", NULL);
1015 return nullptr;
1016 }
1017
1018 return JHwBlob::NewObject(env, ptr, handle);
1019}
1020
1021static jobject JHwParcel_native_readEmbeddedBuffer(
Martijn Coenen7c006392017-04-18 15:54:43 -07001022 JNIEnv *env, jobject thiz, jlong expectedSize,
1023 jlong parentHandle, jlong offset, jboolean nullable) {
Andreas Huber9266f992016-08-25 11:21:21 -07001024 hardware::Parcel *parcel =
1025 JHwParcel::GetNativeContext(env, thiz)->getParcel();
1026
1027 size_t childHandle;
1028
Martijn Coenen24c82272017-01-11 12:35:56 +01001029 const void *ptr;
1030 status_t status =
Martijn Coenen7c006392017-04-18 15:54:43 -07001031 parcel->readNullableEmbeddedBuffer(expectedSize,
1032 &childHandle, parentHandle, offset, &ptr);
1033
1034 if (expectedSize < 0) {
1035 jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
1036 return nullptr;
1037 }
Andreas Huber9266f992016-08-25 11:21:21 -07001038
Martijn Coenen24c82272017-01-11 12:35:56 +01001039 if (status != OK) {
Andreas Huber9266f992016-08-25 11:21:21 -07001040 jniThrowException(env, "java/util/NoSuchElementException", NULL);
1041 return 0;
Martijn Coenen14fae062017-01-13 11:08:51 +01001042 } else if (status == OK && !nullable && ptr == nullptr) {
1043 jniThrowException(env, "java/lang/NullPointerException", NULL);
1044 return 0;
Andreas Huber9266f992016-08-25 11:21:21 -07001045 }
1046
1047 return JHwBlob::NewObject(env, ptr, childHandle);
1048}
1049
1050static void JHwParcel_native_writeBuffer(
1051 JNIEnv *env, jobject thiz, jobject blobObj) {
1052 if (blobObj == nullptr) {
1053 jniThrowException(env, "java/lang/NullPointerException", NULL);
1054 return;
1055 }
1056
1057 hardware::Parcel *parcel =
1058 JHwParcel::GetNativeContext(env, thiz)->getParcel();
1059
1060 sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, blobObj);
1061 status_t err = blob->writeToParcel(parcel);
1062
1063 if (err != OK) {
1064 signalExceptionForError(env, err);
1065 }
1066}
1067
Andreas Huberdab5fc62016-08-15 09:25:02 -07001068static JNINativeMethod gMethods[] = {
1069 { "native_init", "()J", (void *)JHwParcel_native_init },
1070 { "native_setup", "(Z)V", (void *)JHwParcel_native_setup },
1071
1072 { "writeInterfaceToken", "(Ljava/lang/String;)V",
1073 (void *)JHwParcel_native_writeInterfaceToken },
1074
Andreas Huber86635bb2016-08-24 16:19:03 -07001075 { "writeBool", "(Z)V", (void *)JHwParcel_native_writeBool },
Andreas Huberdab5fc62016-08-15 09:25:02 -07001076 { "writeInt8", "(B)V", (void *)JHwParcel_native_writeInt8 },
1077 { "writeInt16", "(S)V", (void *)JHwParcel_native_writeInt16 },
1078 { "writeInt32", "(I)V", (void *)JHwParcel_native_writeInt32 },
1079 { "writeInt64", "(J)V", (void *)JHwParcel_native_writeInt64 },
1080 { "writeFloat", "(F)V", (void *)JHwParcel_native_writeFloat },
1081 { "writeDouble", "(D)V", (void *)JHwParcel_native_writeDouble },
1082
1083 { "writeString", "(Ljava/lang/String;)V",
1084 (void *)JHwParcel_native_writeString },
1085
Nirav Atre9850dd92018-07-24 17:03:44 -07001086 { "writeNativeHandle", "(L" PACKAGE_PATH "/NativeHandle;)V",
1087 (void *)JHwParcel_native_writeNativeHandle },
1088
Andreas Huber86635bb2016-08-24 16:19:03 -07001089 { "writeBoolVector", "([Z)V", (void *)JHwParcel_native_writeBoolVector },
Andreas Huberdab5fc62016-08-15 09:25:02 -07001090 { "writeInt8Vector", "([B)V", (void *)JHwParcel_native_writeInt8Vector },
Andreas Huberdab5fc62016-08-15 09:25:02 -07001091 { "writeInt16Vector", "([S)V", (void *)JHwParcel_native_writeInt16Vector },
Andreas Huberdab5fc62016-08-15 09:25:02 -07001092 { "writeInt32Vector", "([I)V", (void *)JHwParcel_native_writeInt32Vector },
Andreas Huberdab5fc62016-08-15 09:25:02 -07001093 { "writeInt64Vector", "([J)V", (void *)JHwParcel_native_writeInt64Vector },
Andreas Huberdab5fc62016-08-15 09:25:02 -07001094 { "writeFloatVector", "([F)V", (void *)JHwParcel_native_writeFloatVector },
Andreas Huberdab5fc62016-08-15 09:25:02 -07001095
1096 { "writeDoubleVector", "([D)V",
1097 (void *)JHwParcel_native_writeDoubleVector },
1098
Andreas Huberdab5fc62016-08-15 09:25:02 -07001099 { "writeStringVector", "([Ljava/lang/String;)V",
1100 (void *)JHwParcel_native_writeStringVector },
1101
Nirav Atre9850dd92018-07-24 17:03:44 -07001102 { "writeNativeHandleVector", "([L" PACKAGE_PATH "/NativeHandle;)V",
1103 (void *)JHwParcel_native_writeNativeHandleVector },
1104
Andreas Huberdab5fc62016-08-15 09:25:02 -07001105 { "writeStrongBinder", "(L" PACKAGE_PATH "/IHwBinder;)V",
1106 (void *)JHwParcel_native_writeStrongBinder },
1107
1108 { "enforceInterface", "(Ljava/lang/String;)V",
1109 (void *)JHwParcel_native_enforceInterface },
1110
Andreas Huber86635bb2016-08-24 16:19:03 -07001111 { "readBool", "()Z", (void *)JHwParcel_native_readBool },
Andreas Huberdab5fc62016-08-15 09:25:02 -07001112 { "readInt8", "()B", (void *)JHwParcel_native_readInt8 },
1113 { "readInt16", "()S", (void *)JHwParcel_native_readInt16 },
1114 { "readInt32", "()I", (void *)JHwParcel_native_readInt32 },
1115 { "readInt64", "()J", (void *)JHwParcel_native_readInt64 },
1116 { "readFloat", "()F", (void *)JHwParcel_native_readFloat },
1117 { "readDouble", "()D", (void *)JHwParcel_native_readDouble },
1118
1119 { "readString", "()Ljava/lang/String;",
1120 (void *)JHwParcel_native_readString },
1121
Nirav Atre9850dd92018-07-24 17:03:44 -07001122 { "readNativeHandle", "()L" PACKAGE_PATH "/NativeHandle;",
1123 (void *)JHwParcel_native_readNativeHandle },
1124
1125 { "readEmbeddedNativeHandle", "(JJ)L" PACKAGE_PATH "/NativeHandle;",
1126 (void *)JHwParcel_native_readEmbeddedNativeHandle },
1127
Andreas Huberef1a5652016-10-18 09:24:04 -07001128 { "readBoolVectorAsArray", "()[Z",
1129 (void *)JHwParcel_native_readBoolVector },
Andreas Huberdab5fc62016-08-15 09:25:02 -07001130
Andreas Huberef1a5652016-10-18 09:24:04 -07001131 { "readInt8VectorAsArray", "()[B",
1132 (void *)JHwParcel_native_readInt8Vector },
1133
1134 { "readInt16VectorAsArray", "()[S",
1135 (void *)JHwParcel_native_readInt16Vector },
1136
1137 { "readInt32VectorAsArray", "()[I",
1138 (void *)JHwParcel_native_readInt32Vector },
1139
1140 { "readInt64VectorAsArray", "()[J",
1141 (void *)JHwParcel_native_readInt64Vector },
1142
1143 { "readFloatVectorAsArray", "()[F",
1144 (void *)JHwParcel_native_readFloatVector },
1145
1146 { "readDoubleVectorAsArray", "()[D",
1147 (void *)JHwParcel_native_readDoubleVector },
1148
1149 { "readStringVectorAsArray", "()[Ljava/lang/String;",
Andreas Huberdab5fc62016-08-15 09:25:02 -07001150 (void *)JHwParcel_native_readStringVector },
1151
Nirav Atre9850dd92018-07-24 17:03:44 -07001152 { "readNativeHandleAsArray", "()[L" PACKAGE_PATH "/NativeHandle;",
1153 (void *)JHwParcel_native_readNativeHandleVector },
1154
Andreas Huberdab5fc62016-08-15 09:25:02 -07001155 { "readStrongBinder", "()L" PACKAGE_PATH "/IHwBinder;",
1156 (void *)JHwParcel_native_readStrongBinder },
1157
1158 { "writeStatus", "(I)V", (void *)JHwParcel_native_writeStatus },
1159
1160 { "verifySuccess", "()V", (void *)JHwParcel_native_verifySuccess },
1161
1162 { "releaseTemporaryStorage", "()V",
1163 (void *)JHwParcel_native_releaseTemporaryStorage },
1164
1165 { "send", "()V", (void *)JHwParcel_native_send },
Andreas Huber9266f992016-08-25 11:21:21 -07001166
Martijn Coenen7c006392017-04-18 15:54:43 -07001167 { "readBuffer", "(J)L" PACKAGE_PATH "/HwBlob;",
Andreas Huber9266f992016-08-25 11:21:21 -07001168 (void *)JHwParcel_native_readBuffer },
1169
Martijn Coenen7c006392017-04-18 15:54:43 -07001170 { "readEmbeddedBuffer", "(JJJZ)L" PACKAGE_PATH "/HwBlob;",
Andreas Huber9266f992016-08-25 11:21:21 -07001171 (void *)JHwParcel_native_readEmbeddedBuffer },
1172
1173 { "writeBuffer", "(L" PACKAGE_PATH "/HwBlob;)V",
1174 (void *)JHwParcel_native_writeBuffer },
Martijn Coenen3d726d12017-03-16 18:46:42 +01001175
1176 { "release", "()V",
1177 (void *)JHwParcel_native_release },
1178
Ytai Ben-Tsvi4659e182019-11-06 09:53:34 -08001179 {"writeHidlMemory", "(L" PACKAGE_PATH "/HidlMemory;)V",
1180 (void*) JHwParcel_native_writeHidlMemory},
1181
1182 {"readHidlMemory", "()L" PACKAGE_PATH "/HidlMemory;",
1183 (void*) JHwParcel_native_readHidlMemory},
1184
1185 {"readEmbeddedHidlMemory", "(JJJ)L" PACKAGE_PATH "/HidlMemory;",
1186 (void*) JHwParcel_native_readEmbeddedHidlMemory},
Andreas Huberdab5fc62016-08-15 09:25:02 -07001187};
1188
1189namespace android {
1190
1191int register_android_os_HwParcel(JNIEnv *env) {
1192 return RegisterMethodsOrDie(env, CLASS_PATH, gMethods, NELEM(gMethods));
1193}
1194
1195} // namespace android