1dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber/*
2dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * Copyright (C) 2016 The Android Open Source Project
3dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber *
4dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
5dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * you may not use this file except in compliance with the License.
6dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * You may obtain a copy of the License at
7dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber *
8dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
9dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber *
10dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * Unless required by applicable law or agreed to in writing, software
11dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
12dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * See the License for the specific language governing permissions and
14dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber * limitations under the License.
15dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber */
16dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
17dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber//#define LOG_NDEBUG 0
18dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber#define LOG_TAG "android_os_HwParcel"
19dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber#include <android-base/logging.h>
20dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
21dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber#include "android_os_HwParcel.h"
22dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
23dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber#include "android_os_HwBinder.h"
249266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber#include "android_os_HwBlob.h"
25dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber#include "android_os_HwRemoteBinder.h"
26dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
27dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber#include <JNIHelp.h>
28dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber#include <android_runtime/AndroidRuntime.h>
29ddf31f604ee2024daaf50ac309e7fcaf29d7b43cYifan Hong#include <hidl/HidlTransportSupport.h>
30aa2c32f92b199cb40b808554ced67af1edaffef5Martijn Coenen#include <hidl/Status.h>
31dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber#include <nativehelper/ScopedLocalRef.h>
32dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
33dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber#include "core_jni_helpers.h"
34dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
35dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberusing android::AndroidRuntime;
36dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
37dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberusing ::android::hardware::hidl_string;
38dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberusing ::android::hardware::hidl_vec;
39dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
40dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber#define PACKAGE_PATH    "android/os"
41dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber#define CLASS_NAME      "HwParcel"
42dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber#define CLASS_PATH      PACKAGE_PATH "/" CLASS_NAME
43dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
44dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Hubernamespace android {
45dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
46dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic struct fields_t {
47dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    jfieldID contextID;
48dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    jmethodID constructID;
49dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
50dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber} gFields;
51dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
52e62b1f32f3ab72508daeda63c9be49743e8f8b7eSteven Morelandvoid signalExceptionForError(JNIEnv *env, status_t err, bool canThrowRemoteException) {
53dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    switch (err) {
54dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        case OK:
55dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            break;
56dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
57dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        case NO_MEMORY:
58dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        {
59dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
60dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            break;
61dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        }
62dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
63dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        case INVALID_OPERATION:
64dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        {
65dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            jniThrowException(
66dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                    env, "java/lang/UnsupportedOperationException", NULL);
67dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            break;
68dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        }
69dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
70dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        case BAD_VALUE:
71dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        {
72dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
73dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            break;
74dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        }
75dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
769266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        case -ERANGE:
77dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        case BAD_INDEX:
78dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        {
79dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            jniThrowException(env, "java/lang/IndexOutOfBoundsException", NULL);
80dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            break;
81dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        }
82dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
83dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        case BAD_TYPE:
84dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        {
85dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
86dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            break;
87dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        }
88dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
89dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        case NAME_NOT_FOUND:
90dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        {
91dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            jniThrowException(env, "java/util/NoSuchElementException", NULL);
92dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            break;
93dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        }
94dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
95dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        case PERMISSION_DENIED:
96dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        {
97dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            jniThrowException(env, "java/lang/SecurityException", NULL);
98dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            break;
99dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        }
100dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
101dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        case NO_INIT:
102dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        {
103dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            jniThrowException(
104dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                    env, "java/lang/RuntimeException", "Not initialized");
105dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            break;
106dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        }
107dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
108dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        case ALREADY_EXISTS:
109dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        {
110dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            jniThrowException(
111dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                    env, "java/lang/RuntimeException", "Item already exists");
112dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            break;
113dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        }
114dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
115dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        default:
116dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        {
117e62b1f32f3ab72508daeda63c9be49743e8f8b7eSteven Moreland            std::stringstream ss;
118e62b1f32f3ab72508daeda63c9be49743e8f8b7eSteven Moreland            ss << "HwBinder Error: (" << err << ")";
119e62b1f32f3ab72508daeda63c9be49743e8f8b7eSteven Moreland
120dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            jniThrowException(
121e62b1f32f3ab72508daeda63c9be49743e8f8b7eSteven Moreland                    env,
122e62b1f32f3ab72508daeda63c9be49743e8f8b7eSteven Moreland                    canThrowRemoteException ? "android/os/RemoteException" : "java/lang/RuntimeException",
123e62b1f32f3ab72508daeda63c9be49743e8f8b7eSteven Moreland                    ss.str().c_str());
124dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
125dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            break;
126dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        }
127dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
128dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
129dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
130dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber// static
131dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Hubervoid JHwParcel::InitClass(JNIEnv *env) {
132dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    ScopedLocalRef<jclass> clazz(
133dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            env, FindClassOrDie(env, CLASS_PATH));
134dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
135dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    gFields.contextID =
136dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        GetFieldIDOrDie(env, clazz.get(), "mNativeContext", "J");
137dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
138dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    gFields.constructID = GetMethodIDOrDie(env, clazz.get(), "<init>", "(Z)V");
139dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
140dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
141dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber// static
142dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Hubersp<JHwParcel> JHwParcel::SetNativeContext(
143dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JNIEnv *env, jobject thiz, const sp<JHwParcel> &context) {
144dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    sp<JHwParcel> old = (JHwParcel *)env->GetLongField(thiz, gFields.contextID);
145dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
146dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    if (context != NULL) {
147dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        context->incStrong(NULL /* id */);
148dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
149dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
150dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    if (old != NULL) {
151dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        old->decStrong(NULL /* id */);
152dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
153dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
154dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    env->SetLongField(thiz, gFields.contextID, (long)context.get());
155dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
156dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    return old;
157dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
158dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
159dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber// static
160dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Hubersp<JHwParcel> JHwParcel::GetNativeContext(JNIEnv *env, jobject thiz) {
161dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    return (JHwParcel *)env->GetLongField(thiz, gFields.contextID);
162dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
163dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
164dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberJHwParcel::JHwParcel(JNIEnv *env, jobject thiz)
165dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    : mParcel(NULL),
166dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber      mOwnsParcel(false),
167dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber      mTransactCallback(nullptr),
168dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber      mWasSent(false) {
169dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    jclass clazz = env->GetObjectClass(thiz);
170dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    CHECK(clazz != NULL);
171dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
172dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    mClass = (jclass)env->NewGlobalRef(clazz);
173dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    mObject = env->NewWeakGlobalRef(thiz);
174dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
175dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
176dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberJHwParcel::~JHwParcel() {
177dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    JNIEnv *env = AndroidRuntime::getJNIEnv();
178dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
179dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    mStorage.release(env);
180dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
181dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    setParcel(NULL, false /* assumeOwnership */);
182dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
183dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    env->DeleteWeakGlobalRef(mObject);
184dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    mObject = NULL;
185dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
186dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    env->DeleteGlobalRef(mClass);
187dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    mClass = NULL;
188dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
189dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
190dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberhardware::Parcel *JHwParcel::getParcel() {
191dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    return mParcel;
192dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
193dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
194dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberEphemeralStorage *JHwParcel::getStorage() {
195dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    return &mStorage;
196dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
197dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
198dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Hubervoid JHwParcel::setParcel(hardware::Parcel *parcel, bool assumeOwnership) {
199dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    if (mParcel && mOwnsParcel) {
200dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        delete mParcel;
201dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
202dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
203dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    mParcel = parcel;
204dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    mOwnsParcel = assumeOwnership;
205dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
206dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
207dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber// static
208dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberjobject JHwParcel::NewObject(JNIEnv *env) {
209dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    ScopedLocalRef<jclass> clazz(env, FindClassOrDie(env, CLASS_PATH));
210dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
2119266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    jmethodID constructID =
2129266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        GetMethodIDOrDie(env, clazz.get(), "<init>", "(Z)V");
2139266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
2149266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return env->NewObject(clazz.get(), constructID, false /* allocate */);
215dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
216dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
217dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Hubervoid JHwParcel::setTransactCallback(
218dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        ::android::hardware::IBinder::TransactCallback cb) {
219dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    mTransactCallback = cb;
220dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
221dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
222dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Hubervoid JHwParcel::send() {
223dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    CHECK(mTransactCallback != nullptr);
224dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    CHECK(mParcel != nullptr);
225dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
226dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    mTransactCallback(*mParcel);
227dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    mTransactCallback = nullptr;
228dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
229dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    mWasSent = true;
230dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
231dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
232dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberbool JHwParcel::wasSent() const {
233dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    return mWasSent;
234dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
235dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
236dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}  // namespace android
237dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
238dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber////////////////////////////////////////////////////////////////////////////////
239dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
240dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberusing namespace android;
241dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
242dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic void releaseNativeContext(void *nativeContext) {
243dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    sp<JHwParcel> parcel = (JHwParcel *)nativeContext;
244dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
245dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    if (parcel != NULL) {
246dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        parcel->decStrong(NULL /* id */);
247dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
248dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
249dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
250dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic jlong JHwParcel_native_init(JNIEnv *env) {
251dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    JHwParcel::InitClass(env);
252dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
253dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    return reinterpret_cast<jlong>(&releaseNativeContext);
254dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
255dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
256dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic void JHwParcel_native_setup(
257dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JNIEnv *env, jobject thiz, jboolean allocate) {
258dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    sp<JHwParcel> context = new JHwParcel(env, thiz);
259dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
260dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    if (allocate) {
261dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        context->setParcel(new hardware::Parcel, true /* assumeOwnership */);
262dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
263dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
264dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    JHwParcel::SetNativeContext(env, thiz, context);
265dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
266dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
267dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic void JHwParcel_native_writeInterfaceToken(
268dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JNIEnv *env, jobject thiz, jstring interfaceNameObj) {
269dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    if (interfaceNameObj == NULL) {
270dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        jniThrowException(env, "java/lang/NullPointerException", NULL);
271dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        return;
272dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
273dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
274dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    const jchar *interfaceName = env->GetStringCritical(interfaceNameObj, NULL);
275dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    if (interfaceName) {
276ab2fca253b7dc04daf336b4b589bd096b66c4572Steven Moreland        String8 nameCopy = String8(String16(
2779f0268695c046538a1887f54172454dbc89157e7Andreas Huber                reinterpret_cast<const char16_t *>(interfaceName),
278ab2fca253b7dc04daf336b4b589bd096b66c4572Steven Moreland                env->GetStringLength(interfaceNameObj)));
279dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
280dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        env->ReleaseStringCritical(interfaceNameObj, interfaceName);
281dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        interfaceName = NULL;
282dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
2839f0268695c046538a1887f54172454dbc89157e7Andreas Huber        hardware::Parcel *parcel =
2849f0268695c046538a1887f54172454dbc89157e7Andreas Huber            JHwParcel::GetNativeContext(env, thiz)->getParcel();
2859f0268695c046538a1887f54172454dbc89157e7Andreas Huber
286ab2fca253b7dc04daf336b4b589bd096b66c4572Steven Moreland        status_t err = parcel->writeInterfaceToken(nameCopy.string());
287dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        signalExceptionForError(env, err);
288dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
289dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
290dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
291dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic void JHwParcel_native_enforceInterface(
292dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JNIEnv *env, jobject thiz, jstring interfaceNameObj) {
293dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    // XXX original binder Parcel enforceInterface implementation does some
294dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    // mysterious things regarding strictModePolicy(), figure out if we need
295dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    // that here as well.
296dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    if (interfaceNameObj == NULL) {
297dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        jniThrowException(env, "java/lang/NullPointerException", NULL);
298dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        return;
299dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
300dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
301dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    const jchar *interfaceName = env->GetStringCritical(interfaceNameObj, NULL);
302dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    if (interfaceName) {
303ab2fca253b7dc04daf336b4b589bd096b66c4572Steven Moreland        String8 interfaceNameCopy = String8(String16(
3049f0268695c046538a1887f54172454dbc89157e7Andreas Huber                reinterpret_cast<const char16_t *>(interfaceName),
305ab2fca253b7dc04daf336b4b589bd096b66c4572Steven Moreland                env->GetStringLength(interfaceNameObj)));
306dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
307dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        env->ReleaseStringCritical(interfaceNameObj, interfaceName);
308dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        interfaceName = NULL;
309dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
3109f0268695c046538a1887f54172454dbc89157e7Andreas Huber        hardware::Parcel *parcel =
3119f0268695c046538a1887f54172454dbc89157e7Andreas Huber            JHwParcel::GetNativeContext(env, thiz)->getParcel();
3129f0268695c046538a1887f54172454dbc89157e7Andreas Huber
313ab2fca253b7dc04daf336b4b589bd096b66c4572Steven Moreland        bool valid = parcel->enforceInterface(interfaceNameCopy.string());
3149f0268695c046538a1887f54172454dbc89157e7Andreas Huber
315dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        if (!valid) {
316dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            jniThrowException(
317dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                    env,
318dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                    "java/lang/SecurityException",
319dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                    "HWBinder invocation to an incorrect interface");
320dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        }
321dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
322dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
323dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
324dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber#define DEFINE_PARCEL_WRITER(Suffix,Type)                               \
325dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic void JHwParcel_native_write ## Suffix(                           \
326dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JNIEnv *env, jobject thiz, Type val) {                          \
327dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    hardware::Parcel *parcel =                                          \
328dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JHwParcel::GetNativeContext(env, thiz)->getParcel();            \
329dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                                                                        \
330dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    status_t err = parcel->write ## Suffix(val);                        \
331dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    signalExceptionForError(env, err);                                  \
332dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
333dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
334dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber#define DEFINE_PARCEL_READER(Suffix,Type)                               \
335dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic Type JHwParcel_native_read ## Suffix(                            \
336dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JNIEnv *env, jobject thiz) {                                    \
337dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    hardware::Parcel *parcel =                                          \
338dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JHwParcel::GetNativeContext(env, thiz)->getParcel();            \
339dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                                                                        \
340dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    Type val;                                                           \
341dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    status_t err = parcel->read ## Suffix(&val);                        \
342dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    signalExceptionForError(env, err);                                  \
343dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                                                                        \
344dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    return val;                                                         \
345dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
346dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
34786635bb45ee1ddeb3059a8a925659964c7858cc3Andreas HuberDEFINE_PARCEL_WRITER(Bool,jboolean)
348dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_WRITER(Int8,jbyte)
349dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_WRITER(Int16,jshort)
350dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_WRITER(Int32,jint)
351dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_WRITER(Int64,jlong)
352dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_WRITER(Float,jfloat)
353dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_WRITER(Double,jdouble)
354dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
355dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_READER(Int8,jbyte)
356dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_READER(Int16,jshort)
357dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_READER(Int32,jint)
358dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_READER(Int64,jlong)
359dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_READER(Float,jfloat)
360dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_READER(Double,jdouble)
361dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
36286635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huberstatic jboolean JHwParcel_native_readBool(JNIEnv *env, jobject thiz) {
36386635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    hardware::Parcel *parcel =
36486635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber        JHwParcel::GetNativeContext(env, thiz)->getParcel();
36586635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
36686635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    bool val;
36786635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    status_t err = parcel->readBool(&val);
36886635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    signalExceptionForError(env, err);
36986635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
37086635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    return (jboolean)val;
37186635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber}
37286635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
373dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic void JHwParcel_native_writeStatus(
374dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JNIEnv *env, jobject thiz, jint statusCode) {
375dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    using hardware::Status;
376dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
377dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    Status status;
378dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    switch (statusCode) {
379dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        case 0:  // kStatusSuccess
380dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            status = Status::ok();
381dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            break;
382dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        case -1:  // kStatusError
383dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            status = Status::fromStatusT(UNKNOWN_ERROR);
384dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            break;
385dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        default:
386dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            CHECK(!"Should not be here");
387dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
388dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
389dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    hardware::Parcel *parcel =
390dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JHwParcel::GetNativeContext(env, thiz)->getParcel();
391dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
392ddf31f604ee2024daaf50ac309e7fcaf29d7b43cYifan Hong    status_t err = ::android::hardware::writeToParcel(status, parcel);
393dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    signalExceptionForError(env, err);
394dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
395dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
396dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic void JHwParcel_native_verifySuccess(JNIEnv *env, jobject thiz) {
397dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    using hardware::Status;
398dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
399dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    hardware::Parcel *parcel =
400dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JHwParcel::GetNativeContext(env, thiz)->getParcel();
401dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
402dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    Status status;
403ddf31f604ee2024daaf50ac309e7fcaf29d7b43cYifan Hong    status_t err = ::android::hardware::readFromParcel(&status, *parcel);
404dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    signalExceptionForError(env, err);
405dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
406dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
4073d726d16b6c198087dc527d9e5f51f18351a0fa9Martijn Coenenstatic void JHwParcel_native_release(
4083d726d16b6c198087dc527d9e5f51f18351a0fa9Martijn Coenen        JNIEnv *env, jobject thiz) {
4093d726d16b6c198087dc527d9e5f51f18351a0fa9Martijn Coenen    JHwParcel::GetNativeContext(env, thiz)->setParcel(NULL, false /* assumeOwnership */);
4103d726d16b6c198087dc527d9e5f51f18351a0fa9Martijn Coenen}
4113d726d16b6c198087dc527d9e5f51f18351a0fa9Martijn Coenen
412dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic void JHwParcel_native_releaseTemporaryStorage(
413dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JNIEnv *env, jobject thiz) {
414dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    JHwParcel::GetNativeContext(env, thiz)->getStorage()->release(env);
415dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
416dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
417dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic void JHwParcel_native_send(JNIEnv *env, jobject thiz) {
418dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    JHwParcel::GetNativeContext(env, thiz)->send();
419dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
420dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
421dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic void JHwParcel_native_writeString(
422dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JNIEnv *env, jobject thiz, jstring valObj) {
423dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    if (valObj == NULL) {
424dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        jniThrowException(env, "java/lang/NullPointerException", NULL);
425dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        return;
426dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
427dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
428dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    sp<JHwParcel> impl = JHwParcel::GetNativeContext(env, thiz);
429dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
430dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    const hidl_string *s =
431dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        impl->getStorage()->allocTemporaryString(env, valObj);
432dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
433dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    hardware::Parcel *parcel = impl->getParcel();
434dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
435dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    size_t parentHandle;
436dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    status_t err = parcel->writeBuffer(s, sizeof(*s), &parentHandle);
437dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
438dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    if (err == OK) {
4393bb65781ec5aa73d25dc684f53f6b46752a12838Yifan Hong        err = ::android::hardware::writeEmbeddedToParcel(
4403bb65781ec5aa73d25dc684f53f6b46752a12838Yifan Hong                *s, parcel, parentHandle, 0 /* parentOffset */);
441dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
442dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
443dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    signalExceptionForError(env, err);
444dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
445dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
446dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber#define DEFINE_PARCEL_VECTOR_WRITER(Suffix,Type)                               \
447dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic void JHwParcel_native_write ## Suffix ## Vector(                        \
448dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JNIEnv *env, jobject thiz, Type ## Array valObj) {                     \
449dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    if (valObj == NULL) {                                                      \
450dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        jniThrowException(env, "java/lang/NullPointerException", NULL);        \
451dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        return;                                                                \
452dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }                                                                          \
453dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                                                                               \
454dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    sp<JHwParcel> impl = JHwParcel::GetNativeContext(env, thiz);               \
455dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                                                                               \
456dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    const hidl_vec<Type> *vec =                                                \
457dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        impl->getStorage()->allocTemporary ## Suffix ## Vector(env, valObj);   \
458dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                                                                               \
459dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    hardware::Parcel *parcel = impl->getParcel();                              \
460dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                                                                               \
461dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    size_t parentHandle;                                                       \
462dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    status_t err = parcel->writeBuffer(vec, sizeof(*vec), &parentHandle);      \
463dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                                                                               \
464dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    if (err == OK) {                                                           \
465dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        size_t childHandle;                                                    \
466dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                                                                               \
4673bb65781ec5aa73d25dc684f53f6b46752a12838Yifan Hong        err = ::android::hardware::writeEmbeddedToParcel(                      \
4683bb65781ec5aa73d25dc684f53f6b46752a12838Yifan Hong                *vec,                                                          \
469dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                parcel,                                                        \
470dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                parentHandle,                                                  \
471dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                0 /* parentOffset */,                                          \
472dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                &childHandle);                                                 \
473dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }                                                                          \
474dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                                                                               \
475dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    signalExceptionForError(env, err);                                         \
476dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
477dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
478dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_VECTOR_WRITER(Int8,jbyte)
479dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_VECTOR_WRITER(Int16,jshort)
480dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_VECTOR_WRITER(Int32,jint)
481dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_VECTOR_WRITER(Int64,jlong)
482dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_VECTOR_WRITER(Float,jfloat)
483dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_VECTOR_WRITER(Double,jdouble)
484dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
48586635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huberstatic void JHwParcel_native_writeBoolVector(
48686635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber        JNIEnv *env, jobject thiz, jbooleanArray valObj) {
48786635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    if (valObj == NULL) {
48886635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber        jniThrowException(env, "java/lang/NullPointerException", NULL);
48986635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber        return;
49086635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    }
49186635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
49286635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    sp<JHwParcel> impl = JHwParcel::GetNativeContext(env, thiz);
49386635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
4949266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    void *vecPtr =
4959266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        impl->getStorage()->allocTemporaryStorage(sizeof(hidl_vec<bool>));
4969266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
4979266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    hidl_vec<bool> *vec = new (vecPtr) hidl_vec<bool>;
49886635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
49986635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    jsize len = env->GetArrayLength(valObj);
50086635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
50186635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    jboolean *src = env->GetBooleanArrayElements(valObj, nullptr);
50286635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
50386635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    bool *dst =
50486635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber        (bool *)impl->getStorage()->allocTemporaryStorage(len * sizeof(bool));
50586635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
50686635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    for (jsize i = 0; i < len; ++i) {
50786635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber        dst[i] = src[i];
50886635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    }
50986635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
51086635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    env->ReleaseBooleanArrayElements(valObj, src, 0 /* mode */);
51186635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    src = nullptr;
51286635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
51386635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    vec->setToExternal(dst, len);
51486635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
51586635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    hardware::Parcel *parcel = impl->getParcel();
51686635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
51786635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    size_t parentHandle;
51886635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    status_t err = parcel->writeBuffer(vec, sizeof(*vec), &parentHandle);
51986635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
52086635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    if (err == OK) {
52186635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber        size_t childHandle;
52286635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
5233bb65781ec5aa73d25dc684f53f6b46752a12838Yifan Hong        err = ::android::hardware::writeEmbeddedToParcel(
5243bb65781ec5aa73d25dc684f53f6b46752a12838Yifan Hong                *vec,
52586635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber                parcel,
52686635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber                parentHandle,
52786635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber                0 /* parentOffset */,
52886635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber                &childHandle);
52986635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    }
53086635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
53186635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    signalExceptionForError(env, err);
53286635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber}
53386635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
534dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic void JHwParcel_native_writeStrongBinder(
535dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JNIEnv *env, jobject thiz, jobject binderObj) {
536dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    sp<hardware::IBinder> binder;
537dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    if (binderObj != NULL) {
538dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        ScopedLocalRef<jclass> hwBinderKlass(
539dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                env, FindClassOrDie(env, PACKAGE_PATH "/HwBinder"));
540dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
541dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        ScopedLocalRef<jclass> hwRemoteBinderKlass(
542dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                env, FindClassOrDie(env, PACKAGE_PATH "/HwRemoteBinder"));
543dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
544dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        if (env->IsInstanceOf(binderObj, hwBinderKlass.get())) {
545dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            binder = JHwBinder::GetNativeContext(env, binderObj);
546dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        } else if (env->IsInstanceOf(binderObj, hwRemoteBinderKlass.get())) {
547dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            binder = JHwRemoteBinder::GetNativeContext(
548dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                    env, binderObj)->getBinder();
549dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        } else {
550dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            signalExceptionForError(env, INVALID_OPERATION);
551dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            return;
552dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        }
553dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
554dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
555dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    hardware::Parcel *parcel =
556dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JHwParcel::GetNativeContext(env, thiz)->getParcel();
557dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
558dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    status_t err = parcel->writeStrongBinder(binder);
559dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    signalExceptionForError(env, err);
560dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
561dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
562dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic jstring MakeStringObjFromHidlString(JNIEnv *env, const hidl_string &s) {
563dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    String16 utf16String(s.c_str(), s.size());
564dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
565dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    return env->NewString(
566dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            reinterpret_cast<const jchar *>(utf16String.string()),
567dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            utf16String.size());
568dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
569dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
570dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic jstring JHwParcel_native_readString(JNIEnv *env, jobject thiz) {
571dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    hardware::Parcel *parcel =
572dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JHwParcel::GetNativeContext(env, thiz)->getParcel();
573dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
574dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    size_t parentHandle;
575dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
57624c82279feaff1674efacddc33a7785b23351c58Martijn Coenen    const hidl_string *s;
577932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen    status_t err = parcel->readBuffer(sizeof(*s), &parentHandle,
57824c82279feaff1674efacddc33a7785b23351c58Martijn Coenen            reinterpret_cast<const void**>(&s));
579dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
58024c82279feaff1674efacddc33a7785b23351c58Martijn Coenen    if (err != OK) {
58124c82279feaff1674efacddc33a7785b23351c58Martijn Coenen        signalExceptionForError(env, err);
582dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        return NULL;
583dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
584dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
58524c82279feaff1674efacddc33a7785b23351c58Martijn Coenen    err = ::android::hardware::readEmbeddedFromParcel(
586932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen            const_cast<hidl_string &>(*s),
587dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            *parcel, parentHandle, 0 /* parentOffset */);
588dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
589dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    if (err != OK) {
590dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        signalExceptionForError(env, err);
591dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        return NULL;
592dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
593dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
594dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    return MakeStringObjFromHidlString(env, *s);
595dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
596dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
597dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber#define DEFINE_PARCEL_VECTOR_READER(Suffix,Type,NewType)                       \
598dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic Type ## Array JHwParcel_native_read ## Suffix ## Vector(                \
599dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JNIEnv *env, jobject thiz) {                                           \
600dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    hardware::Parcel *parcel =                                                 \
601dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JHwParcel::GetNativeContext(env, thiz)->getParcel();                   \
602dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    size_t parentHandle;                                                       \
603dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                                                                               \
60424c82279feaff1674efacddc33a7785b23351c58Martijn Coenen    const hidl_vec<Type> *vec;                                                 \
605932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen    status_t err = parcel->readBuffer(sizeof(*vec), &parentHandle,             \
60624c82279feaff1674efacddc33a7785b23351c58Martijn Coenen            reinterpret_cast<const void**>(&vec));                             \
607dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                                                                               \
60824c82279feaff1674efacddc33a7785b23351c58Martijn Coenen    if (err != OK) {                                                           \
60924c82279feaff1674efacddc33a7785b23351c58Martijn Coenen        signalExceptionForError(env, err);                                     \
610dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        return NULL;                                                           \
611dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }                                                                          \
612dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                                                                               \
613dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    size_t childHandle;                                                        \
614dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                                                                               \
61524c82279feaff1674efacddc33a7785b23351c58Martijn Coenen    err = ::android::hardware::readEmbeddedFromParcel(                         \
616932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen                const_cast<hidl_vec<Type> &>(*vec),                            \
617dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                *parcel,                                                       \
618dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                parentHandle,                                                  \
619dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                0 /* parentOffset */,                                          \
620dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                &childHandle);                                                 \
621dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                                                                               \
622dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    if (err != OK) {                                                           \
623dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        signalExceptionForError(env, err);                                     \
624dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        return NULL;                                                           \
625dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }                                                                          \
626dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                                                                               \
627dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    Type ## Array valObj = env->New ## NewType ## Array(vec->size());          \
628dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    env->Set ## NewType ## ArrayRegion(valObj, 0, vec->size(), &(*vec)[0]);    \
629dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                                                                               \
630dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    return valObj;                                                             \
631dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
632dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
633dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_VECTOR_READER(Int8,jbyte,Byte)
634dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_VECTOR_READER(Int16,jshort,Short)
635dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_VECTOR_READER(Int32,jint,Int)
636dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_VECTOR_READER(Int64,jlong,Long)
637dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_VECTOR_READER(Float,jfloat,Float)
638dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas HuberDEFINE_PARCEL_VECTOR_READER(Double,jdouble,Double)
639dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
64086635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huberstatic jbooleanArray JHwParcel_native_readBoolVector(
64186635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber        JNIEnv *env, jobject thiz) {
64286635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    hardware::Parcel *parcel =
64386635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber        JHwParcel::GetNativeContext(env, thiz)->getParcel();
64486635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
64586635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    size_t parentHandle;
64686635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
64724c82279feaff1674efacddc33a7785b23351c58Martijn Coenen    const hidl_vec<bool> *vec;
648932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen    status_t err = parcel->readBuffer(sizeof(*vec), &parentHandle,
64924c82279feaff1674efacddc33a7785b23351c58Martijn Coenen            reinterpret_cast<const void**>(&vec));
65086635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
65124c82279feaff1674efacddc33a7785b23351c58Martijn Coenen    if (err != OK) {
65224c82279feaff1674efacddc33a7785b23351c58Martijn Coenen        signalExceptionForError(env, err);
65386635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber        return NULL;
65486635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    }
65586635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
65686635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    size_t childHandle;
65786635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
65824c82279feaff1674efacddc33a7785b23351c58Martijn Coenen    err = ::android::hardware::readEmbeddedFromParcel(
659932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen                const_cast<hidl_vec<bool> &>(*vec),
66086635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber                *parcel,
66186635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber                parentHandle,
66286635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber                0 /* parentOffset */,
66386635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber                &childHandle);
66486635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
66586635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    if (err != OK) {
66686635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber        signalExceptionForError(env, err);
66786635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber        return NULL;
66886635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    }
66986635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
67086635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    jbooleanArray valObj = env->NewBooleanArray(vec->size());
67186635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
67286635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    for (size_t i = 0; i < vec->size(); ++i) {
67386635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber        jboolean x = (*vec)[i];
67486635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber        env->SetBooleanArrayRegion(valObj, i, 1, &x);
67586635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    }
67686635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
67786635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    return valObj;
67886635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber}
67986635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber
680dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic jobjectArray MakeStringArray(
681dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JNIEnv *env, const hidl_string *array, size_t size) {
682dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    ScopedLocalRef<jclass> stringKlass(
683dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            env,
684dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            env->FindClass("java/lang/String"));
685dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
686dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    // XXX Why can't I use ScopedLocalRef<> for the arrayObj and the stringObjs?
687dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
688dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    jobjectArray arrayObj = env->NewObjectArray(size, stringKlass.get(), NULL);
689dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
690dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    for (size_t i = 0; i < size; ++i) {
691dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        jstring stringObj = MakeStringObjFromHidlString(env, array[i]);
692dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
693dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        env->SetObjectArrayElement(
694dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                arrayObj,
695dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                i,
696dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                stringObj);
697dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
698dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
699dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    return arrayObj;
700dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
701dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
702dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic jobjectArray JHwParcel_native_readStringVector(
703dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JNIEnv *env, jobject thiz) {
704dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    typedef hidl_vec<hidl_string> string_vec;
705dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
706dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    hardware::Parcel *parcel =
707dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JHwParcel::GetNativeContext(env, thiz)->getParcel();
708dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
709dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    size_t parentHandle;
710dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
71124c82279feaff1674efacddc33a7785b23351c58Martijn Coenen    const string_vec *vec;
712932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen    status_t err = parcel->readBuffer(sizeof(*vec), &parentHandle,
71324c82279feaff1674efacddc33a7785b23351c58Martijn Coenen            reinterpret_cast<const void **>(&vec));
714dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
71524c82279feaff1674efacddc33a7785b23351c58Martijn Coenen    if (err != OK) {
71624c82279feaff1674efacddc33a7785b23351c58Martijn Coenen        signalExceptionForError(env, err);
717dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        return NULL;
718dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
719dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
720dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    size_t childHandle;
72124c82279feaff1674efacddc33a7785b23351c58Martijn Coenen    err = ::android::hardware::readEmbeddedFromParcel(
722932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen            const_cast<string_vec &>(*vec),
723dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            *parcel, parentHandle, 0 /* parentOffset */, &childHandle);
724dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
725dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    for (size_t i = 0; (err == OK) && (i < vec->size()); ++i) {
7263bb65781ec5aa73d25dc684f53f6b46752a12838Yifan Hong        err = android::hardware::readEmbeddedFromParcel(
727932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen                    const_cast<hidl_string &>((*vec)[i]),
728dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                    *parcel,
729dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                    childHandle,
730932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen                    i * sizeof(hidl_string) /* parentOffset */);
731dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
732dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
733dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    if (err != OK) {
734dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        signalExceptionForError(env, err);
735dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        return NULL;
736dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
737dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
738dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    return MakeStringArray(env, &(*vec)[0], vec->size());
739dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
740dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
741dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic void JHwParcel_native_writeStringVector(
742dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JNIEnv *env, jobject thiz, jobjectArray arrayObj) {
743dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    typedef hidl_vec<hidl_string> string_vec;
744dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
745dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    if (arrayObj == NULL) {
746dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        jniThrowException(env, "java/lang/NullPointerException", NULL);
747dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        return;
748dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
749dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
750dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    jsize len = env->GetArrayLength(arrayObj);
751dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
752dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    sp<JHwParcel> impl = JHwParcel::GetNativeContext(env, thiz);
753dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
7549266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    void *vecPtr =
7559266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        impl->getStorage()->allocTemporaryStorage(sizeof(string_vec));
7569266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
7579266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    string_vec *vec = new (vecPtr) string_vec;
758dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
759dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    hidl_string *strings = impl->getStorage()->allocStringArray(len);
760dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    vec->setToExternal(strings, len);
761dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
762dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    for (jsize i = 0; i < len; ++i) {
763dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        ScopedLocalRef<jstring> stringObj(
764dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                env,
765dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                (jstring)env->GetObjectArrayElement(arrayObj, i));
766dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
767dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        const hidl_string *s =
768dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber            impl->getStorage()->allocTemporaryString(env, stringObj.get());
769dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
770dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        strings[i].setToExternal(s->c_str(), s->size());
771dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
772dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
773dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    hardware::Parcel *parcel = impl->getParcel();
774dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
775dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    size_t parentHandle;
776dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    status_t err = parcel->writeBuffer(vec, sizeof(*vec), &parentHandle);
777dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
778dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    if (err == OK) {
779dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        size_t childHandle;
7803bb65781ec5aa73d25dc684f53f6b46752a12838Yifan Hong        err = ::android::hardware::writeEmbeddedToParcel(
7813bb65781ec5aa73d25dc684f53f6b46752a12838Yifan Hong                *vec,
782dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                parcel,
783dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                parentHandle,
784dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                0 /* parentOffset */,
785dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                &childHandle);
786dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
787dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        for (size_t i = 0; (err == OK) && (i < vec->size()); ++i) {
7883bb65781ec5aa73d25dc684f53f6b46752a12838Yifan Hong            err = ::android::hardware::writeEmbeddedToParcel(
7893bb65781ec5aa73d25dc684f53f6b46752a12838Yifan Hong                    (*vec)[i],
790dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                    parcel,
791dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                    childHandle,
792dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber                    i * sizeof(hidl_string));
793dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        }
794dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
795dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
796dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    signalExceptionForError(env, err);
797dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
798dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
799dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic jobject JHwParcel_native_readStrongBinder(JNIEnv *env, jobject thiz) {
800dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    hardware::Parcel *parcel =
801dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        JHwParcel::GetNativeContext(env, thiz)->getParcel();
802dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
803dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    sp<hardware::IBinder> binder = parcel->readStrongBinder();
804dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
805dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    if (binder == NULL) {
806dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        return NULL;
807dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    }
808dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
809dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    return JHwRemoteBinder::NewObject(env, binder);
810dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
811dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
812932b5048655ad746e265be1fd590194f7e930f61Martijn Coenenstatic jobject JHwParcel_native_readBuffer(JNIEnv *env, jobject thiz,
813932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen                                           jlong expectedSize) {
8149266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    hardware::Parcel *parcel =
8159266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        JHwParcel::GetNativeContext(env, thiz)->getParcel();
8169266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
8179266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    size_t handle;
81824c82279feaff1674efacddc33a7785b23351c58Martijn Coenen    const void *ptr;
819932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen
820932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen    if (expectedSize < 0) {
821932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
822932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen        return nullptr;
823932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen    }
824932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen
825932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen    status_t status = parcel->readBuffer(expectedSize, &handle, &ptr);
8269266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
82724c82279feaff1674efacddc33a7785b23351c58Martijn Coenen    if (status != OK) {
8289266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        jniThrowException(env, "java/util/NoSuchElementException", NULL);
8299266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        return nullptr;
8309266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
8319266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
8329266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return JHwBlob::NewObject(env, ptr, handle);
8339266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
8349266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
8359266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatic jobject JHwParcel_native_readEmbeddedBuffer(
836932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen        JNIEnv *env, jobject thiz, jlong expectedSize,
837932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen        jlong parentHandle, jlong offset, jboolean nullable) {
8389266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    hardware::Parcel *parcel =
8399266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        JHwParcel::GetNativeContext(env, thiz)->getParcel();
8409266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
8419266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    size_t childHandle;
8429266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
84324c82279feaff1674efacddc33a7785b23351c58Martijn Coenen    const void *ptr;
84424c82279feaff1674efacddc33a7785b23351c58Martijn Coenen    status_t status =
845932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen        parcel->readNullableEmbeddedBuffer(expectedSize,
846932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen                &childHandle, parentHandle, offset, &ptr);
847932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen
848932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen    if (expectedSize < 0) {
849932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
850932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen        return nullptr;
851932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen    }
8529266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
85324c82279feaff1674efacddc33a7785b23351c58Martijn Coenen    if (status != OK) {
8549266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        jniThrowException(env, "java/util/NoSuchElementException", NULL);
8559266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        return 0;
85614fae06b603b431f341453ddbfa69bbc2e03c959Martijn Coenen    } else if (status == OK && !nullable && ptr == nullptr) {
85714fae06b603b431f341453ddbfa69bbc2e03c959Martijn Coenen        jniThrowException(env, "java/lang/NullPointerException", NULL);
85814fae06b603b431f341453ddbfa69bbc2e03c959Martijn Coenen        return 0;
8599266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
8609266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
8619266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    return JHwBlob::NewObject(env, ptr, childHandle);
8629266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
8639266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
8649266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huberstatic void JHwParcel_native_writeBuffer(
8659266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        JNIEnv *env, jobject thiz, jobject blobObj) {
8669266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if (blobObj == nullptr) {
8679266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        jniThrowException(env, "java/lang/NullPointerException", NULL);
8689266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        return;
8699266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
8709266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
8719266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    hardware::Parcel *parcel =
8729266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        JHwParcel::GetNativeContext(env, thiz)->getParcel();
8739266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
8749266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    sp<JHwBlob> blob = JHwBlob::GetNativeContext(env, blobObj);
8759266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    status_t err = blob->writeToParcel(parcel);
8769266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
8779266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    if (err != OK) {
8789266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        signalExceptionForError(env, err);
8799266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    }
8809266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber}
8819266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
882dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberstatic JNINativeMethod gMethods[] = {
883dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "native_init", "()J", (void *)JHwParcel_native_init },
884dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "native_setup", "(Z)V", (void *)JHwParcel_native_setup },
885dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
886dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "writeInterfaceToken", "(Ljava/lang/String;)V",
887dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        (void *)JHwParcel_native_writeInterfaceToken },
888dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
88986635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    { "writeBool", "(Z)V", (void *)JHwParcel_native_writeBool },
890dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "writeInt8", "(B)V", (void *)JHwParcel_native_writeInt8 },
891dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "writeInt16", "(S)V", (void *)JHwParcel_native_writeInt16 },
892dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "writeInt32", "(I)V", (void *)JHwParcel_native_writeInt32 },
893dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "writeInt64", "(J)V", (void *)JHwParcel_native_writeInt64 },
894dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "writeFloat", "(F)V", (void *)JHwParcel_native_writeFloat },
895dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "writeDouble", "(D)V", (void *)JHwParcel_native_writeDouble },
896dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
897dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "writeString", "(Ljava/lang/String;)V",
898dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        (void *)JHwParcel_native_writeString },
899dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
90086635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    { "writeBoolVector", "([Z)V", (void *)JHwParcel_native_writeBoolVector },
901dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "writeInt8Vector", "([B)V", (void *)JHwParcel_native_writeInt8Vector },
902dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "writeInt16Vector", "([S)V", (void *)JHwParcel_native_writeInt16Vector },
903dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "writeInt32Vector", "([I)V", (void *)JHwParcel_native_writeInt32Vector },
904dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "writeInt64Vector", "([J)V", (void *)JHwParcel_native_writeInt64Vector },
905dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "writeFloatVector", "([F)V", (void *)JHwParcel_native_writeFloatVector },
906dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
907dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "writeDoubleVector", "([D)V",
908dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        (void *)JHwParcel_native_writeDoubleVector },
909dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
910dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "writeStringVector", "([Ljava/lang/String;)V",
911dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        (void *)JHwParcel_native_writeStringVector },
912dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
913dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "writeStrongBinder", "(L" PACKAGE_PATH "/IHwBinder;)V",
914dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        (void *)JHwParcel_native_writeStrongBinder },
915dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
916dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "enforceInterface", "(Ljava/lang/String;)V",
917dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        (void *)JHwParcel_native_enforceInterface },
918dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
91986635bb45ee1ddeb3059a8a925659964c7858cc3Andreas Huber    { "readBool", "()Z", (void *)JHwParcel_native_readBool },
920dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "readInt8", "()B", (void *)JHwParcel_native_readInt8 },
921dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "readInt16", "()S", (void *)JHwParcel_native_readInt16 },
922dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "readInt32", "()I", (void *)JHwParcel_native_readInt32 },
923dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "readInt64", "()J", (void *)JHwParcel_native_readInt64 },
924dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "readFloat", "()F", (void *)JHwParcel_native_readFloat },
925dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "readDouble", "()D", (void *)JHwParcel_native_readDouble },
926dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
927dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "readString", "()Ljava/lang/String;",
928dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        (void *)JHwParcel_native_readString },
929dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
930ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber    { "readBoolVectorAsArray", "()[Z",
931ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber        (void *)JHwParcel_native_readBoolVector },
932ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber
933ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber    { "readInt8VectorAsArray", "()[B",
934ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber        (void *)JHwParcel_native_readInt8Vector },
935ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber
936ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber    { "readInt16VectorAsArray", "()[S",
937ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber        (void *)JHwParcel_native_readInt16Vector },
938ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber
939ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber    { "readInt32VectorAsArray", "()[I",
940ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber        (void *)JHwParcel_native_readInt32Vector },
941ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber
942ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber    { "readInt64VectorAsArray", "()[J",
943ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber        (void *)JHwParcel_native_readInt64Vector },
944ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber
945ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber    { "readFloatVectorAsArray", "()[F",
946ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber        (void *)JHwParcel_native_readFloatVector },
947ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber
948ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber    { "readDoubleVectorAsArray", "()[D",
949ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber        (void *)JHwParcel_native_readDoubleVector },
950ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber
951ef1a565bd4e96646e6848a6a40a53ee4dfe33293Andreas Huber    { "readStringVectorAsArray", "()[Ljava/lang/String;",
952dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        (void *)JHwParcel_native_readStringVector },
953dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
954dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "readStrongBinder", "()L" PACKAGE_PATH "/IHwBinder;",
955dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        (void *)JHwParcel_native_readStrongBinder },
956dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
957dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "writeStatus", "(I)V", (void *)JHwParcel_native_writeStatus },
958dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
959dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "verifySuccess", "()V", (void *)JHwParcel_native_verifySuccess },
960dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
961dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "releaseTemporaryStorage", "()V",
962dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber        (void *)JHwParcel_native_releaseTemporaryStorage },
963dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
964dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    { "send", "()V", (void *)JHwParcel_native_send },
9659266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
966932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen    { "readBuffer", "(J)L" PACKAGE_PATH "/HwBlob;",
9679266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        (void *)JHwParcel_native_readBuffer },
9689266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
969932b5048655ad746e265be1fd590194f7e930f61Martijn Coenen    { "readEmbeddedBuffer", "(JJJZ)L" PACKAGE_PATH "/HwBlob;",
9709266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        (void *)JHwParcel_native_readEmbeddedBuffer },
9719266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber
9729266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber    { "writeBuffer", "(L" PACKAGE_PATH "/HwBlob;)V",
9739266f9928d5b3431982cd04f4d6946b70f40766aAndreas Huber        (void *)JHwParcel_native_writeBuffer },
9743d726d16b6c198087dc527d9e5f51f18351a0fa9Martijn Coenen
9753d726d16b6c198087dc527d9e5f51f18351a0fa9Martijn Coenen    { "release", "()V",
9763d726d16b6c198087dc527d9e5f51f18351a0fa9Martijn Coenen        (void *)JHwParcel_native_release },
9773d726d16b6c198087dc527d9e5f51f18351a0fa9Martijn Coenen
978dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber};
979dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
980dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Hubernamespace android {
981dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
982dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huberint register_android_os_HwParcel(JNIEnv *env) {
983dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber    return RegisterMethodsOrDie(env, CLASS_PATH, gMethods, NELEM(gMethods));
984dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}
985dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber
986dab5fc65b92b37ee623b10f86a6ccf1709ba17d4Andreas Huber}  // namespace android
987