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