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