• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2022 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 "napi_ashmem.h"
17 #include <cinttypes>
18 #include <limits>
19 #include <unistd.h>
20 #include "ipc_debug.h"
21 #include "log_tags.h"
22 #include "securec.h"
23 #include "napi_rpc_error.h"
24 
25 namespace OHOS {
26 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_IPC_NAPI, "napi_ashmem" };
27 
28 static constexpr int MMAP_PROT_MAX = NAPIAshmem::PROT_EXEC | NAPIAshmem::PROT_READ | NAPIAshmem::PROT_WRITE;
29 constexpr size_t BYTE_SIZE_32 = 4;
30 
31 NapiError NAPIAshmem::napiErr;
32 
33 static const size_t ARGV_INDEX_0 = 0;
34 static const size_t ARGV_INDEX_1 = 1;
35 static const size_t ARGV_INDEX_2 = 2;
36 
37 static const size_t ARGV_LENGTH_1 = 1;
38 static const size_t ARGV_LENGTH_2 = 2;
39 static const size_t ARGV_LENGTH_3 = 3;
NAPIAshmem(sptr<Ashmem> & ashmem)40 NAPIAshmem::NAPIAshmem(sptr<Ashmem> &ashmem) : ashmem_(ashmem)
41 {
42     if (ashmem == nullptr) {
43         ZLOGE(LOG_LABEL, "ashmem is null");
44     }
45 }
46 
CloseAshmem(napi_env env,napi_callback_info info)47 napi_value NAPIAshmem::CloseAshmem(napi_env env, napi_callback_info info)
48 {
49     napi_value thisVar = nullptr;
50     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
51     NAPIAshmem *napiAshmem = nullptr;
52     napi_unwrap(env, thisVar, (void **)&napiAshmem);
53     NAPI_ASSERT(env, napiAshmem != nullptr, "napiAshmem is null");
54     napiAshmem->GetAshmem()->CloseAshmem();
55     napi_value result = nullptr;
56     napi_get_undefined(env, &result);
57     return result;
58 }
59 
CreateAshmem(napi_env env,napi_callback_info info)60 napi_value NAPIAshmem::CreateAshmem(napi_env env, napi_callback_info info)
61 {
62     napi_value thisVar = nullptr;
63     size_t argc = 2;
64     napi_value argv[ARGV_LENGTH_2] = { 0 };
65     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
66     NAPI_ASSERT(env, argc == 2, "requires 2 parameter");
67     napi_valuetype valueType = napi_null;
68     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
69     if (valueType != napi_string) {
70         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
71         return nullptr;
72     }
73     size_t bufferSize = 0;
74     napi_get_value_string_utf8(env, argv[ARGV_INDEX_0], nullptr, 0, &bufferSize);
75     if (bufferSize == 0) {
76         ZLOGE(LOG_LABEL, "invalid ashmem name");
77         return nullptr;
78     }
79     napi_typeof(env, argv[ARGV_INDEX_1], &valueType);
80     if (valueType != napi_number) {
81         ZLOGE(LOG_LABEL, "type mismatch for parameter 2");
82         return nullptr;
83     }
84     int32_t ashmemSize = 0;
85     napi_get_value_int32(env, argv[ARGV_INDEX_1], &ashmemSize);
86     if (ashmemSize <= 0) {
87         ZLOGE(LOG_LABEL, "invalid ashmem size");
88         return nullptr;
89     }
90     napi_value global = nullptr;
91     napi_status status = napi_get_global(env, &global);
92     NAPI_ASSERT(env, status == napi_ok, "get napi global failed");
93     napi_value constructor = nullptr;
94     status = napi_get_named_property(env, global, "AshmemConstructor_", &constructor);
95     NAPI_ASSERT(env, status == napi_ok, "get Ashmem constructor failed");
96     napi_value jsAshmem;
97     status = napi_new_instance(env, constructor, 2, argv, &jsAshmem);
98     NAPI_ASSERT(env, status == napi_ok, "failed to  construct js Ashmem");
99     return jsAshmem;
100 }
101 
CreateAshmemFromExisting(napi_env env,napi_callback_info info)102 napi_value NAPIAshmem::CreateAshmemFromExisting(napi_env env, napi_callback_info info)
103 {
104     size_t argc = 1;
105     napi_value argv[ARGV_LENGTH_1] = {nullptr};
106     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
107     NAPI_ASSERT(env, argc == 1, "requires 1 parameter");
108     napi_value global = nullptr;
109     napi_status status = napi_get_global(env, &global);
110     NAPI_ASSERT(env, status == napi_ok, "get napi global failed");
111     napi_value constructor = nullptr;
112     status = napi_get_named_property(env, global, "AshmemConstructor_", &constructor);
113     NAPI_ASSERT(env, status == napi_ok, "get Ashmem constructor failed");
114     bool isAshmem = false;
115     napi_instanceof(env, argv[ARGV_INDEX_0], constructor, &isAshmem);
116     NAPI_ASSERT(env, isAshmem == true, "parameter is not instanceof Ashmem");
117     NAPIAshmem *napiAshmem = nullptr;
118     napi_unwrap(env, argv[ARGV_INDEX_0], (void **)&napiAshmem);
119     NAPI_ASSERT(env, napiAshmem != nullptr, "napiAshmem is null");
120     int32_t fd = napiAshmem->GetAshmem()->GetAshmemFd();
121     uint32_t size = (uint32_t)(napiAshmem->GetAshmem()->GetAshmemSize());
122     NAPI_ASSERT(env,  (fd > 0) && (size > 0), "fd <= 0 or  size <= 0");
123     int dupFd = dup(fd);
124     NAPI_ASSERT(env, dupFd >= 0, "failed to dup fd");
125     sptr<Ashmem> newAshmem(new Ashmem(dupFd, size));
126     NAPI_ASSERT(env, newAshmem != nullptr, "napiAshmem is null");
127     napi_value jsAshmem = nullptr;
128     status = napi_new_instance(env, constructor, 0, nullptr, &jsAshmem);
129     NAPI_ASSERT(env, status == napi_ok, "failed to  construct js Ashmem");
130     NAPIAshmem *newNapiAshmem = nullptr;
131     napi_unwrap(env, jsAshmem, (void **)&newNapiAshmem);
132     NAPI_ASSERT(env, newNapiAshmem != nullptr, "newNapiAshmem is null");
133     newNapiAshmem->SetAshmem(newAshmem);
134     return jsAshmem;
135 }
136 
Create(napi_env env,napi_callback_info info)137 napi_value NAPIAshmem::Create(napi_env env, napi_callback_info info)
138 {
139     napi_value thisVar = nullptr;
140     size_t argc = 2;
141     size_t argcExistingAshmem = 1;
142     size_t argcAshmem = 2;
143     napi_value argv[ARGV_LENGTH_2] = { 0 };
144     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
145     if ((argc != argcExistingAshmem) && (argc != argcAshmem)) {
146         ZLOGE(LOG_LABEL, "requires 1 or 2 parameter");
147         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
148     }
149 
150     if (argc == argcExistingAshmem) {
151         return GetAshmemFromExisting(env, info);
152     }
153 
154     napi_valuetype valueType = napi_null;
155     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
156     if (valueType != napi_string) {
157         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
158         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
159     }
160     size_t bufferSize = 0;
161     napi_get_value_string_utf8(env, argv[ARGV_INDEX_0], nullptr, 0, &bufferSize);
162     if (bufferSize == 0) {
163         ZLOGE(LOG_LABEL, "invalid ashmem name");
164         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
165     }
166 
167     napi_typeof(env, argv[ARGV_INDEX_1], &valueType);
168     if (valueType != napi_number) {
169         ZLOGE(LOG_LABEL, "type mismatch for parameter 2");
170         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
171     }
172 
173     int32_t ashmemSize = 0;
174     napi_get_value_int32(env, argv[ARGV_INDEX_1], &ashmemSize);
175     if (ashmemSize <= 0) {
176         ZLOGE(LOG_LABEL, "invalid ashmem size");
177         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
178     }
179 
180     return GetAshmemConstructor(env, argv);
181 }
182 
GetAshmemConstructor(napi_env env,napi_value * argv)183 napi_value NAPIAshmem::GetAshmemConstructor(napi_env env, napi_value* argv)
184 {
185     napi_value global = nullptr;
186     napi_status status = napi_get_global(env, &global);
187     if (status != napi_ok) {
188         ZLOGE(LOG_LABEL, "get napi global failed");
189         return nullptr;
190     }
191     napi_value constructor = nullptr;
192     status = napi_get_named_property(env, global, "AshmemConstructor_", &constructor);
193     if (status != napi_ok) {
194         ZLOGE(LOG_LABEL, "get Ashmem constructor failed");
195         return nullptr;
196     }
197     napi_value jsAshmem;
198     status = napi_new_instance(env, constructor, 2, argv, &jsAshmem);
199     if (status != napi_ok) {
200         ZLOGE(LOG_LABEL, "failed to  construct js Ashmem");
201         return nullptr;
202     }
203     return jsAshmem;
204 }
205 
GetAshmemFromExisting(napi_env env,napi_callback_info info)206 napi_value NAPIAshmem::GetAshmemFromExisting(napi_env env, napi_callback_info info)
207 {
208     size_t argc = 1;
209     napi_value argv[ARGV_LENGTH_1] = {nullptr};
210     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
211     napi_value global = nullptr;
212     napi_status status = napi_get_global(env, &global);
213     if (status != napi_ok) {
214         ZLOGE(LOG_LABEL, "get napi global failed");
215         return nullptr;
216     }
217     napi_value constructor = nullptr;
218     status = napi_get_named_property(env, global, "AshmemConstructor_", &constructor);
219     if (status != napi_ok) {
220         ZLOGE(LOG_LABEL, "get Ashmem constructor failed");
221         return nullptr;
222     }
223     bool isAshmem = false;
224     napi_instanceof(env, argv[ARGV_INDEX_0], constructor, &isAshmem);
225     if (isAshmem == false) {
226         ZLOGE(LOG_LABEL, "parameter is not instanceof Ashmem");
227         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
228     }
229     NAPIAshmem *napiAshmem = nullptr;
230     napi_unwrap(env, argv[ARGV_INDEX_0], (void **)&napiAshmem);
231     if (napiAshmem == nullptr) {
232         ZLOGE(LOG_LABEL, "napiAshmem is null");
233         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
234     }
235     int32_t fd = napiAshmem->GetAshmem()->GetAshmemFd();
236     uint32_t size = (uint32_t)(napiAshmem->GetAshmem()->GetAshmemSize());
237     if (fd <= 0 || size == 0) {
238         ZLOGE(LOG_LABEL, "fd <= 0 or  size == 0");
239         return nullptr;
240     }
241 
242     return getNewAshmemConstructor(env, constructor, fd, size);
243 }
244 
getNewAshmemConstructor(napi_env env,napi_value & constructor,int32_t fd,uint32_t size)245 napi_value NAPIAshmem::getNewAshmemConstructor(napi_env env, napi_value& constructor, int32_t fd, uint32_t size)
246 {
247     int dupFd = dup(fd);
248     if (dupFd < 0) {
249         ZLOGE(LOG_LABEL, "fail to dup fd:%{public}d", dupFd);
250         return napiErr.ThrowError(env, OHOS::errorDesc::OS_DUP_ERROR);
251     }
252     sptr<Ashmem> newAshmem(new Ashmem(dupFd, size));
253     if (newAshmem == nullptr) {
254         ZLOGE(LOG_LABEL, "newAshmem is null");
255         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
256     }
257 
258     napi_value jsAshmem = nullptr;
259     napi_status status = napi_new_instance(env, constructor, 0, nullptr, &jsAshmem);
260     if (status != napi_ok) {
261         ZLOGE(LOG_LABEL, "failed to  construct js Ashmem");
262         return nullptr;
263     }
264     NAPIAshmem *newNapiAshmem = nullptr;
265     napi_unwrap(env, jsAshmem, (void **)&newNapiAshmem);
266     if (newNapiAshmem == nullptr) {
267         ZLOGE(LOG_LABEL, "newNapiAshmem is null");
268         return nullptr;
269     }
270     newNapiAshmem->SetAshmem(newAshmem);
271     return jsAshmem;
272 }
273 
GetAshmemSize(napi_env env,napi_callback_info info)274 napi_value NAPIAshmem::GetAshmemSize(napi_env env, napi_callback_info info)
275 {
276     napi_value thisVar = nullptr;
277     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
278     NAPIAshmem *napiAshmem = nullptr;
279     napi_unwrap(env, thisVar, (void **)&napiAshmem);
280     NAPI_ASSERT(env, napiAshmem != nullptr, "napiAshmem is null");
281     uint32_t ashmemSize = (uint32_t)(napiAshmem->GetAshmem()->GetAshmemSize());
282     napi_value napiValue;
283     napi_create_uint32(env, ashmemSize, &napiValue);
284     return napiValue;
285 }
286 
MapAshmem(napi_env env,napi_callback_info info)287 napi_value NAPIAshmem::MapAshmem(napi_env env, napi_callback_info info)
288 {
289     napi_value thisVar = nullptr;
290     size_t argc = 1;
291     napi_value argv[ARGV_LENGTH_1] = {0};
292     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
293     NAPI_ASSERT(env, argc == 1, "requires 1 parameter");
294     napi_valuetype valueType = napi_null;
295     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
296     NAPI_ASSERT(env, valueType == napi_number, "type mismatch for parameter 1");
297     uint32_t mapType = 0;
298     napi_get_value_uint32(env, argv[ARGV_INDEX_0], &mapType);
299     NAPI_ASSERT(env, mapType <= MMAP_PROT_MAX, "napiAshmem mapType error");
300     NAPIAshmem *napiAshmem = nullptr;
301     napi_unwrap(env, thisVar, (void **)&napiAshmem);
302     NAPI_ASSERT(env, napiAshmem != nullptr, "napiAshmem is null");
303     bool result = napiAshmem->GetAshmem()->MapAshmem(mapType);
304     napi_value napiValue = nullptr;
305     NAPI_CALL(env, napi_get_boolean(env, result, &napiValue));
306     return napiValue;
307 }
308 
MapTypedAshmem(napi_env env,napi_callback_info info)309 napi_value NAPIAshmem::MapTypedAshmem(napi_env env, napi_callback_info info)
310 {
311     napi_value thisVar = nullptr;
312     size_t argc = 1;
313     napi_value argv[ARGV_LENGTH_1] = {0};
314     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
315     if (argc != 1) {
316         ZLOGE(LOG_LABEL, "requires 1 parameter");
317         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
318     }
319     napi_valuetype valueType = napi_null;
320     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
321     if (valueType != napi_number) {
322         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
323         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
324     }
325     uint32_t mapType = 0;
326     napi_get_value_uint32(env, argv[ARGV_INDEX_0], &mapType);
327     if (mapType > MMAP_PROT_MAX) {
328         ZLOGE(LOG_LABEL, "napiAshmem mapType error");
329         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
330     }
331     NAPIAshmem *napiAshmem = nullptr;
332     napi_unwrap(env, thisVar, (void **)&napiAshmem);
333     if (napiAshmem == nullptr) {
334         ZLOGE(LOG_LABEL, "napiAshmem is null");
335         return napiErr.ThrowError(env, OHOS::errorDesc::OS_MMAP_ERROR);
336     }
337     napiAshmem->GetAshmem()->MapAshmem(mapType);
338     napi_value result = nullptr;
339     napi_get_undefined(env, &result);
340     return result;
341 }
342 
MapReadAndWriteAshmem(napi_env env,napi_callback_info info)343 napi_value NAPIAshmem::MapReadAndWriteAshmem(napi_env env, napi_callback_info info)
344 {
345     napi_value thisVar = nullptr;
346     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
347     NAPIAshmem *napiAshmem = nullptr;
348     napi_unwrap(env, thisVar, (void **)&napiAshmem);
349     NAPI_ASSERT(env, napiAshmem != nullptr, "napiAshmem is null");
350     bool result = napiAshmem->GetAshmem()->MapReadAndWriteAshmem();
351     napi_value napiValue = nullptr;
352     NAPI_CALL(env, napi_get_boolean(env, result, &napiValue));
353     return napiValue;
354 }
355 
MapReadWriteAshmem(napi_env env,napi_callback_info info)356 napi_value NAPIAshmem::MapReadWriteAshmem(napi_env env, napi_callback_info info)
357 {
358     napi_value thisVar = nullptr;
359     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
360     NAPIAshmem *napiAshmem = nullptr;
361     napi_unwrap(env, thisVar, (void **)&napiAshmem);
362     if (napiAshmem == nullptr) {
363         ZLOGE(LOG_LABEL, "napiAshmem is null");
364         return napiErr.ThrowError(env, OHOS::errorDesc::OS_MMAP_ERROR);
365     }
366     napiAshmem->GetAshmem()->MapReadAndWriteAshmem();
367     napi_value result = nullptr;
368     napi_get_undefined(env, &result);
369     return result;
370 }
371 
MapReadOnlyAshmem(napi_env env,napi_callback_info info)372 napi_value NAPIAshmem::MapReadOnlyAshmem(napi_env env, napi_callback_info info)
373 {
374     napi_value thisVar = nullptr;
375     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
376     NAPIAshmem *napiAshmem = nullptr;
377     napi_unwrap(env, thisVar, (void **)&napiAshmem);
378     NAPI_ASSERT(env, napiAshmem != nullptr, "napiAshmem is null");
379     bool result = napiAshmem->GetAshmem()->MapReadOnlyAshmem();
380     napi_value napiValue = nullptr;
381     NAPI_CALL(env, napi_get_boolean(env, result, &napiValue));
382     return napiValue;
383 }
384 
MapReadonlyAshmem(napi_env env,napi_callback_info info)385 napi_value NAPIAshmem::MapReadonlyAshmem(napi_env env, napi_callback_info info)
386 {
387     napi_value thisVar = nullptr;
388     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
389     NAPIAshmem *napiAshmem = nullptr;
390     napi_unwrap(env, thisVar, (void **)&napiAshmem);
391     if (napiAshmem == nullptr) {
392         ZLOGE(LOG_LABEL, "napiAshmem is null");
393         return napiErr.ThrowError(env, OHOS::errorDesc::OS_MMAP_ERROR);
394     }
395     napiAshmem->GetAshmem()->MapReadOnlyAshmem();
396     napi_value result = nullptr;
397     napi_get_undefined(env, &result);
398     return result;
399 }
400 
ReadFromAshmem(napi_env env,napi_callback_info info)401 napi_value NAPIAshmem::ReadFromAshmem(napi_env env, napi_callback_info info)
402 {
403     napi_value thisVar = nullptr;
404     size_t argc = 2;
405     napi_value argv[ARGV_LENGTH_2] = {0};
406     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
407     NAPI_ASSERT(env, argc == 2, "requires 2 parameter");
408     napi_valuetype valueType = napi_null;
409     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
410     NAPI_ASSERT(env, valueType == napi_number, "type mismatch for parameter 1");
411     napi_typeof(env, argv[ARGV_INDEX_1], &valueType);
412     NAPI_ASSERT(env, valueType == napi_number, "type mismatch for parameter 2");
413     int64_t size = 0;
414     napi_get_value_int64(env, argv[ARGV_INDEX_0], &size);
415     int64_t offset = 0;
416     napi_get_value_int64(env, argv[ARGV_INDEX_1], &offset);
417     NAPIAshmem *napiAshmem = nullptr;
418     napi_unwrap(env, thisVar, (void **)&napiAshmem);
419     NAPI_ASSERT(env, napiAshmem != nullptr, "napiAshmem is null");
420 
421     uint32_t ashmemSize = (uint32_t)napiAshmem->GetAshmem()->GetAshmemSize();
422     if (size < 0 || size > static_cast<int64_t>(std::numeric_limits<int32_t>::max() / BYTE_SIZE_32) ||
423         offset < 0 || offset > static_cast<int64_t>(std::numeric_limits<int32_t>::max() / BYTE_SIZE_32) ||
424         (size * BYTE_SIZE_32 + offset * BYTE_SIZE_32) > ashmemSize) {
425         ZLOGE(LOG_LABEL, "invalid parameter, size:%{public}jd offset:%{public}jd", size, offset);
426         return nullptr;
427     }
428     size *= BYTE_SIZE_32;
429     offset *= BYTE_SIZE_32;
430     const void  *result = napiAshmem->GetAshmem()->ReadFromAshmem(size, offset);
431     if (result == nullptr) {
432         ZLOGE(LOG_LABEL, "ashmem->ReadFromAshmem returns null");
433         return nullptr;
434     }
435     // c++ byte[] to js []
436     napi_value arrayBuffer = nullptr;
437     void *arrayBufferPtr = nullptr;
438     napi_create_arraybuffer(env, size, &arrayBufferPtr, &arrayBuffer);
439     napi_value typedArray = nullptr;
440     napi_create_typedarray(env, napi_int32_array, size / BYTE_SIZE_32, arrayBuffer, 0, &typedArray);
441     bool isTypedArray = false;
442     napi_is_typedarray(env, typedArray, &isTypedArray);
443     NAPI_ASSERT(env, isTypedArray == true, "create  TypedArray failed");
444     if (size == 0) {
445         return typedArray;
446     }
447     errno_t status = memcpy_s(arrayBufferPtr, size, result, size);
448     NAPI_ASSERT(env, status == EOK, "memcpy_s is failed");
449     return typedArray;
450 }
451 
ReadAshmem(napi_env env,napi_callback_info info)452 napi_value NAPIAshmem::ReadAshmem(napi_env env, napi_callback_info info)
453 {
454     napi_value thisVar = nullptr;
455     size_t argc = 2;
456     size_t argNum = 2;
457     napi_value argv[ARGV_LENGTH_2] = {0};
458     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
459     if (argc != argNum) {
460         ZLOGE(LOG_LABEL, "requires 2 parameter");
461         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
462     }
463     napi_valuetype valueType = napi_null;
464     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
465     if (valueType != napi_number) {
466         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
467         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
468     }
469     napi_typeof(env, argv[ARGV_INDEX_1], &valueType);
470     if (valueType != napi_number) {
471         ZLOGE(LOG_LABEL, "type mismatch for parameter 2");
472         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
473     }
474     int64_t size = 0;
475     napi_get_value_int64(env, argv[ARGV_INDEX_0], &size);
476     int64_t offset = 0;
477     napi_get_value_int64(env, argv[ARGV_INDEX_1], &offset);
478     NAPIAshmem *napiAshmem = nullptr;
479     napi_unwrap(env, thisVar, (void **)&napiAshmem);
480     if (napiAshmem == nullptr) {
481         ZLOGE(LOG_LABEL, "napiAshmem is null");
482         return napiErr.ThrowError(env, OHOS::errorDesc::READ_FROM_ASHMEM_ERROR);
483     }
484     uint32_t ashmemSize = (uint32_t)napiAshmem->GetAshmem()->GetAshmemSize();
485     if (size < 0 || size > (int64_t)(std::numeric_limits<int32_t>::max() / BYTE_SIZE_32) ||
486         offset < 0 || offset > (int64_t)(std::numeric_limits<int32_t>::max() / BYTE_SIZE_32) ||
487         (size * BYTE_SIZE_32 + offset * BYTE_SIZE_32) > ashmemSize) {
488         ZLOGE(LOG_LABEL, "invalid parameter, size:%{public}jd offset:%{public}jd", size, offset);
489         return nullptr;
490     }
491     size *= BYTE_SIZE_32;
492     offset *= BYTE_SIZE_32;
493     const void  *result = napiAshmem->GetAshmem()->ReadFromAshmem(size, offset);
494     if (result == nullptr) {
495         ZLOGE(LOG_LABEL, "ashmem->ReadFromAshmem returns null");
496         return nullptr;
497     }
498     // c++ byte[] to js []
499     return TransferByteToJsData(env, size, result);
500 }
501 
TransferByteToJsData(napi_env env,uint32_t size,const void * result)502 napi_value NAPIAshmem::TransferByteToJsData(napi_env env, uint32_t size, const void *result)
503 {
504     napi_value arrayBuffer = nullptr;
505     void *arrayBufferPtr = nullptr;
506     napi_create_arraybuffer(env, size, &arrayBufferPtr, &arrayBuffer);
507     napi_value typedArray = nullptr;
508     napi_create_typedarray(env, napi_int32_array, size / BYTE_SIZE_32, arrayBuffer, 0, &typedArray);
509     bool isTypedArray = false;
510     napi_is_typedarray(env, typedArray, &isTypedArray);
511     NAPI_ASSERT(env, isTypedArray == true, "create  TypedArray failed");
512     if (!isTypedArray) {
513         ZLOGE(LOG_LABEL, "napiAshmem is null");
514         return napiErr.ThrowError(env, OHOS::errorDesc::READ_FROM_ASHMEM_ERROR);
515     }
516     if (size == 0) {
517         return typedArray;
518     }
519     errno_t status = memcpy_s(arrayBufferPtr, size, result, size);
520     if (status != EOK) {
521         ZLOGE(LOG_LABEL, "memcpy_s is failed");
522         return napiErr.ThrowError(env, OHOS::errorDesc::READ_FROM_ASHMEM_ERROR);
523     }
524     return typedArray;
525 }
526 
SetProtection(napi_env env,napi_callback_info info)527 napi_value NAPIAshmem::SetProtection(napi_env env, napi_callback_info info)
528 {
529     napi_value thisVar = nullptr;
530     size_t argc = 1;
531     napi_value argv[ARGV_LENGTH_1] = { 0 };
532     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
533     NAPI_ASSERT(env, argc == 1, "requires 1 parameter");
534     napi_valuetype valueType = napi_null;
535     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
536     NAPI_ASSERT(env, valueType == napi_number, "type mismatch for parameter 1");
537     uint32_t protectionType = 0;
538     napi_get_value_uint32(env, argv[ARGV_INDEX_0], &protectionType);
539     NAPIAshmem *napiAshmem = nullptr;
540     napi_unwrap(env, thisVar, (void **)&napiAshmem);
541     NAPI_ASSERT(env, napiAshmem != nullptr, "napiAshmem is null");
542     bool result = napiAshmem->GetAshmem()->SetProtection(protectionType);
543     napi_value napiValue = nullptr;
544     NAPI_CALL(env, napi_get_boolean(env, result, &napiValue));
545     return napiValue;
546 }
547 
SetProtectionType(napi_env env,napi_callback_info info)548 napi_value NAPIAshmem::SetProtectionType(napi_env env, napi_callback_info info)
549 {
550     napi_value thisVar = nullptr;
551     size_t argc = 1;
552     size_t argNum = 1;
553     napi_value argv[ARGV_LENGTH_1] = { 0 };
554     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
555     if (argc != argNum) {
556         ZLOGE(LOG_LABEL, "requires 1 parameter");
557         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
558     }
559     napi_valuetype valueType = napi_null;
560     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
561     if (valueType != napi_number) {
562         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
563         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
564     }
565     uint32_t protectionType = 0;
566     napi_get_value_uint32(env, argv[ARGV_INDEX_0], &protectionType);
567     NAPIAshmem *napiAshmem = nullptr;
568     napi_unwrap(env, thisVar, (void **)&napiAshmem);
569     if (napiAshmem == nullptr) {
570         ZLOGE(LOG_LABEL, "napiAshmem is null");
571         return napiErr.ThrowError(env, OHOS::errorDesc::OS_IOCTL_ERROR);
572     }
573     napiAshmem->GetAshmem()->SetProtection(protectionType);
574     napi_value result = nullptr;
575     napi_get_undefined(env, &result);
576     return result;
577 }
578 
UnmapAshmem(napi_env env,napi_callback_info info)579 napi_value NAPIAshmem::UnmapAshmem(napi_env env, napi_callback_info info)
580 {
581     napi_value thisVar = nullptr;
582     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
583     NAPIAshmem *napiAshmem = nullptr;
584     napi_unwrap(env, thisVar, (void **)&napiAshmem);
585     NAPI_ASSERT(env, napiAshmem != nullptr, "napiAshmem is null");
586     napiAshmem->GetAshmem()->UnmapAshmem();
587     napi_value result = nullptr;
588     napi_get_undefined(env, &result);
589     return result;
590 }
591 
WriteToAshmem(napi_env env,napi_callback_info info)592 napi_value NAPIAshmem::WriteToAshmem(napi_env env, napi_callback_info info)
593 {
594     size_t argc = 3;
595     napi_value argv[ARGV_LENGTH_3] = {0};
596     napi_value thisVar = nullptr;
597     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
598     NAPI_ASSERT(env, argc == 3, "requires 3 parameter");
599     bool isArray = false;
600     napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
601     NAPI_ASSERT(env, isArray == true, "type mismatch for parameter 1");
602     napi_valuetype valueType = napi_null;
603     napi_typeof(env, argv[ARGV_INDEX_1], &valueType);
604     NAPI_ASSERT(env, valueType == napi_number, "type mismatch for parameter 2");
605     napi_typeof(env, argv[ARGV_INDEX_2], &valueType);
606     NAPI_ASSERT(env, valueType == napi_number, "type mismatch for parameter 3");
607 
608     std::vector<int32_t> array;
609     uint32_t arrayLength = 0;
610     napi_get_array_length(env, argv[ARGV_INDEX_0], &arrayLength);
611 
612     for (size_t i = 0; i < arrayLength; i++) {
613         bool hasElement = false;
614         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
615         NAPI_ASSERT(env, hasElement == true, "parameter check error");
616 
617         napi_value element = nullptr;
618         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
619 
620         int32_t value = 0;
621         napi_get_value_int32(env, element, &value);
622         array.push_back(value);
623     }
624 
625     int64_t size = 0;
626     napi_get_value_int64(env, argv[ARGV_INDEX_1], &size);
627     int64_t offset = 0;
628     napi_get_value_int64(env, argv[ARGV_INDEX_2], &offset);
629     NAPIAshmem *napiAshmem = nullptr;
630     napi_unwrap(env, thisVar, (void **)&napiAshmem);
631     NAPI_ASSERT(env, napiAshmem != nullptr, "napiAshmem is null");
632 
633     // need check size offset and capacity
634     napi_value napiValue = nullptr;
635     bool result = true;
636     uint32_t ashmemSize = (uint32_t)napiAshmem->GetAshmem()->GetAshmemSize();
637     if (size < 0 || size > (int64_t)(std::numeric_limits<int32_t>::max() / BYTE_SIZE_32) ||
638         offset < 0 || offset > (int64_t)(std::numeric_limits<int32_t>::max() / BYTE_SIZE_32) ||
639         (size * BYTE_SIZE_32 + offset * BYTE_SIZE_32) > ashmemSize) {
640         ZLOGE(LOG_LABEL, "invalid parameter, size:%{public}jd offset:%{public}jd", size, offset);
641         result = false;
642     } else {
643         result = napiAshmem->GetAshmem()->WriteToAshmem(array.data(), size * BYTE_SIZE_32, offset * BYTE_SIZE_32);
644     }
645     NAPI_CALL(env, napi_get_boolean(env, result, &napiValue));
646     return napiValue;
647 }
648 
WriteAshmem(napi_env env,napi_callback_info info)649 napi_value NAPIAshmem::WriteAshmem(napi_env env, napi_callback_info info)
650 {
651     size_t argc = 3;
652     napi_value argv[ARGV_LENGTH_3] = {0};
653     napi_value thisVar = nullptr;
654     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
655     napi_value checkArgsResult = CheckWriteAshmemParams(env, argc, argv);
656     if (checkArgsResult != nullptr) {
657         return checkArgsResult;
658     }
659 
660     std::vector<int32_t> array;
661     uint32_t arrayLength = 0;
662     napi_get_array_length(env, argv[ARGV_INDEX_0], &arrayLength);
663 
664     for (size_t i = 0; i < arrayLength; i++) {
665         bool hasElement = false;
666         napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
667         if (!hasElement) {
668             ZLOGE(LOG_LABEL, "parameter check error");
669             return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
670         }
671 
672         napi_value element = nullptr;
673         napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
674 
675         int32_t value = 0;
676         napi_get_value_int32(env, element, &value);
677         array.push_back(value);
678     }
679 
680     int64_t size = 0;
681     napi_get_value_int64(env, argv[ARGV_INDEX_1], &size);
682     int64_t offset = 0;
683     napi_get_value_int64(env, argv[ARGV_INDEX_2], &offset);
684     NAPIAshmem *napiAshmem = nullptr;
685     napi_unwrap(env, thisVar, (void **)&napiAshmem);
686     if (napiAshmem == nullptr) {
687         ZLOGE(LOG_LABEL, "napiAshmem is null");
688         return napiErr.ThrowError(env, OHOS::errorDesc::WRITE_TO_ASHMEM_ERROR);
689     }
690 
691     // need check size offset and capacity
692     uint32_t ashmemSize = (uint32_t)napiAshmem->GetAshmem()->GetAshmemSize();
693     if (size < 0 || size > (int64_t)(std::numeric_limits<int32_t>::max() / BYTE_SIZE_32) ||
694         offset < 0 || offset > (int64_t)(std::numeric_limits<int32_t>::max() / BYTE_SIZE_32) ||
695         (size * BYTE_SIZE_32 + offset * BYTE_SIZE_32) > ashmemSize) {
696         ZLOGE(LOG_LABEL, "invalid parameter, size:%{public}jd offset:%{public}jd", size, offset);
697         return napiErr.ThrowError(env, OHOS::errorDesc::WRITE_TO_ASHMEM_ERROR);
698     }
699     napiAshmem->GetAshmem()->WriteToAshmem(array.data(), size * BYTE_SIZE_32, offset * BYTE_SIZE_32);
700     napi_value result = nullptr;
701     napi_get_undefined(env, &result);
702     return result;
703 }
704 
CheckWriteAshmemParams(napi_env env,size_t argc,napi_value * argv)705 napi_value NAPIAshmem::CheckWriteAshmemParams(napi_env env, size_t argc, napi_value* argv)
706 {
707     size_t argNum = 3;
708     if (argc != argNum) {
709         ZLOGE(LOG_LABEL, "requires 3 parameter");
710         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
711     }
712     bool isArray = false;
713     napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
714     if (!isArray) {
715         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
716         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
717     }
718     napi_valuetype valueType = napi_null;
719     napi_typeof(env, argv[ARGV_INDEX_1], &valueType);
720     if (valueType != napi_number) {
721         ZLOGE(LOG_LABEL, "type mismatch for parameter 2");
722         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
723     }
724     napi_typeof(env, argv[ARGV_INDEX_2], &valueType);
725     if (valueType != napi_number) {
726         ZLOGE(LOG_LABEL, "type mismatch for parameter 4");
727         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
728     }
729     return nullptr;
730 }
731 
CheckWriteToAshmemParams(napi_env env,size_t argc,napi_value * argv)732 napi_value NAPIAshmem::CheckWriteToAshmemParams(napi_env env, size_t argc, napi_value* argv)
733 {
734     if (argc != ARGV_LENGTH_3) {
735         ZLOGE(LOG_LABEL, "requires 3 parameter");
736         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
737     }
738 
739     bool isArrayBuffer = false;
740     napi_is_arraybuffer(env, argv[ARGV_INDEX_0], &isArrayBuffer);
741     if (!isArrayBuffer) {
742         ZLOGE(LOG_LABEL, "type mismatch for parameter 1, not ArrayBuffer");
743         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
744     }
745 
746     napi_valuetype valueType = napi_null;
747     napi_typeof(env, argv[ARGV_INDEX_1], &valueType);
748     if (valueType != napi_number) {
749         ZLOGE(LOG_LABEL, "type mismatch for parameter 2");
750         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
751     }
752 
753     napi_typeof(env, argv[ARGV_INDEX_2], &valueType);
754     if (valueType != napi_number) {
755         ZLOGE(LOG_LABEL, "type mismatch for parameter 3");
756         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
757     }
758     return nullptr;
759 }
760 
WriteDataToAshmem(napi_env env,napi_callback_info info)761 napi_value NAPIAshmem::WriteDataToAshmem(napi_env env, napi_callback_info info)
762 {
763     size_t argc = ARGV_LENGTH_3;
764     napi_value argv[ARGV_LENGTH_3] = {0};
765     napi_value thisVar = nullptr;
766     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
767     napi_value checkArgsResult = CheckWriteToAshmemParams(env, argc, argv);
768     if (checkArgsResult != nullptr) {
769         return checkArgsResult;
770     }
771 
772     void *data = nullptr;
773     size_t byteLength = 0;
774     napi_status isGet = napi_get_arraybuffer_info(env, argv[ARGV_INDEX_0], (void **)&data, &byteLength);
775     if (isGet != napi_ok) {
776         ZLOGE(LOG_LABEL, "arraybuffer get info failed");
777         return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
778     }
779 
780     int64_t size = 0;
781     napi_get_value_int64(env, argv[ARGV_INDEX_1], &size);
782     int64_t offset = 0;
783     napi_get_value_int64(env, argv[ARGV_INDEX_2], &offset);
784     NAPIAshmem *napiAshmem = nullptr;
785     napi_unwrap(env, thisVar, (void **)&napiAshmem);
786     if (napiAshmem == nullptr) {
787         ZLOGE(LOG_LABEL, "napiAshmem is null");
788         return napiErr.ThrowError(env, OHOS::errorDesc::WRITE_TO_ASHMEM_ERROR);
789     }
790 
791     uint32_t ashmemSize = (uint32_t)napiAshmem->GetAshmem()->GetAshmemSize();
792     if (size <= 0 || size > std::numeric_limits<int32_t>::max() ||
793         offset < 0 || offset > std::numeric_limits<int32_t>::max() ||
794         (size + offset) > ashmemSize) {
795         ZLOGE(LOG_LABEL, "invalid parameter, size:%{public}" PRId64 " offset:%{public}" PRId64, size, offset);
796         return napiErr.ThrowError(env, OHOS::errorDesc::WRITE_TO_ASHMEM_ERROR);
797     }
798 
799     if (!napiAshmem->GetAshmem()->WriteToAshmem(data, size, offset)) {
800         ZLOGE(LOG_LABEL, "WriteToAshmem fail");
801         return napiErr.ThrowError(env, OHOS::errorDesc::WRITE_TO_ASHMEM_ERROR);
802     }
803     napi_value result = nullptr;
804     napi_get_undefined(env, &result);
805     return result;
806 }
807 
CheckReadFromAshmemParams(napi_env env,size_t argc,napi_value * argv)808 napi_value NAPIAshmem::CheckReadFromAshmemParams(napi_env env, size_t argc, napi_value* argv)
809 {
810     if (argc != ARGV_LENGTH_2) {
811         ZLOGE(LOG_LABEL, "requires 2 parameter");
812         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
813     }
814     napi_valuetype valueType = napi_null;
815     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
816     if (valueType != napi_number) {
817         ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
818         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
819     }
820     napi_typeof(env, argv[ARGV_INDEX_1], &valueType);
821     if (valueType != napi_number) {
822         ZLOGE(LOG_LABEL, "type mismatch for parameter 2");
823         return napiErr.ThrowError(env, OHOS::errorDesc::CHECK_PARAM_ERROR);
824     }
825     return nullptr;
826 }
827 
ReadDataFromAshmem(napi_env env,napi_callback_info info)828 napi_value NAPIAshmem::ReadDataFromAshmem(napi_env env, napi_callback_info info)
829 {
830     size_t argc = ARGV_LENGTH_2;
831     napi_value argv[ARGV_LENGTH_2] = {0};
832     napi_value thisVar = nullptr;
833     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
834     napi_value checkArgsResult = CheckReadFromAshmemParams(env, argc, argv);
835     if (checkArgsResult != nullptr) {
836         return checkArgsResult;
837     }
838 
839     int64_t size = 0;
840     napi_get_value_int64(env, argv[ARGV_INDEX_0], &size);
841     int64_t offset = 0;
842     napi_get_value_int64(env, argv[ARGV_INDEX_1], &offset);
843     NAPIAshmem *napiAshmem = nullptr;
844     napi_unwrap(env, thisVar, (void **)&napiAshmem);
845     if (napiAshmem == nullptr) {
846         ZLOGE(LOG_LABEL, "napiAshmem is null");
847         return napiErr.ThrowError(env, OHOS::errorDesc::READ_FROM_ASHMEM_ERROR);
848     }
849     uint32_t ashmemSize = (uint32_t)napiAshmem->GetAshmem()->GetAshmemSize();
850     if (size <= 0 || size > std::numeric_limits<int32_t>::max() ||
851         offset < 0 || offset > std::numeric_limits<int32_t>::max() ||
852         (size + offset) > ashmemSize) {
853         ZLOGE(LOG_LABEL, "invalid parameter, size:%{public}" PRId64 " offset:%{public}" PRId64, size, offset);
854         return napiErr.ThrowError(env, OHOS::errorDesc::READ_FROM_ASHMEM_ERROR);
855     }
856 
857     const void *result = napiAshmem->GetAshmem()->ReadFromAshmem(size, offset);
858     if (result == nullptr) {
859         ZLOGE(LOG_LABEL, "ashmem->ReadFromAshmem returns null");
860         return napiErr.ThrowError(env, OHOS::errorDesc::READ_FROM_ASHMEM_ERROR);
861     }
862 
863     napi_value arrayBuffer = nullptr;
864     void *arrayBufferPtr = nullptr;
865     size_t bufferSize = static_cast<size_t>(size);
866     napi_status isCreateBufferOk = napi_create_arraybuffer(env, size, &arrayBufferPtr, &arrayBuffer);
867     if (isCreateBufferOk != napi_ok) {
868         ZLOGE(LOG_LABEL, "ReadDataFromAshmem create arrayBuffer failed");
869         return napiErr.ThrowError(env, errorDesc::READ_FROM_ASHMEM_ERROR);
870     }
871     errno_t status = memcpy_s(arrayBufferPtr, bufferSize, result, bufferSize);
872     if (status != EOK) {
873         ZLOGE(LOG_LABEL, "memcpy_s is failed");
874         return napiErr.ThrowError(env, OHOS::errorDesc::READ_FROM_ASHMEM_ERROR);
875     }
876     return arrayBuffer;
877 }
878 
AshmemExport(napi_env env,napi_value exports)879 napi_value NAPIAshmem::AshmemExport(napi_env env, napi_value exports)
880 {
881     const std::string className = "Ashmem";
882     napi_value exec = nullptr;
883     napi_create_int32(env, NAPIAshmem::PROT_EXEC, &exec);
884     napi_value none = nullptr;
885     napi_create_int32(env, NAPIAshmem::PROT_NONE, &none);
886     napi_value read = nullptr;
887     napi_create_int32(env, NAPIAshmem::PROT_READ, &read);
888     napi_value write = nullptr;
889     napi_create_int32(env, NAPIAshmem::PROT_WRITE, &write);
890     napi_property_descriptor properties[] = {
891         DECLARE_NAPI_STATIC_FUNCTION("createAshmem", NAPIAshmem::CreateAshmem),
892         DECLARE_NAPI_STATIC_FUNCTION("create", NAPIAshmem::Create),
893         DECLARE_NAPI_STATIC_FUNCTION("createAshmemFromExisting", NAPIAshmem::CreateAshmemFromExisting),
894         DECLARE_NAPI_FUNCTION("closeAshmem", NAPIAshmem::CloseAshmem),
895         DECLARE_NAPI_FUNCTION("getAshmemSize", NAPIAshmem::GetAshmemSize),
896         DECLARE_NAPI_FUNCTION("mapAshmem", NAPIAshmem::MapAshmem),
897         DECLARE_NAPI_FUNCTION("mapTypedAshmem", NAPIAshmem::MapTypedAshmem),
898         DECLARE_NAPI_FUNCTION("mapReadAndWriteAshmem", NAPIAshmem::MapReadAndWriteAshmem),
899         DECLARE_NAPI_FUNCTION("mapReadWriteAshmem", NAPIAshmem::MapReadWriteAshmem),
900         DECLARE_NAPI_FUNCTION("mapReadOnlyAshmem", NAPIAshmem::MapReadOnlyAshmem),
901         DECLARE_NAPI_FUNCTION("mapReadonlyAshmem", NAPIAshmem::MapReadonlyAshmem),
902         DECLARE_NAPI_FUNCTION("readFromAshmem", NAPIAshmem::ReadFromAshmem),
903         DECLARE_NAPI_FUNCTION("readAshmem", NAPIAshmem::ReadAshmem),
904         DECLARE_NAPI_FUNCTION("setProtection", NAPIAshmem::SetProtection),
905         DECLARE_NAPI_FUNCTION("setProtectionType", NAPIAshmem::SetProtectionType),
906         DECLARE_NAPI_FUNCTION("unmapAshmem", NAPIAshmem::UnmapAshmem),
907         DECLARE_NAPI_FUNCTION("writeToAshmem", NAPIAshmem::WriteToAshmem),
908         DECLARE_NAPI_FUNCTION("writeAshmem", NAPIAshmem::WriteAshmem),
909         DECLARE_NAPI_FUNCTION("writeDataToAshmem", NAPIAshmem::WriteDataToAshmem),
910         DECLARE_NAPI_FUNCTION("readDataFromAshmem", NAPIAshmem::ReadDataFromAshmem),
911         DECLARE_NAPI_STATIC_PROPERTY("PROT_EXEC", exec),
912         DECLARE_NAPI_STATIC_PROPERTY("PROT_NONE", none),
913         DECLARE_NAPI_STATIC_PROPERTY("PROT_READ", read),
914         DECLARE_NAPI_STATIC_PROPERTY("PROT_WRITE", write),
915     };
916     napi_value constructor = nullptr;
917     napi_define_class(env, className.c_str(), className.length(), Ashmem_JS_Constructor, nullptr,
918         sizeof(properties) / sizeof(properties[0]), properties, &constructor);
919     NAPI_ASSERT(env, constructor != nullptr, "define js class Ashmem failed");
920     napi_status status = napi_set_named_property(env, exports, "Ashmem", constructor);
921     NAPI_ASSERT(env, status == napi_ok, "set property Ashmem failed");
922     napi_value global = nullptr;
923     status = napi_get_global(env, &global);
924     NAPI_ASSERT(env, status == napi_ok, "get napi global failed");
925     status = napi_set_named_property(env, global, "AshmemConstructor_", constructor);
926     NAPI_ASSERT(env, status == napi_ok, "set Ashmem constructor failed");
927     return exports;
928 }
929 
Ashmem_JS_Constructor(napi_env env,napi_callback_info info)930 napi_value NAPIAshmem::Ashmem_JS_Constructor(napi_env env, napi_callback_info info)
931 {
932     napi_value thisVar = nullptr;
933     size_t argc = 2;
934     napi_value argv[ARGV_LENGTH_2] = { 0 };
935     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
936     NAPIAshmem *napiAshmem = nullptr;
937     if (argc == 0) {
938         napiAshmem = new (std::nothrow) NAPIAshmem();
939     } else {
940         NAPI_ASSERT(env, argc == 2, "requires 2 parameter");
941         napi_valuetype valueType = napi_null;
942         napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
943         NAPI_ASSERT(env, valueType == napi_string, "type mismatch for parameter 1");
944         napi_typeof(env, argv[ARGV_INDEX_1], &valueType);
945         NAPI_ASSERT(env, valueType == napi_number, "type mismatch for parameter 2");
946         size_t bufferSize = 0;
947         size_t maxLen = 40960;
948         napi_get_value_string_utf8(env, argv[ARGV_INDEX_0], nullptr, 0, &bufferSize);
949         NAPI_ASSERT(env, bufferSize < maxLen, "string length too large");
950         char stringValue[bufferSize + 1];
951         size_t jsStringLength = 0;
952         napi_get_value_string_utf8(env, argv[ARGV_INDEX_0], stringValue, bufferSize + 1, &jsStringLength);
953         NAPI_ASSERT(env, jsStringLength == bufferSize, "string length wrong");
954         std::string ashmemName = stringValue;
955         uint32_t ashmemSize = 0;
956         napi_get_value_uint32(env, argv[ARGV_INDEX_1], &ashmemSize);
957         // new napi Ashmem
958         sptr<Ashmem> nativeAshmem = Ashmem::CreateAshmem(ashmemName.c_str(), ashmemSize);
959         NAPI_ASSERT(env, nativeAshmem != nullptr, "invalid parameters");
960         napiAshmem = new (std::nothrow) NAPIAshmem(nativeAshmem);
961     }
962     NAPI_ASSERT(env, napiAshmem != nullptr, "new NAPIAshmem failed");
963     // connect native object to js thisVar
964     napi_status status = napi_wrap(
965         env, thisVar, napiAshmem,
966         [](napi_env env, void *data, void *hint) {
967             ZLOGD(LOG_LABEL, "Ashmem destructed by js callback");
968             delete (reinterpret_cast<NAPIAshmem *>(data));
969         },
970         nullptr, nullptr);
971     if (status != napi_ok) {
972         delete napiAshmem;
973         NAPI_ASSERT(env, false, "wrap js Ashmem and native holder failed");
974     }
975     return thisVar;
976 }
977 } // namespace OHOS
978