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