1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ohos_rpc_message_parcel.h"
17 
18 #include <ashmem.h>
19 #include <securec.h>
20 #include <unistd.h>
21 
22 #include "ipc_debug.h"
23 #include "ipc_file_descriptor.h"
24 #include "jkit_utils.h"
25 #include "jni_helper.h"
26 #include "log_tags.h"
27 #include "ohos_rpc_remote_object.h"
28 #include "ohos_utils_parcel.h"
29 
30 using namespace OHOS;
31 using namespace OHOS::HiviewDFX;
32 
33 namespace OHOS {
34 struct JMessageParcel {
35     jclass klazz;
36     jfieldID nativeObject;
37     jfieldID nativeObjectOwner;
38 } g_jMessageParcel;
39 
40 static constexpr HiLogLabel LABEL = { LOG_CORE, LOG_ID_IPC_OTHER, "IPCJni" };
41 
42 class AshmemSmartPointWrapper {
43 public:
AshmemSmartPointWrapper(const sptr<Ashmem> & ashmem)44     explicit AshmemSmartPointWrapper(const sptr<Ashmem> &ashmem) : ashmem_(ashmem)
45     {
46         if (ashmem == nullptr) {
47             ZLOGE(LABEL, "ashmem is null");
48         }
49     }
50     ~AshmemSmartPointWrapper() = default;
51 
GetAshmem() const52     const sptr<Ashmem> &GetAshmem() const
53     {
54         return ashmem_;
55     }
56 
57 private:
58     // make sure this is immutable
59     sptr<Ashmem> const ashmem_;
60 };
61 
62 /*
63  * Get Native Message Parcel instance of zindaneos/rpc/MessageParcel
64  */
JavaOhosRpcMessageParcelGetNative(JNIEnv * env,jobject object)65 MessageParcel *JavaOhosRpcMessageParcelGetNative(JNIEnv *env, jobject object)
66 {
67     ZLOGD(LABEL, "enter");
68     if (env == nullptr) {
69         ZLOGE(LABEL, "env is null");
70         return nullptr;
71     }
72     jlong nativeObject = env->GetLongField(object, g_jMessageParcel.nativeObject);
73     return reinterpret_cast<MessageParcel *>(nativeObject);
74 }
75 
Java_ohos_rpc_Ashmem_getSptrAshmem(JNIEnv * env,jobject object,jlong id)76 sptr<Ashmem> Java_ohos_rpc_Ashmem_getSptrAshmem(JNIEnv *env, jobject object, jlong id)
77 {
78     if (env == nullptr) {
79         ZLOGE(LABEL, "env is null");
80         return nullptr;
81     }
82     if (id == 0) {
83         return nullptr;
84     }
85     AshmemSmartPointWrapper *wrapper = reinterpret_cast<AshmemSmartPointWrapper *>(id);
86     return wrapper->GetAshmem();
87 }
88 
89 static const JNINativeMethod sMethods[] = {
90     /* Name, Signature, FunctionPointer */
91     { "nativeNewObject", "(J)J", (void *)Java_ohos_rpc_MessageParcel_nativeNewObject },
92     { "nativeFreeObject", "(J)V", (void *)Java_ohos_rpc_MessageParcel_nativeFreeObject },
93     { "nativeWriteRemoteObject", "(Lohos/rpc/IRemoteObject;)Z",
94       (void *)Java_ohos_rpc_MessageParcel_nativeWriteRemoteObject },
95     { "nativeReadRemoteObject", "()Lohos/rpc/IRemoteObject;",
96       (void *)Java_ohos_rpc_MessageParcel_nativeReadRemoteObject },
97     { "nativeWriteFileDescriptor", "(Ljava/io/FileDescriptor;)Z",
98       (void *)Java_ohos_rpc_MessageParcel_nativeWriteFileDescriptor },
99     { "nativeReadFileDescriptor", "()Ljava/io/FileDescriptor;",
100       (void *)Java_ohos_rpc_MessageParcel_nativeReadFileDescriptor },
101     { "nativeWriteInterfaceToken", "(Ljava/lang/String;I)Z",
102       (void *)Java_ohos_rpc_MessageParcel_nativeWriteInterfaceToken },
103     { "nativeReadInterfaceToken", "()Ljava/lang/String;",
104       (void *)Java_ohos_rpc_MessageParcel_nativeReadInterfaceToken },
105     { "nativeWriteRawData", "([BI)Z", (void *)Java_ohos_rpc_MessageParcel_nativeWriteRawData },
106     { "nativeReadRawData", "(I)[B", (void *)Java_ohos_rpc_MessageParcel_nativeReadRawData },
107     { "nativeGetRawDataCapacity", "()I", (void *)Java_ohos_rpc_MessageParcel_nativeGetRawDataCapacity },
108     { "nativeCloseFileDescriptor", "(Ljava/io/FileDescriptor;)V",
109       (void *)Java_ohos_rpc_MessageParcel_nativeCloseFileDescriptor },
110     { "nativeDupFileDescriptor", "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;",
111       (void *)Java_ohos_rpc_MessageParcel_nativeDupFileDescriptor },
112     { "nativeContainFileDescriptors", "()Z", (void *)Java_ohos_rpc_MessageParcel_nativeContainFileDescriptors },
113     { "nativeWriteAshmem", "(J)Z", (void *)Java_ohos_rpc_MessageParcel_nativeWriteAshmem },
114     { "nativeReadAshmem", "()J", (void *)Java_ohos_rpc_MessageParcel_nativeReadAshmem },
115     { "nativeReleaseAshmem", "(J)V", (void *)Java_ohos_rpc_MessageParcel_nativeReleaseAshmem },
116 };
117 
118 /*
119  * register native methods fopr ohos.rpc.MessageParcel.
120  */
JavaOhosRpcMessageParcelRegisterNativeMethods(JNIEnv * env)121 int JavaOhosRpcMessageParcelRegisterNativeMethods(JNIEnv *env)
122 {
123     ZLOGD(LABEL, "enter");
124     if (env = nullptr) {
125         ZLOGE(LABEL, "env is null");
126         return JNI_ERR;
127     }
128     jclass klazz = reinterpret_cast<jclass>(env->NewGlobalRef(env->FindClass("ohos/rpc/MessageParcel")));
129     if (klazz == nullptr) {
130         ZLOGE(LABEL, "could not find class for MessageParcel");
131         return JNI_ERR;
132     }
133     g_jMessageParcel.klazz = reinterpret_cast<jclass>(env->NewGlobalRef(klazz));
134     g_jMessageParcel.nativeObject = env->GetFieldID(g_jMessageParcel.klazz, "mNativeObject", "J");
135     if (g_jMessageParcel.nativeObject == nullptr) {
136         ZLOGE(LABEL, "could not Get mNativeObject field for MessageParcel");
137         if (g_jMessageParcel.klazz != nullptr) {
138             env->DeleteGlobalRef(g_jMessageParcel.klazz);
139         }
140         env->DeleteGlobalRef(klazz);
141         return JNI_ERR;
142     }
143     g_jMessageParcel.nativeObjectOwner = env->GetFieldID(g_jMessageParcel.klazz, "mOwnsNativeObject", "Z");
144     if (g_jMessageParcel.nativeObjectOwner == nullptr) {
145         ZLOGE(LABEL, "could not Get mOwnsNativeObject field for MessageParcel");
146         if (g_jMessageParcel.klazz != nullptr) {
147             env->DeleteGlobalRef(g_jMessageParcel.klazz);
148         }
149         env->DeleteGlobalRef(klazz);
150         return JNI_ERR;
151     }
152     return JkitRegisterNativeMethods(env, "ohos/rpc/MessageParcel", sMethods, NUM_METHODS(sMethods));
153 }
154 } // namespace OHOS
155 
156 /*
157  * Class:     ohos.rpc.MessageParcel
158  * Method:    nativeWriteRemoteObject
159  * Signature: (Lohos/rpc/IRemoteObject;)Z
160  */
Java_ohos_rpc_MessageParcel_nativeWriteRemoteObject(JNIEnv * env,jobject parcel,jobject object)161 jboolean JNICALL Java_ohos_rpc_MessageParcel_nativeWriteRemoteObject(JNIEnv *env, jobject parcel, jobject object)
162 {
163     ZLOGD(LABEL, "enter");
164     if (env == nullptr) {
165         ZLOGE(LABEL, "env is null");
166         return JNI_FALSE;
167     }
168     MessageParcel *nativeParcel = JavaOhosRpcMessageParcelGetNative(env, parcel);
169     if (nativeParcel == nullptr) {
170         ZLOGE(LABEL, "could not get native parcel for marshalling");
171         return JNI_FALSE;
172     }
173 
174     sptr<IRemoteObject> target = Java_ohos_rpc_getNativeRemoteObject(env, object);
175     if (target != nullptr) {
176         if (nativeParcel->WriteRemoteObject(target)) {
177             return JNI_TRUE;
178         }
179     }
180     return JNI_FALSE;
181 }
182 
183 /*
184  * Class:     ohos.rpc.MessageParcel
185  * Method:    nativeReadRemoteObject
186  * Signature: ()Lohos/rpc/IRemoteObject;
187  */
Java_ohos_rpc_MessageParcel_nativeReadRemoteObject(JNIEnv * env,jobject object)188 jobject JNICALL Java_ohos_rpc_MessageParcel_nativeReadRemoteObject(JNIEnv *env, jobject object)
189 {
190     ZLOGD(LABEL, "enter");
191     if (env = nullptr) {
192         ZLOGE(LABEL, "env is null");
193         return nullptr;
194     }
195     MessageParcel *nativeParcel = JavaOhosRpcMessageParcelGetNative(env, object);
196     if (nativeParcel == nullptr) {
197         ZLOGE(LABEL, "could not get native parcel for unmarshalling");
198         return nullptr;
199     }
200 
201     return Java_ohos_rpc_getJavaRemoteObject(env, nativeParcel->ReadRemoteObject());
202 }
203 
204 /*
205  * Class:     ohos.rpc.MessageParcel
206  * Method:    nativeWriteFileDescriptor
207  * Signature: (Ljava/io/FileDescriptor;)Z
208  */
Java_ohos_rpc_MessageParcel_nativeWriteFileDescriptor(JNIEnv * env,jobject object,jobject descriptor)209 jboolean JNICALL Java_ohos_rpc_MessageParcel_nativeWriteFileDescriptor(JNIEnv *env, jobject object, jobject descriptor)
210 {
211     ZLOGD(LABEL, "enter");
212     MessageParcel *nativeParcel = JavaOhosRpcMessageParcelGetNative(env, object);
213     if (nativeParcel == nullptr) {
214         ZLOGE(LABEL, "could not get native parcel for marshalling");
215         return JNI_FALSE;
216     }
217 
218     int fd = JniHelperJavaIoGetFdFromFileDescriptor(env, descriptor);
219     return fd > 0 ? nativeParcel->WriteFileDescriptor(fd) : JNI_FALSE;
220 }
221 
222 /*
223  * Class:     ohos.rpc.MessageParcel
224  * Method:    nativeReadFileDescriptor
225  * Signature: ()Ljava/io/FileDescriptor;
226  */
Java_ohos_rpc_MessageParcel_nativeReadFileDescriptor(JNIEnv * env,jobject object)227 jobject JNICALL Java_ohos_rpc_MessageParcel_nativeReadFileDescriptor(JNIEnv *env, jobject object)
228 {
229     ZLOGD(LABEL, "enter");
230     MessageParcel *nativeParcel = JavaOhosRpcMessageParcelGetNative(env, object);
231     if (nativeParcel == nullptr) {
232         ZLOGE(LABEL, "unable to get native parcel");
233         return nullptr;
234     }
235 
236     int fd = nativeParcel->ReadFileDescriptor();
237     if (fd != INVALID_FD) {
238         return JniHelperJavaIoCreateFileDescriptor(env, fd);
239     }
240 
241     ZLOGE(LABEL, "Got invalid fd from parcel");
242     return nullptr;
243 }
244 
245 /*
246  * Class:     ohos.rpc.MessageParcel
247  * Method:    nativeContainFileDescriptors
248  * Signature: ()Z;
249  */
Java_ohos_rpc_MessageParcel_nativeContainFileDescriptors(JNIEnv * env,jobject object)250 jboolean JNICALL Java_ohos_rpc_MessageParcel_nativeContainFileDescriptors(JNIEnv *env, jobject object)
251 {
252     ZLOGD(LABEL, "enter");
253     MessageParcel *nativeParcel = JavaOhosRpcMessageParcelGetNative(env, object);
254     if (nativeParcel == nullptr) {
255         ZLOGE(LABEL, "unable to get native parcel");
256         return JNI_FALSE;
257     }
258 
259     bool result = nativeParcel->ContainFileDescriptors();
260     return result ? JNI_TRUE : JNI_FALSE;
261 }
262 
263 /*
264  * Class:     ohos.rpc.MessageParcel
265  * Method:    nativeWriteInterfaceToken
266  * Signature: (Ljava/lang/String;I)Z
267  */
Java_ohos_rpc_MessageParcel_nativeWriteInterfaceToken(JNIEnv * env,jobject object,jstring name,jint len)268 jboolean JNICALL Java_ohos_rpc_MessageParcel_nativeWriteInterfaceToken(JNIEnv *env, jobject object, jstring name,
269     jint len)
270 {
271     ZLOGD(LABEL, "enter");
272     if (env == nullptr || len < 0) {
273         ZLOGE(LABEL, "env is null or len < 0");
274         return JNI_FALSE;
275     }
276     MessageParcel *nativeParcel = JavaOhosRpcMessageParcelGetNative(env, object);
277     if (nativeParcel == nullptr) {
278         ZLOGE(LABEL, "could not get native parcel for marshalling");
279         return JNI_FALSE;
280     }
281 
282     bool result = false;
283     const jchar *u16chars = env->GetStringCritical(name, 0);
284     if (u16chars != nullptr) {
285         const auto *u16Str = reinterpret_cast<const char16_t *>(u16chars);
286         result = nativeParcel->WriteInterfaceToken(std::u16string(u16Str, len));
287         env->ReleaseStringCritical(name, u16chars);
288     }
289 
290     return result ? JNI_TRUE : JNI_FALSE;
291 }
292 
293 /*
294  * Class:     ohos.rpc.MessageParcel
295  * Method:    nativeReadInterfaceToken
296  * Signature: ()Ljava/lang/String;
297  */
Java_ohos_rpc_MessageParcel_nativeReadInterfaceToken(JNIEnv * env,jobject object)298 jobject JNICALL Java_ohos_rpc_MessageParcel_nativeReadInterfaceToken(JNIEnv *env, jobject object)
299 {
300     ZLOGD(LABEL, "enter");
301     MessageParcel *nativeParcel = JavaOhosRpcMessageParcelGetNative(env, object);
302     if (nativeParcel == nullptr) {
303         ZLOGE(LABEL, "could not get native parcel for marshalling");
304         return JNI_FALSE;
305     }
306 
307     std::u16string name = nativeParcel->ReadInterfaceToken();
308     return env->NewString(reinterpret_cast<const jchar *>(name.data()), name.size());
309 }
310 
311 /*
312  * Class:     ohos.rpc.MessageParcel
313  * Method:    nativeWriteRawData
314  * Signature: ([BI)Z
315  */
Java_ohos_rpc_MessageParcel_nativeWriteRawData(JNIEnv * env,jobject object,jobject rawData,jint size)316 jboolean JNICALL Java_ohos_rpc_MessageParcel_nativeWriteRawData(JNIEnv *env, jobject object, jobject rawData, jint size)
317 {
318     MessageParcel *nativeParcel = JavaOhosRpcMessageParcelGetNative(env, object);
319     if (nativeParcel == nullptr) {
320         ZLOGE(LABEL, "could not get native parcel for raw data");
321         return JNI_FALSE;
322     }
323 
324     jbyte *ptr = static_cast<jbyte *>(env->GetPrimitiveArrayCritical(static_cast<jarray>(rawData), 0));
325     if (ptr == nullptr) {
326         return JNI_FALSE;
327     }
328     bool result = nativeParcel->WriteRawData(ptr, size);
329     env->ReleasePrimitiveArrayCritical(static_cast<jarray>(rawData), ptr, 0);
330     return result ? JNI_TRUE : JNI_FALSE;
331 }
332 
333 /*
334  * Class:     ohos.rpc.MessageParcel
335  * Method:    nativeReadRawData
336  * Signature: (I)[B
337  */
Java_ohos_rpc_MessageParcel_nativeReadRawData(JNIEnv * env,jobject object,jint size)338 jbyteArray JNICALL Java_ohos_rpc_MessageParcel_nativeReadRawData(JNIEnv *env, jobject object, jint size)
339 {
340     MessageParcel *nativeParcel = JavaOhosRpcMessageParcelGetNative(env, object);
341     if (nativeParcel == nullptr) {
342         ZLOGE(LABEL, "could not get native parcel for rawData");
343         return nullptr;
344     }
345 
346     const void *rawData = nativeParcel->ReadRawData(size);
347     if (rawData == nullptr) {
348         ZLOGE(LABEL, "read raw data failed");
349         return nullptr;
350     }
351     jbyteArray bytes = env->NewByteArray(size);
352     if (bytes == nullptr) {
353         ZLOGE(LABEL, "NewByteArray failed");
354         return nullptr;
355     }
356     jbyte *ptr = static_cast<jbyte *>(env->GetPrimitiveArrayCritical(bytes, 0));
357     if (ptr != nullptr) {
358         int result = memcpy_s(ptr, size, rawData, size);
359         env->ReleasePrimitiveArrayCritical(bytes, ptr, 0);
360         if (result != JNI_OK) {
361             ZLOGE(LABEL, "copy raw data failed");
362             env->DeleteLocalRef(bytes);
363             return nullptr;
364         }
365     }
366     return bytes;
367 }
368 
369 
370 /*
371  * Class:     ohos.rpc.MessageParcel
372  * Method:    nativeGetRawDataCapacity
373  * Signature: ()I;
374  */
Java_ohos_rpc_MessageParcel_nativeGetRawDataCapacity(JNIEnv * env,jobject object)375 jint JNICALL Java_ohos_rpc_MessageParcel_nativeGetRawDataCapacity(JNIEnv *env, jobject object)
376 {
377     MessageParcel *nativeParcel = JavaOhosRpcMessageParcelGetNative(env, object);
378     if (nativeParcel == nullptr) {
379         ZLOGE(LABEL, "could not get native parcel for rawData");
380         return JNI_OK;
381     }
382 
383     return static_cast<jint>(nativeParcel->GetRawDataCapacity());
384 }
385 
386 /*
387  * Set mOwnsNativeObject filed to ohos.rpc.MessageParcel
388  */
JavaOhosRpcMessageOptionSetNativeObjectOwner(JNIEnv * env,jobject object,jboolean value)389 void JavaOhosRpcMessageOptionSetNativeObjectOwner(JNIEnv *env, jobject object, jboolean value)
390 {
391     ZLOGD(LABEL, "enter");
392     env->SetBooleanField(object, g_jMessageParcel.nativeObjectOwner, value);
393 }
394 
395 /*
396  * Class:     ohos.rpc.MessageParcel
397  * Method:    nativeNewObject
398  * Signature: (J)J;
399  */
Java_ohos_rpc_MessageParcel_nativeNewObject(JNIEnv * env,jobject object,jlong nativeObject)400 jlong JNICALL Java_ohos_rpc_MessageParcel_nativeNewObject(JNIEnv *env, jobject object, jlong nativeObject)
401 {
402     ZLOGD(LABEL, "enter");
403     MessageParcel *nativeMessageParcel = nullptr;
404     if (nativeObject != 0) {
405         nativeMessageParcel = reinterpret_cast<MessageParcel *>(nativeObject);
406         JavaOhosRpcMessageOptionSetNativeObjectOwner(env, object, JNI_FALSE);
407     } else {
408         JavaOhosRpcMessageOptionSetNativeObjectOwner(env, object, JNI_TRUE);
409         nativeMessageParcel = new MessageParcel();
410     }
411 
412     if (nativeMessageParcel == nullptr) {
413         return 0L;
414     }
415     jclass superClass = env->GetSuperclass(g_jMessageParcel.klazz);
416     if (superClass == nullptr) {
417         ZLOGE(LABEL, "get supper class for MessageParcel failed");
418         delete nativeMessageParcel;
419         return 0L;
420     }
421 
422     jmethodID superInit = env->GetMethodID(superClass, "<init>", "(J)V");
423     if (superInit == nullptr) {
424         ZLOGE(LABEL, "get supper method for MessageParcel failed");
425         delete nativeMessageParcel;
426         return 0L;
427     }
428     Parcel *nativeParcel = static_cast<Parcel *>(nativeMessageParcel);
429     env->CallNonvirtualVoidMethod(object, superClass, superInit, reinterpret_cast<jlong>(nativeParcel));
430 
431     return reinterpret_cast<jlong>(nativeMessageParcel);
432 }
433 
434 /*
435  * Class:     ohos.rpc.MessageParcel
436  * Method:    nativeFreeObject
437  * Signature: (J)V;
438  */
Java_ohos_rpc_MessageParcel_nativeFreeObject(JNIEnv * env,jobject object,jlong nativeObject)439 void JNICALL Java_ohos_rpc_MessageParcel_nativeFreeObject(JNIEnv *env, jobject object, jlong nativeObject)
440 {
441     ZLOGD(LABEL, "enter");
442     std::unique_ptr<MessageParcel> nativeParcel(reinterpret_cast<MessageParcel *>(nativeObject));
443 }
444 
445 /*
446  * Class:     ohos.rpc.MessageParcel
447  * Method:    nativeCloseFileDescriptor
448  * Signature: (Ljava/io/FileDescriptor;)V
449  */
Java_ohos_rpc_MessageParcel_nativeCloseFileDescriptor(JNIEnv * env,jobject object,jobject descriptor)450 void JNICALL Java_ohos_rpc_MessageParcel_nativeCloseFileDescriptor(JNIEnv *env, jobject object, jobject descriptor)
451 {
452     ZLOGD(LABEL, "enter");
453     if (descriptor != nullptr) {
454         int fd = JniHelperJavaIoGetFdFromFileDescriptor(env, descriptor);
455         if (fd != INVALID_FD) {
456             close(fd);
457             JniHelperJavaIoSetFdToFileDescriptor(env, descriptor, INVALID_FD);
458         }
459     }
460 }
461 
462 /*
463  * Class:     ohos.rpc.MessageParcel
464  * Method:    nativeDupFileDescriptor
465  * Signature: (Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;
466  */
Java_ohos_rpc_MessageParcel_nativeDupFileDescriptor(JNIEnv * env,jobject object,jobject descriptor)467 jobject JNICALL Java_ohos_rpc_MessageParcel_nativeDupFileDescriptor(JNIEnv *env, jobject object, jobject descriptor)
468 {
469     ZLOGD(LABEL, "enter");
470     if (descriptor != nullptr) {
471         int fd = JniHelperJavaIoGetFdFromFileDescriptor(env, descriptor);
472         int dupFd = INVALID_FD;
473         if (fd != INVALID_FD) {
474             dupFd = dup(fd);
475         }
476         if (dupFd != INVALID_FD) {
477             return JniHelperJavaIoCreateFileDescriptor(env, dupFd);
478         }
479     }
480     return nullptr;
481 }
482 
483 /*
484  * Class:     ohos.rpc.MessageParcel
485  * Method:    nativeWriteAshmem
486  * Signature: (J)Z
487  */
Java_ohos_rpc_MessageParcel_nativeWriteAshmem(JNIEnv * env,jobject object,jlong id)488 jboolean JNICALL Java_ohos_rpc_MessageParcel_nativeWriteAshmem(JNIEnv *env, jobject object, jlong id)
489 {
490     ZLOGD(LABEL, "enter");
491     MessageParcel *nativeParcel = JavaOhosRpcMessageParcelGetNative(env, object);
492     if (nativeParcel == nullptr) {
493         ZLOGE(LABEL, "could not get native parcel for raw data");
494         return JNI_FALSE;
495     }
496 
497     sptr<Ashmem> ashmem = Java_ohos_rpc_Ashmem_getSptrAshmem(env, object, id);
498     if (ashmem == nullptr) {
499         ZLOGE(LABEL, "ashmem is null");
500         return JNI_FALSE;
501     }
502 
503     bool result = nativeParcel->WriteAshmem(ashmem);
504     return result ? JNI_TRUE : JNI_FALSE;
505 }
506 
507 /*
508  * Class:     ohos.rpc.MessageParcel
509  * Method:    nativeReadAshmem
510  * Signature: (V)J
511  */
Java_ohos_rpc_MessageParcel_nativeReadAshmem(JNIEnv * env,jobject object)512 jlong JNICALL Java_ohos_rpc_MessageParcel_nativeReadAshmem(JNIEnv *env, jobject object)
513 {
514     ZLOGD(LABEL, "enter");
515     MessageParcel *nativeParcel = JavaOhosRpcMessageParcelGetNative(env, object);
516     if (nativeParcel == nullptr) {
517         ZLOGE(LABEL, "could not get native parcel for rawData");
518         return 0;
519     }
520 
521     sptr<Ashmem> nativeAshmem = nativeParcel->ReadAshmem();
522     if (nativeAshmem == nullptr) {
523         ZLOGE(LABEL, "read raw data failed");
524         return 0;
525     }
526 
527     // memory is released in Java_ohos_rpc_MessageParcel_nativeReleaseAshmem
528     AshmemSmartPointWrapper *wrapper = new AshmemSmartPointWrapper(nativeAshmem);
529     return reinterpret_cast<jlong>(wrapper);
530 }
531 
532 /*
533  * Class:     ohos.rpc.MessageParcel
534  * Method:    nativeReleaseAshmem
535  * Signature: (J)V
536  */
Java_ohos_rpc_MessageParcel_nativeReleaseAshmem(JNIEnv * env,jobject object,jlong id)537 void JNICALL Java_ohos_rpc_MessageParcel_nativeReleaseAshmem(JNIEnv *env, jobject object, jlong id)
538 {
539     ZLOGD(LABEL, "enter");
540     if (id == 0) {
541         return;
542     }
543     std::unique_ptr<AshmemSmartPointWrapper> nativeParcel(reinterpret_cast<AshmemSmartPointWrapper *>(id));
544 }
545