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