1 /*
2 * Copyright (c) 2023 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_remote_object_holder.h"
17 #include "napi_remote_object_internal.h"
18
19 #include <hitrace_meter.h>
20 #include <string_ex.h>
21 #include <uv.h>
22
23 #include "ipc_debug.h"
24 #include "ipc_process_skeleton.h"
25 #include "iremote_invoker.h"
26 #include "log_tags.h"
27 #include "napi/native_api.h"
28 #include "napi/native_node_api.h"
29 #include "napi_message_parcel.h"
30 #include "napi_message_sequence.h"
31 #include "napi_remote_proxy_holder.h"
32 #include "napi_rpc_error.h"
33 #include "native_engine/native_value.h"
34 #include "napi_process_skeleton.h"
35
36 namespace OHOS {
37 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_IPC_NAPI, "napi_remoteObject" };
38
39 static const size_t ARGV_INDEX_0 = 0;
40 static const size_t ARGV_INDEX_1 = 1;
41 static const size_t ARGV_INDEX_2 = 2;
42 static const size_t ARGV_INDEX_3 = 3;
43 static const size_t ARGV_INDEX_4 = 4;
44
45 static const size_t ARGV_LENGTH_1 = 1;
46 static const size_t ARGV_LENGTH_2 = 2;
47 static const size_t ARGV_LENGTH_5 = 5;
48 static const uint64_t HITRACE_TAG_RPC = (1ULL << 46); // RPC and IPC tag.
49
50 static std::atomic<int32_t> bytraceId = 1000;
51 static NapiError napiErr;
52
RemoteObjectHolderFinalizeCb(napi_env env,void * data,void * hint)53 static void RemoteObjectHolderFinalizeCb(napi_env env, void *data, void *hint)
54 {
55 NAPIRemoteObjectHolder *holder = reinterpret_cast<NAPIRemoteObjectHolder *>(data);
56 if (holder == nullptr) {
57 ZLOGW(LOG_LABEL, "RemoteObjectHolderFinalizeCb null holder");
58 return;
59 }
60 holder->Lock();
61 int32_t curAttachCount = holder->DecAttachCount();
62 ZLOGD(LOG_LABEL, "NAPIRemoteObjectHolder destructed by js callback, curAttachCount:%{public}d", curAttachCount);
63 if (curAttachCount == 0) {
64 delete holder;
65 }
66 }
67
DecreaseJsObjectRef(napi_env env,napi_ref ref)68 static void DecreaseJsObjectRef(napi_env env, napi_ref ref)
69 {
70 if (ref == nullptr) {
71 ZLOGI(LOG_LABEL, "ref is nullptr, do nothing");
72 return;
73 }
74
75 uint32_t result;
76 napi_status napiStatus = napi_reference_unref(env, ref, &result);
77 NAPI_ASSERT_RETURN_VOID(env, napiStatus == napi_ok, "failed to decrease ref to js RemoteObject");
78 }
79
IncreaseJsObjectRef(napi_env env,napi_ref ref)80 static void IncreaseJsObjectRef(napi_env env, napi_ref ref)
81 {
82 uint32_t result;
83 napi_status napiStatus = napi_reference_ref(env, ref, &result);
84 NAPI_ASSERT_RETURN_VOID(env, napiStatus == napi_ok, "failed to increase ref to js RemoteObject");
85 }
86
RemoteObjectHolderRefCb(napi_env env,void * data,void * hint)87 static void RemoteObjectHolderRefCb(napi_env env, void *data, void *hint)
88 {
89 NAPIRemoteObjectHolder *holder = reinterpret_cast<NAPIRemoteObjectHolder *>(data);
90 if (holder == nullptr) {
91 ZLOGW(LOG_LABEL, "RemoteObjectHolderRefCb holder is nullptr");
92 return;
93 }
94 holder->Lock();
95 int32_t curAttachCount = holder->DecAttachCount();
96 holder->Unlock();
97 ZLOGD(LOG_LABEL, "RemoteObjectHolderRefCb, curAttachCount:%{public}d", curAttachCount);
98
99 napi_ref ref = holder->GetJsObjectRef();
100 napi_env workerEnv = holder->GetJsObjectEnv();
101 if (ref == nullptr || workerEnv == nullptr) {
102 ZLOGE(LOG_LABEL, "ref or env is null");
103 return;
104 }
105 uv_loop_s *loop = nullptr;
106 napi_get_uv_event_loop(workerEnv, &loop);
107 uv_work_t *work = new(std::nothrow) uv_work_t;
108 NAPI_ASSERT_RETURN_VOID(workerEnv, work != nullptr, "cb failed to new work");
109 OperateJsRefParam *param = new OperateJsRefParam {
110 .env = workerEnv,
111 .thisVarRef = ref
112 };
113 work->data = reinterpret_cast<void *>(param);
114 int uvRet = uv_queue_work(loop, work, [](uv_work_t *work) {
115 ZLOGD(LOG_LABEL, "enter work pool.");
116 }, [](uv_work_t *work, int status) {
117 ZLOGI(LOG_LABEL, "decrease on uv work thread");
118 OperateJsRefParam *param = reinterpret_cast<OperateJsRefParam *>(work->data);
119 napi_handle_scope scope = nullptr;
120 napi_open_handle_scope(param->env, &scope);
121 DecreaseJsObjectRef(param->env, param->thisVarRef);
122 napi_close_handle_scope(param->env, scope);
123 delete param;
124 delete work;
125 });
126 if (uvRet != 0) {
127 ZLOGE(LOG_LABEL, "uv_queue_work failed, ret %{public}d", uvRet);
128 }
129 }
130
RemoteObjectDetachCb(napi_env engine,void * value,void * hint)131 static void *RemoteObjectDetachCb(napi_env engine, void *value, void *hint)
132 {
133 (void)hint;
134 napi_env env = engine;
135 NAPIRemoteObjectHolder *holder = reinterpret_cast<NAPIRemoteObjectHolder *>(value);
136 napi_ref ref = holder->GetJsObjectRef();
137
138 uint32_t result;
139 napi_status napiStatus = napi_reference_ref(env, ref, &result);
140 if (napiStatus != napi_ok) {
141 ZLOGE(LOG_LABEL, "RemoteObjectDetachCb, failed to increase ref");
142 } else {
143 ZLOGI(LOG_LABEL, "RemoteObjectDetachCb, ref result:%{public}u", result);
144 }
145 return value;
146 }
147
RemoteObjectAttachCb(napi_env engine,void * value,void * hint)148 static napi_value RemoteObjectAttachCb(napi_env engine, void *value, void *hint)
149 {
150 (void)hint;
151 NAPIRemoteObjectHolder *holder = reinterpret_cast<NAPIRemoteObjectHolder *>(value);
152 if (holder == nullptr) {
153 ZLOGE(LOG_LABEL, "holder is nullptr when attach");
154 return nullptr;
155 }
156 holder->Lock();
157 ZLOGI(LOG_LABEL, "create js remote object when attach");
158 napi_env env = engine;
159 // retrieve js remote object constructor
160 napi_value global = nullptr;
161 napi_status status = napi_get_global(env, &global);
162 NAPI_ASSERT(env, status == napi_ok, "get napi global failed");
163 napi_value constructor = nullptr;
164 status = napi_get_named_property(env, global, "IPCStubConstructor_", &constructor);
165 NAPI_ASSERT(env, status == napi_ok, "get stub constructor failed");
166 NAPI_ASSERT(env, constructor != nullptr, "failed to get js RemoteObject constructor");
167 // retrieve descriptor and it's length
168 std::u16string descriptor = holder->GetDescriptor();
169 std::string desc = Str16ToStr8(descriptor);
170 napi_value jsDesc = nullptr;
171 napi_create_string_utf8(env, desc.c_str(), desc.length(), &jsDesc);
172 // create a new js remote object
173 size_t argc = 1;
174 napi_value argv[ARGV_LENGTH_1] = { jsDesc };
175 napi_value jsRemoteObject = nullptr;
176 status = napi_new_instance(env, constructor, argc, argv, &jsRemoteObject);
177 NAPI_ASSERT(env, status == napi_ok, "failed to construct js RemoteObject when attach");
178 // retrieve and remove create holder
179 NAPIRemoteObjectHolder *createHolder = nullptr;
180 status = napi_remove_wrap(env, jsRemoteObject, (void **)&createHolder);
181 NAPI_ASSERT(env, status == napi_ok && createHolder != nullptr, "failed to remove create holder when attach");
182 status = napi_wrap(env, jsRemoteObject, holder, RemoteObjectHolderRefCb, nullptr, nullptr);
183 NAPI_ASSERT(env, status == napi_ok, "wrap js RemoteObject and native holder failed when attach");
184 holder->IncAttachCount();
185 holder->Unlock();
186 return jsRemoteObject;
187 }
188
RemoteObject_JS_Constructor(napi_env env,napi_callback_info info)189 napi_value RemoteObject_JS_Constructor(napi_env env, napi_callback_info info)
190 {
191 // new napi remote object
192 size_t argc = 2;
193 size_t expectedArgc = 1;
194 napi_value argv[ARGV_LENGTH_2] = { 0 };
195 napi_value thisVar = nullptr;
196 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
197 NAPI_ASSERT(env, argc >= expectedArgc, "requires at least 1 parameters");
198 napi_valuetype valueType = napi_null;
199 napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
200 NAPI_ASSERT(env, valueType == napi_string, "type mismatch for parameter 1");
201 size_t bufferSize = 0;
202 size_t maxLen = 40960;
203 napi_get_value_string_utf8(env, argv[ARGV_INDEX_0], nullptr, 0, &bufferSize);
204 NAPI_ASSERT(env, bufferSize < maxLen, "string length too large");
205 char stringValue[bufferSize + 1];
206 size_t jsStringLength = 0;
207 napi_get_value_string_utf8(env, argv[ARGV_INDEX_0], stringValue, bufferSize + 1, &jsStringLength);
208 NAPI_ASSERT(env, jsStringLength == bufferSize, "string length wrong");
209 std::string descriptor = stringValue;
210 auto holder = new NAPIRemoteObjectHolder(env, Str8ToStr16(descriptor), thisVar);
211 napi_coerce_to_native_binding_object(env, thisVar, RemoteObjectDetachCb, RemoteObjectAttachCb, holder, nullptr);
212 // connect native object to js thisVar
213 napi_status status = napi_wrap(env, thisVar, holder, RemoteObjectHolderFinalizeCb, nullptr, nullptr);
214 NAPI_ASSERT(env, status == napi_ok, "wrap js RemoteObject and native holder failed");
215 return thisVar;
216 }
217
NAPIRemoteObject(std::thread::id jsThreadId,napi_env env,napi_ref jsObjectRef,const std::u16string & descriptor)218 NAPIRemoteObject::NAPIRemoteObject(std::thread::id jsThreadId, napi_env env, napi_ref jsObjectRef,
219 const std::u16string &descriptor)
220 : IPCObjectStub(descriptor)
221 {
222 ZLOGD(LOG_LABEL, "created, desc:%{public}s", Str16ToStr8(descriptor_).c_str());
223 env_ = env;
224 jsThreadId_ = jsThreadId;
225 thisVarRef_ = jsObjectRef;
226
227 if (jsThreadId_ == std::this_thread::get_id()) {
228 IncreaseJsObjectRef(env, jsObjectRef);
229 } else {
230 uv_loop_s *loop = nullptr;
231 napi_get_uv_event_loop(env_, &loop);
232 uv_work_t *work = new(std::nothrow) uv_work_t;
233 NAPI_ASSERT_RETURN_VOID(env_, work != nullptr, "create NAPIRemoteObject, new work failed");
234 std::shared_ptr<struct ThreadLockInfo> lockInfo = std::make_shared<struct ThreadLockInfo>();
235 OperateJsRefParam *param = new OperateJsRefParam {
236 .env = env_,
237 .thisVarRef = jsObjectRef,
238 .lockInfo = lockInfo.get()
239 };
240
241 work->data = reinterpret_cast<void *>(param);
242 int uvRet = uv_queue_work(loop, work, [](uv_work_t *work) {
243 ZLOGD(LOG_LABEL, "enter work pool.");
244 }, [](uv_work_t *work, int status) {
245 OperateJsRefParam *param = reinterpret_cast<OperateJsRefParam *>(work->data);
246 napi_handle_scope scope = nullptr;
247 napi_open_handle_scope(param->env, &scope);
248 IncreaseJsObjectRef(param->env, param->thisVarRef);
249 std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
250 param->lockInfo->ready = true;
251 param->lockInfo->condition.notify_all();
252 napi_close_handle_scope(param->env, scope);
253 });
254 if (uvRet != 0) {
255 ZLOGE(LOG_LABEL, "uv_queue_work failed, ret %{public}d", uvRet);
256 } else {
257 std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
258 param->lockInfo->condition.wait(lock, [¶m] { return param->lockInfo->ready; });
259 }
260 delete param;
261 delete work;
262 }
263 }
264
~NAPIRemoteObject()265 NAPIRemoteObject::~NAPIRemoteObject()
266 {
267 ZLOGD(LOG_LABEL, "destoryed, desc:%{public}s", Str16ToStr8(descriptor_).c_str());
268 if (thisVarRef_ != nullptr && env_ != nullptr) {
269 if (jsThreadId_ == std::this_thread::get_id()) {
270 DecreaseJsObjectRef(env_, thisVarRef_);
271 } else {
272 uv_loop_s *loop = nullptr;
273 napi_get_uv_event_loop(env_, &loop);
274 uv_work_t *work = new(std::nothrow) uv_work_t;
275 NAPI_ASSERT_RETURN_VOID(env_, work != nullptr, "release NAPIRemoteObject, new work failed");
276 OperateJsRefParam *param = new OperateJsRefParam {
277 .env = env_,
278 .thisVarRef = thisVarRef_
279 };
280 work->data = reinterpret_cast<void *>(param);
281 int uvRet = uv_queue_work(loop, work, [](uv_work_t *work) {
282 ZLOGD(LOG_LABEL, "enter work pool.");
283 }, [](uv_work_t *work, int status) {
284 OperateJsRefParam *param = reinterpret_cast<OperateJsRefParam *>(work->data);
285 napi_handle_scope scope = nullptr;
286 napi_open_handle_scope(param->env, &scope);
287 DecreaseJsObjectRef(param->env, param->thisVarRef);
288 napi_close_handle_scope(param->env, scope);
289 delete param;
290 delete work;
291 });
292 if (uvRet != 0) {
293 ZLOGE(LOG_LABEL, "uv_queue_work failed, ret %{public}d", uvRet);
294 }
295 }
296 thisVarRef_ = nullptr;
297 }
298 }
299
CheckObjectLegality() const300 bool NAPIRemoteObject::CheckObjectLegality() const
301 {
302 return true;
303 }
304
GetObjectType() const305 int NAPIRemoteObject::GetObjectType() const
306 {
307 return OBJECT_TYPE_JAVASCRIPT;
308 }
309
GetJsObjectRef() const310 napi_ref NAPIRemoteObject::GetJsObjectRef() const
311 {
312 return thisVarRef_;
313 }
314
ResetJsEnv()315 void NAPIRemoteObject::ResetJsEnv()
316 {
317 env_ = nullptr;
318 thisVarRef_ = nullptr;
319 }
320
NAPI_RemoteObject_getCallingInfo(CallingInfo & newCallingInfoParam)321 void NAPI_RemoteObject_getCallingInfo(CallingInfo &newCallingInfoParam)
322 {
323 newCallingInfoParam.callingPid = IPCSkeleton::GetCallingPid();
324 newCallingInfoParam.callingUid = IPCSkeleton::GetCallingUid();
325 newCallingInfoParam.callingTokenId = IPCSkeleton::GetCallingTokenID();
326 newCallingInfoParam.callingDeviceID = IPCSkeleton::GetCallingDeviceID();
327 newCallingInfoParam.localDeviceID = IPCSkeleton::GetLocalDeviceID();
328 newCallingInfoParam.isLocalCalling = IPCSkeleton::IsLocalCalling();
329 newCallingInfoParam.activeStatus = IRemoteInvoker::ACTIVE_INVOKER;
330 };
331
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)332 int NAPIRemoteObject::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
333 {
334 ZLOGD(LOG_LABEL, "enter OnRemoteRequest");
335 if (code == DUMP_TRANSACTION) {
336 ZLOGE(LOG_LABEL, "DUMP_TRANSACTION data size:%{public}zu", data.GetReadableBytes());
337 }
338 std::shared_ptr<struct ThreadLockInfo> lockInfo = std::make_shared<struct ThreadLockInfo>();
339 CallbackParam *param = new CallbackParam {
340 .env = env_,
341 .thisVarRef = thisVarRef_,
342 .code = code,
343 .data = &data,
344 .reply = &reply,
345 .option = &option,
346 .lockInfo = lockInfo.get(),
347 .result = 0
348 };
349
350 NAPI_RemoteObject_getCallingInfo(param->callingInfo);
351 ZLOGD(LOG_LABEL, "callingPid:%{public}u callingUid:%{public}u "
352 "callingDeviceID:%{public}s localDeviceId:%{public}s localCalling:%{public}d",
353 param->callingInfo.callingPid, param->callingInfo.callingUid,
354 IPCProcessSkeleton::ConvertToSecureString(param->callingInfo.callingDeviceID).c_str(),
355 IPCProcessSkeleton::ConvertToSecureString(param->callingInfo.localDeviceID).c_str(),
356 param->callingInfo.isLocalCalling);
357 int ret = OnJsRemoteRequest(param);
358 if (ret != 0) {
359 uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(
360 std::chrono::steady_clock::now().time_since_epoch()).count());
361 ZLOGE(LOG_LABEL, "OnJsRemoteRequest failed, ret:%{public}d time:%{public}" PRIu64, ret, curTime);
362 }
363 return ret;
364 }
365
ThenCallback(napi_env env,napi_callback_info info)366 napi_value NAPIRemoteObject::ThenCallback(napi_env env, napi_callback_info info)
367 {
368 ZLOGD(LOG_LABEL, "call js onRemoteRequest done");
369 size_t argc = 1;
370 napi_value argv[ARGV_LENGTH_1] = {nullptr};
371 void* data = nullptr;
372 napi_get_cb_info(env, info, &argc, argv, nullptr, &data);
373 CallbackParam *param = static_cast<CallbackParam *>(data);
374 bool result = false;
375 napi_get_value_bool(param->env, argv[ARGV_INDEX_0], &result);
376 if (!result) {
377 uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(
378 std::chrono::steady_clock::now().time_since_epoch()).count());
379 ZLOGE(LOG_LABEL, "OnRemoteRequest res:%{public}s time:%{public}" PRIu64, result ? "true" : "false", curTime);
380 param->result = ERR_UNKNOWN_TRANSACTION;
381 } else {
382 param->result = ERR_NONE;
383 }
384 std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
385 param->lockInfo->ready = true;
386 param->lockInfo->condition.notify_all();
387 napi_value res;
388 napi_get_undefined(env, &res);
389 return res;
390 }
391
CatchCallback(napi_env env,napi_callback_info info)392 napi_value NAPIRemoteObject::CatchCallback(napi_env env, napi_callback_info info)
393 {
394 ZLOGI(LOG_LABEL, "Async onReomteReuqest's returnVal is rejected");
395 size_t argc = 1;
396 napi_value argv[ARGV_LENGTH_1] = {nullptr};
397 void* data = nullptr;
398 napi_get_cb_info(env, info, &argc, argv, nullptr, &data);
399 napi_value res;
400 CallbackParam *param = static_cast<CallbackParam *>(data);
401 if (param == nullptr) {
402 ZLOGE(LOG_LABEL, "param is null");
403 napi_get_undefined(env, &res);
404 return res;
405 }
406
407 param->result = ERR_UNKNOWN_TRANSACTION;
408 std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
409 param->lockInfo->ready = true;
410 param->lockInfo->condition.notify_all();
411 napi_get_undefined(env, &res);
412 return res;
413 }
414
NAPI_RemoteObject_saveOldCallingInfo(napi_env env,NAPI_CallingInfo & oldCallingInfo)415 void NAPI_RemoteObject_saveOldCallingInfo(napi_env env, NAPI_CallingInfo &oldCallingInfo)
416 {
417 napi_value global = nullptr;
418 napi_get_global(env, &global);
419 napi_get_named_property(env, global, "callingPid_", &oldCallingInfo.callingPid);
420 napi_get_named_property(env, global, "callingUid_", &oldCallingInfo.callingUid);
421 napi_get_named_property(env, global, "callingTokenId_", &oldCallingInfo.callingTokenId);
422 napi_get_named_property(env, global, "callingDeviceID_", &oldCallingInfo.callingDeviceID);
423 napi_get_named_property(env, global, "localDeviceID_", &oldCallingInfo.localDeviceID);
424 napi_get_named_property(env, global, "isLocalCalling_", &oldCallingInfo.isLocalCalling);
425 napi_get_named_property(env, global, "isLocalCalling_", &oldCallingInfo.isLocalCalling);
426 napi_get_named_property(env, global, "activeStatus_", &oldCallingInfo.activeStatus);
427 }
428
NAPI_RemoteObject_setNewCallingInfo(napi_env env,const CallingInfo & newCallingInfoParam)429 void NAPI_RemoteObject_setNewCallingInfo(napi_env env, const CallingInfo &newCallingInfoParam)
430 {
431 napi_value global = nullptr;
432 napi_get_global(env, &global);
433 napi_value newPid;
434 napi_create_int32(env, static_cast<int32_t>(newCallingInfoParam.callingPid), &newPid);
435 napi_set_named_property(env, global, "callingPid_", newPid);
436 napi_value newUid;
437 napi_create_int32(env, static_cast<int32_t>(newCallingInfoParam.callingUid), &newUid);
438 napi_set_named_property(env, global, "callingUid_", newUid);
439 napi_value newCallingTokenId;
440 napi_create_uint32(env, newCallingInfoParam.callingTokenId, &newCallingTokenId);
441 napi_set_named_property(env, global, "callingTokenId_", newCallingTokenId);
442 napi_value newDeviceID;
443 napi_create_string_utf8(env, newCallingInfoParam.callingDeviceID.c_str(), NAPI_AUTO_LENGTH, &newDeviceID);
444 napi_set_named_property(env, global, "callingDeviceID_", newDeviceID);
445 napi_value newLocalDeviceID;
446 napi_create_string_utf8(env, newCallingInfoParam.localDeviceID.c_str(), NAPI_AUTO_LENGTH, &newLocalDeviceID);
447 napi_set_named_property(env, global, "localDeviceID_", newLocalDeviceID);
448 napi_value newIsLocalCalling;
449 napi_get_boolean(env, newCallingInfoParam.isLocalCalling, &newIsLocalCalling);
450 napi_set_named_property(env, global, "isLocalCalling_", newIsLocalCalling);
451 napi_value newActiveStatus;
452 napi_create_int32(env, newCallingInfoParam.activeStatus, &newActiveStatus);
453 napi_set_named_property(env, global, "activeStatus_", newActiveStatus);
454 }
455
NAPI_RemoteObject_resetOldCallingInfo(napi_env env,NAPI_CallingInfo & oldCallingInfo)456 void NAPI_RemoteObject_resetOldCallingInfo(napi_env env, NAPI_CallingInfo &oldCallingInfo)
457 {
458 napi_value global = nullptr;
459 napi_get_global(env, &global);
460 napi_set_named_property(env, global, "callingPid_", oldCallingInfo.callingPid);
461 napi_set_named_property(env, global, "callingUid_", oldCallingInfo.callingUid);
462 napi_set_named_property(env, global, "callingTokenId_", oldCallingInfo.callingTokenId);
463 napi_set_named_property(env, global, "callingDeviceID_", oldCallingInfo.callingDeviceID);
464 napi_set_named_property(env, global, "localDeviceID_", oldCallingInfo.localDeviceID);
465 napi_set_named_property(env, global, "isLocalCalling_", oldCallingInfo.isLocalCalling);
466 napi_set_named_property(env, global, "activeStatus_", oldCallingInfo.activeStatus);
467 }
468
OnJsRemoteRequest(CallbackParam * jsParam)469 int NAPIRemoteObject::OnJsRemoteRequest(CallbackParam *jsParam)
470 {
471 if (jsParam == nullptr) {
472 ZLOGE(LOG_LABEL, "Js Param is null");
473 return ERR_UNKNOWN_REASON;
474 }
475 if (thisVarRef_ == nullptr || env_ == nullptr) {
476 ZLOGE(LOG_LABEL, "Js env has been destructed");
477 return ERR_UNKNOWN_REASON;
478 }
479 uv_loop_s *loop = nullptr;
480 napi_get_uv_event_loop(env_, &loop);
481
482 uv_work_t *work = new(std::nothrow) uv_work_t;
483 if (work == nullptr) {
484 ZLOGE(LOG_LABEL, "failed to new uv_work_t");
485 delete jsParam;
486 return -1;
487 }
488 work->data = reinterpret_cast<void *>(jsParam);
489
490 uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(
491 std::chrono::steady_clock::now().time_since_epoch()).count());
492 ZLOGD(LOG_LABEL, "start nv queue work loop. desc:%{public}s time:%{public}" PRIu64,
493 Str16ToStr8(descriptor_).c_str(), curTime);
494 int uvRet = uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {
495 uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(
496 std::chrono::steady_clock::now().time_since_epoch()).count());
497 ZLOGI(LOG_LABEL, "enter work pool. code:%{public}u time:%{public}" PRIu64,
498 (reinterpret_cast<CallbackParam *>(work->data))->code, curTime);
499 }, [](uv_work_t *work, int status) {
500 uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(
501 std::chrono::steady_clock::now().time_since_epoch()).count());
502 ZLOGI(LOG_LABEL, "enter thread pool time:%{public}" PRIu64, curTime);
503 CallbackParam *param = reinterpret_cast<CallbackParam *>(work->data);
504 napi_handle_scope scope = nullptr;
505 napi_open_handle_scope(param->env, &scope);
506 napi_value onRemoteRequest = nullptr;
507 napi_value thisVar = nullptr;
508 napi_get_reference_value(param->env, param->thisVarRef, &thisVar);
509 if (thisVar == nullptr) {
510 ZLOGE(LOG_LABEL, "thisVar is null");
511 param->result = -1;
512 std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
513 param->lockInfo->ready = true;
514 param->lockInfo->condition.notify_all();
515 napi_close_handle_scope(param->env, scope);
516 return;
517 }
518 napi_get_named_property(param->env, thisVar, "onRemoteMessageRequest", &onRemoteRequest);
519 if (onRemoteRequest == nullptr) {
520 ZLOGE(LOG_LABEL, "get founction onRemoteRequest failed");
521 param->result = -1;
522 std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
523 param->lockInfo->ready = true;
524 param->lockInfo->condition.notify_all();
525 napi_close_handle_scope(param->env, scope);
526 return;
527 }
528 napi_valuetype type = napi_undefined;
529 napi_typeof(param->env, onRemoteRequest, &type);
530 bool isOnRemoteMessageRequest = true;
531 if (type != napi_function) {
532 napi_get_named_property(param->env, thisVar, "onRemoteRequest", &onRemoteRequest);
533 if (onRemoteRequest == nullptr) {
534 ZLOGE(LOG_LABEL, "get founction onRemoteRequest failed");
535 param->result = -1;
536 std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
537 param->lockInfo->ready = true;
538 param->lockInfo->condition.notify_all();
539 napi_close_handle_scope(param->env, scope);
540 return;
541 }
542 isOnRemoteMessageRequest = false;
543 }
544 napi_value jsCode;
545 napi_create_uint32(param->env, param->code, &jsCode);
546
547 napi_value global = nullptr;
548 napi_get_global(param->env, &global);
549 if (global == nullptr) {
550 ZLOGE(LOG_LABEL, "get napi global failed");
551 param->result = -1;
552 std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
553 param->lockInfo->ready = true;
554 param->lockInfo->condition.notify_all();
555 napi_close_handle_scope(param->env, scope);
556 return;
557 }
558 napi_value jsOptionConstructor = nullptr;
559 napi_get_named_property(param->env, global, "IPCOptionConstructor_", &jsOptionConstructor);
560 if (jsOptionConstructor == nullptr) {
561 ZLOGE(LOG_LABEL, "jsOption constructor is null");
562 param->result = -1;
563 std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
564 param->lockInfo->ready = true;
565 param->lockInfo->condition.notify_all();
566 napi_close_handle_scope(param->env, scope);
567 return;
568 }
569 napi_value jsOption;
570 size_t argc = 2;
571 napi_value flags = nullptr;
572 napi_create_int32(param->env, param->option->GetFlags(), &flags);
573 napi_value waittime = nullptr;
574 napi_create_int32(param->env, param->option->GetWaitTime(), &waittime);
575 napi_value argv[ARGV_LENGTH_2] = { flags, waittime };
576 napi_new_instance(param->env, jsOptionConstructor, argc, argv, &jsOption);
577 if (jsOption == nullptr) {
578 ZLOGE(LOG_LABEL, "new jsOption failed");
579 param->result = -1;
580 std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
581 param->lockInfo->ready = true;
582 param->lockInfo->condition.notify_all();
583 napi_close_handle_scope(param->env, scope);
584 return;
585 }
586 napi_value jsParcelConstructor = nullptr;
587 if (isOnRemoteMessageRequest) {
588 napi_get_named_property(param->env, global, "IPCSequenceConstructor_", &jsParcelConstructor);
589 } else {
590 napi_get_named_property(param->env, global, "IPCParcelConstructor_", &jsParcelConstructor);
591 }
592 if (jsParcelConstructor == nullptr) {
593 ZLOGE(LOG_LABEL, "jsParcel constructor is null");
594 param->result = -1;
595 std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
596 param->lockInfo->ready = true;
597 param->lockInfo->condition.notify_all();
598 napi_close_handle_scope(param->env, scope);
599 return;
600 }
601 napi_value jsData;
602 napi_value dataParcel;
603 napi_create_object(param->env, &dataParcel);
604 napi_wrap(param->env, dataParcel, param->data,
605 [](napi_env env, void *data, void *hint) {}, nullptr, nullptr);
606 if (dataParcel == nullptr) {
607 ZLOGE(LOG_LABEL, "create js object for data parcel address failed");
608 param->result = -1;
609 std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
610 param->lockInfo->ready = true;
611 param->lockInfo->condition.notify_all();
612 napi_close_handle_scope(param->env, scope);
613 return;
614 }
615 size_t argc3 = 1;
616 napi_value argv3[1] = { dataParcel };
617 napi_new_instance(param->env, jsParcelConstructor, argc3, argv3, &jsData);
618 if (jsData == nullptr) {
619 ZLOGE(LOG_LABEL, "create js data parcel failed");
620 param->result = -1;
621 std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
622 param->lockInfo->ready = true;
623 param->lockInfo->condition.notify_all();
624 napi_close_handle_scope(param->env, scope);
625 return;
626 }
627 napi_value jsReply;
628 napi_value replyParcel;
629 napi_create_object(param->env, &replyParcel);
630 napi_wrap(param->env, replyParcel, param->reply,
631 [](napi_env env, void *data, void *hint) {}, nullptr, nullptr);
632 if (replyParcel == nullptr) {
633 ZLOGE(LOG_LABEL, "create js object for reply parcel address failed");
634 param->result = -1;
635 std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
636 param->lockInfo->ready = true;
637 param->lockInfo->condition.notify_all();
638 napi_close_handle_scope(param->env, scope);
639 return;
640 }
641 size_t argc4 = 1;
642 napi_value argv4[1] = { replyParcel };
643 napi_new_instance(param->env, jsParcelConstructor, argc4, argv4, &jsReply);
644 if (jsReply == nullptr) {
645 ZLOGE(LOG_LABEL, "create js reply parcel failed");
646 param->result = -1;
647 std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
648 param->lockInfo->ready = true;
649 param->lockInfo->condition.notify_all();
650 napi_close_handle_scope(param->env, scope);
651 return;
652 }
653 NAPI_CallingInfo oldCallingInfo;
654 NAPI_RemoteObject_saveOldCallingInfo(param->env, oldCallingInfo);
655 NAPI_RemoteObject_setNewCallingInfo(param->env, param->callingInfo);
656 // start to call onRemoteRequest
657 size_t argc2 = 4;
658 napi_value argv2[] = { jsCode, jsData, jsReply, jsOption };
659 napi_value returnVal;
660 napi_status ret = napi_call_function(param->env, thisVar, onRemoteRequest, argc2, argv2, &returnVal);
661 // Reset old calling pid, uid, device id
662 NAPI_RemoteObject_resetOldCallingInfo(param->env, oldCallingInfo);
663
664 do {
665 if (ret != napi_ok) {
666 ZLOGE(LOG_LABEL, "OnRemoteRequest got exception");
667 param->result = ERR_UNKNOWN_TRANSACTION;
668 break;
669 }
670
671 ZLOGD(LOG_LABEL, "call js onRemoteRequest done");
672 // Check whether return_val is Promise
673 bool returnIsPromise = false;
674 napi_is_promise(param->env, returnVal, &returnIsPromise);
675 if (!returnIsPromise) {
676 ZLOGD(LOG_LABEL, "onRemoteRequest is synchronous");
677 bool result = false;
678 napi_get_value_bool(param->env, returnVal, &result);
679 if (!result) {
680 uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(
681 std::chrono::steady_clock::now().time_since_epoch()).count());
682 ZLOGE(LOG_LABEL, "OnRemoteRequest res:%{public}s time:%{public}" PRIu64,
683 result ? "true" : "false", curTime);
684 param->result = ERR_UNKNOWN_TRANSACTION;
685 } else {
686 param->result = ERR_NONE;
687 }
688 break;
689 }
690
691 ZLOGD(LOG_LABEL, "onRemoteRequest is asynchronous");
692 // Create promiseThen
693 napi_value promiseThen = nullptr;
694 napi_get_named_property(param->env, returnVal, "then", &promiseThen);
695 if (promiseThen == nullptr) {
696 ZLOGE(LOG_LABEL, "get promiseThen failed");
697 param->result = -1;
698 break;
699 }
700 napi_value thenValue;
701 ret = napi_create_function(param->env, "thenCallback", NAPI_AUTO_LENGTH, ThenCallback, param, &thenValue);
702 if (ret != napi_ok) {
703 ZLOGE(LOG_LABEL, "thenCallback got exception");
704 param->result = ERR_UNKNOWN_TRANSACTION;
705 break;
706 }
707 napi_value catchValue;
708 ret = napi_create_function(param->env, "catchCallback",
709 NAPI_AUTO_LENGTH, CatchCallback, param, &catchValue);
710 if (ret != napi_ok) {
711 ZLOGE(LOG_LABEL, "catchCallback got exception");
712 param->result = ERR_UNKNOWN_TRANSACTION;
713 break;
714 }
715 // Start to call promiseThen
716 napi_env env = param->env;
717 napi_value thenReturnValue;
718 constexpr uint32_t THEN_ARGC = 2;
719 napi_value thenArgv[THEN_ARGC] = {thenValue, catchValue};
720 ret = napi_call_function(env, returnVal, promiseThen, THEN_ARGC, thenArgv, &thenReturnValue);
721 if (ret != napi_ok) {
722 ZLOGE(LOG_LABEL, "PromiseThen got exception");
723 param->result = ERR_UNKNOWN_TRANSACTION;
724 break;
725 }
726 napi_close_handle_scope(env, scope);
727 return;
728 } while (0);
729
730 std::unique_lock<std::mutex> lock(param->lockInfo->mutex);
731 param->lockInfo->ready = true;
732 param->lockInfo->condition.notify_all();
733 napi_close_handle_scope(param->env, scope);
734 }, uv_qos_user_initiated);
735 int ret = 0;
736 if (uvRet != 0) {
737 ZLOGE(LOG_LABEL, "uv_queue_work_with_qos failed, ret:%{public}d", uvRet);
738 ret = -1;
739 } else {
740 std::unique_lock<std::mutex> lock(jsParam->lockInfo->mutex);
741 jsParam->lockInfo->condition.wait(lock, [&jsParam] { return jsParam->lockInfo->ready; });
742 ret = jsParam->result;
743 }
744 delete jsParam;
745 delete work;
746 return ret;
747 }
748
NAPI_ohos_rpc_CreateJsRemoteObject(napi_env env,const sptr<IRemoteObject> target)749 napi_value NAPI_ohos_rpc_CreateJsRemoteObject(napi_env env, const sptr<IRemoteObject> target)
750 {
751 if (target == nullptr) {
752 uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(
753 std::chrono::steady_clock::now().time_since_epoch()).count());
754 ZLOGE(LOG_LABEL, "RemoteObject is null time:%{public}" PRIu64, curTime);
755 return nullptr;
756 }
757
758 if (!target->IsProxyObject()) {
759 IPCObjectStub *tmp = static_cast<IPCObjectStub *>(target.GetRefPtr());
760 uint32_t objectType = static_cast<uint32_t>(tmp->GetObjectType());
761 ZLOGD(LOG_LABEL, "create js object, type:%{public}d", objectType);
762 if (objectType == IPCObjectStub::OBJECT_TYPE_JAVASCRIPT || objectType == IPCObjectStub::OBJECT_TYPE_NATIVE) {
763 // retrieve js remote object constructor
764 napi_value global = nullptr;
765 napi_status status = napi_get_global(env, &global);
766 NAPI_ASSERT(env, status == napi_ok, "get napi global failed");
767 napi_value constructor = nullptr;
768 status = napi_get_named_property(env, global, "IPCStubConstructor_", &constructor);
769 NAPI_ASSERT(env, status == napi_ok, "set stub constructor failed");
770 NAPI_ASSERT(env, constructor != nullptr, "failed to get js RemoteObject constructor");
771 // retrieve descriptor and it's length
772 std::u16string descriptor = target->GetObjectDescriptor();
773 std::string desc = Str16ToStr8(descriptor);
774 napi_value jsDesc = nullptr;
775 napi_create_string_utf8(env, desc.c_str(), desc.length(), &jsDesc);
776 // create a new js remote object
777 size_t argc = 1;
778 napi_value argv[ARGV_LENGTH_1] = { jsDesc };
779 napi_value jsRemoteObject = nullptr;
780 status = napi_new_instance(env, constructor, argc, argv, &jsRemoteObject);
781 NAPI_ASSERT(env, status == napi_ok, "failed to construct js RemoteObject");
782 // retrieve holder and set object
783 NAPIRemoteObjectHolder *holder = nullptr;
784 napi_unwrap(env, jsRemoteObject, (void **)&holder);
785 NAPI_ASSERT(env, holder != nullptr, "failed to get napi remote object holder");
786 holder->Set(target);
787 return jsRemoteObject;
788 }
789 }
790
791 napi_value global = nullptr;
792 napi_status status = napi_get_global(env, &global);
793 NAPI_ASSERT(env, status == napi_ok, "get napi global failed");
794 napi_value constructor = nullptr;
795 status = napi_get_named_property(env, global, "IPCProxyConstructor_", &constructor);
796 NAPI_ASSERT(env, status == napi_ok, "get proxy constructor failed");
797 napi_value jsRemoteProxy;
798 status = napi_new_instance(env, constructor, 0, nullptr, &jsRemoteProxy);
799 NAPI_ASSERT(env, status == napi_ok, "failed to construct js RemoteProxy");
800 NAPIRemoteProxyHolder *proxyHolder = NAPI_ohos_rpc_getRemoteProxyHolder(env, jsRemoteProxy);
801 if (proxyHolder == nullptr) {
802 ZLOGE(LOG_LABEL, "proxyHolder null");
803 return nullptr;
804 }
805 proxyHolder->object_ = target;
806 proxyHolder->list_ = new NAPIDeathRecipientList();
807
808 return jsRemoteProxy;
809 }
810
NAPI_ohos_rpc_ClearNativeRemoteProxy(napi_env env,napi_value jsRemoteProxy)811 bool NAPI_ohos_rpc_ClearNativeRemoteProxy(napi_env env, napi_value jsRemoteProxy)
812 {
813 NAPIRemoteProxyHolder *holder = NAPI_ohos_rpc_getRemoteProxyHolder(env, jsRemoteProxy);
814 if (holder == nullptr) {
815 ZLOGE(LOG_LABEL, "holder null");
816 return false;
817 }
818 ZLOGI(LOG_LABEL, "clear native remote proxy");
819 holder->object_ = nullptr;
820 return true;
821 }
822
NAPI_ohos_rpc_getNativeRemoteObject(napi_env env,napi_value object)823 sptr<IRemoteObject> NAPI_ohos_rpc_getNativeRemoteObject(napi_env env, napi_value object)
824 {
825 if (object != nullptr) {
826 napi_value global = nullptr;
827 napi_status status = napi_get_global(env, &global);
828 NAPI_ASSERT(env, status == napi_ok, "get napi global failed");
829 napi_value stubConstructor = nullptr;
830 status = napi_get_named_property(env, global, "IPCStubConstructor_", &stubConstructor);
831 NAPI_ASSERT(env, status == napi_ok, "get stub constructor failed");
832 bool instanceOfStub = false;
833 status = napi_instanceof(env, object, stubConstructor, &instanceOfStub);
834 NAPI_ASSERT(env, status == napi_ok, "failed to check js object type");
835 if (instanceOfStub) {
836 NAPIRemoteObjectHolder *holder = nullptr;
837 napi_unwrap(env, object, (void **)&holder);
838 NAPI_ASSERT(env, holder != nullptr, "failed to get napi remote object holder");
839 return holder != nullptr ? holder->Get() : nullptr;
840 }
841
842 napi_value proxyConstructor = nullptr;
843 status = napi_get_named_property(env, global, "IPCProxyConstructor_", &proxyConstructor);
844 NAPI_ASSERT(env, status == napi_ok, "get proxy constructor failed");
845 bool instanceOfProxy = false;
846 status = napi_instanceof(env, object, proxyConstructor, &instanceOfProxy);
847 NAPI_ASSERT(env, status == napi_ok, "failed to check js object type");
848 if (instanceOfProxy) {
849 NAPIRemoteProxyHolder *holder = NAPI_ohos_rpc_getRemoteProxyHolder(env, object);
850 return holder != nullptr ? holder->object_ : nullptr;
851 }
852 }
853 return nullptr;
854 }
855
NAPI_RemoteObject_queryLocalInterface(napi_env env,napi_callback_info info)856 static napi_value NAPI_RemoteObject_queryLocalInterface(napi_env env, napi_callback_info info)
857 {
858 size_t argc = 1;
859 size_t expectedArgc = 1;
860 napi_value argv[ARGV_LENGTH_1] = {nullptr};
861 napi_value thisVar = nullptr;
862 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
863 NAPI_ASSERT(env, argc == expectedArgc, "requires 1 parameters");
864 napi_valuetype valueType = napi_null;
865 napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
866 NAPI_ASSERT(env, valueType == napi_string, "type mismatch for parameter 1");
867 size_t bufferSize = 0;
868 size_t maxLen = 40960;
869 napi_get_value_string_utf8(env, argv[ARGV_INDEX_0], nullptr, 0, &bufferSize);
870 NAPI_ASSERT(env, bufferSize < maxLen, "string length too large");
871 char stringValue[bufferSize + 1];
872 size_t jsStringLength = 0;
873 napi_get_value_string_utf8(env, argv[ARGV_INDEX_0], stringValue, bufferSize + 1, &jsStringLength);
874 NAPI_ASSERT(env, jsStringLength == bufferSize, "string length wrong");
875 std::string descriptor = stringValue;
876 NAPIRemoteObjectHolder *holder = nullptr;
877 napi_unwrap(env, thisVar, (void **)&holder);
878 NAPI_ASSERT(env, holder != nullptr, "failed to get napi remote object holder");
879 napi_value ret = holder->queryLocalInterface(descriptor);
880 return ret;
881 }
882
NAPI_RemoteObject_getLocalInterface(napi_env env,napi_callback_info info)883 static napi_value NAPI_RemoteObject_getLocalInterface(napi_env env, napi_callback_info info)
884 {
885 size_t argc = 1;
886 size_t expectedArgc = 1;
887 napi_value argv[ARGV_LENGTH_1] = {nullptr};
888 napi_value thisVar = nullptr;
889 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
890 if (argc != expectedArgc) {
891 ZLOGE(LOG_LABEL, "requires 1 parameters");
892 return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
893 }
894 napi_valuetype valueType = napi_null;
895 napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
896 if (valueType != napi_string) {
897 ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
898 return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
899 }
900 size_t bufferSize = 0;
901 size_t maxLen = 40960;
902 napi_get_value_string_utf8(env, argv[ARGV_INDEX_0], nullptr, 0, &bufferSize);
903 if (bufferSize >= maxLen) {
904 ZLOGE(LOG_LABEL, "string length too large");
905 return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
906 }
907 char stringValue[bufferSize + 1];
908 size_t jsStringLength = 0;
909 napi_get_value_string_utf8(env, argv[ARGV_INDEX_0], stringValue, bufferSize + 1, &jsStringLength);
910 if (jsStringLength != bufferSize) {
911 ZLOGE(LOG_LABEL, "string length wrong");
912 return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
913 }
914 std::string descriptor = stringValue;
915 NAPIRemoteObjectHolder *holder = nullptr;
916 napi_unwrap(env, thisVar, (void **)&holder);
917 if (holder == nullptr) {
918 ZLOGE(LOG_LABEL, "failed to get napi remote object holder");
919 return nullptr;
920 }
921 napi_value ret = holder->queryLocalInterface(descriptor);
922 return ret;
923 }
924
NAPI_RemoteObject_getInterfaceDescriptor(napi_env env,napi_callback_info info)925 static napi_value NAPI_RemoteObject_getInterfaceDescriptor(napi_env env, napi_callback_info info)
926 {
927 napi_value result = nullptr;
928 napi_value thisVar = nullptr;
929 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
930 sptr<IRemoteObject> nativeObject = NAPI_ohos_rpc_getNativeRemoteObject(env, thisVar);
931 std::u16string descriptor = nativeObject->GetObjectDescriptor();
932 napi_create_string_utf8(env, Str16ToStr8(descriptor).c_str(), NAPI_AUTO_LENGTH, &result);
933 return result;
934 }
935
NAPI_RemoteObject_getDescriptor(napi_env env,napi_callback_info info)936 static napi_value NAPI_RemoteObject_getDescriptor(napi_env env, napi_callback_info info)
937 {
938 napi_value result = nullptr;
939 napi_value thisVar = nullptr;
940 napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
941 sptr<IRemoteObject> nativeObject = NAPI_ohos_rpc_getNativeRemoteObject(env, thisVar);
942 if (nativeObject == nullptr) {
943 ZLOGE(LOG_LABEL, "native stub object is nullptr");
944 return napiErr.ThrowError(env, errorDesc::PROXY_OR_REMOTE_OBJECT_INVALID_ERROR);
945 }
946 std::u16string descriptor = nativeObject->GetObjectDescriptor();
947 napi_create_string_utf8(env, Str16ToStr8(descriptor).c_str(), NAPI_AUTO_LENGTH, &result);
948 return result;
949 }
950
NAPI_RemoteObject_getCallingPid(napi_env env,napi_callback_info info)951 static napi_value NAPI_RemoteObject_getCallingPid(napi_env env, napi_callback_info info)
952 {
953 return NAPI_getCallingPid(env, info);
954 }
955
NAPI_RemoteObject_getCallingUid(napi_env env,napi_callback_info info)956 static napi_value NAPI_RemoteObject_getCallingUid(napi_env env, napi_callback_info info)
957 {
958 return NAPI_getCallingUid(env, info);
959 }
960
MakeSendRequestResult(SendRequestParam * param)961 napi_value MakeSendRequestResult(SendRequestParam *param)
962 {
963 if (param == nullptr) {
964 ZLOGE(LOG_LABEL, "send request param is null");
965 return nullptr;
966 }
967 napi_value errCode = nullptr;
968 napi_create_int32(param->env, param->errCode, &errCode);
969 napi_value code = nullptr;
970 napi_get_reference_value(param->env, param->jsCodeRef, &code);
971 napi_value data = nullptr;
972 napi_get_reference_value(param->env, param->jsDataRef, &data);
973 napi_value reply = nullptr;
974 napi_get_reference_value(param->env, param->jsReplyRef, &reply);
975 napi_value result = nullptr;
976 napi_create_object(param->env, &result);
977 napi_set_named_property(param->env, result, "errCode", errCode);
978 napi_set_named_property(param->env, result, "code", code);
979 napi_set_named_property(param->env, result, "data", data);
980 napi_set_named_property(param->env, result, "reply", reply);
981 return result;
982 }
983
StubExecuteSendRequest(napi_env env,SendRequestParam * param)984 void StubExecuteSendRequest(napi_env env, SendRequestParam *param)
985 {
986 if (param == nullptr) {
987 ZLOGE(LOG_LABEL, "param is null");
988 return;
989 }
990 param->errCode = param->target->SendRequest(param->code,
991 *(param->data.get()), *(param->reply.get()), param->option);
992 uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(
993 std::chrono::steady_clock::now().time_since_epoch()).count());
994 ZLOGI(LOG_LABEL, "sendRequest done, errCode:%{public}d time:%{public}" PRIu64, param->errCode, curTime);
995 if (param->traceId != 0) {
996 FinishAsyncTrace(HITRACE_TAG_RPC, (param->traceValue).c_str(), param->traceId);
997 }
998 uv_loop_s *loop = nullptr;
999 napi_get_uv_event_loop(env, &loop);
1000 uv_work_t *work = new uv_work_t;
1001 work->data = reinterpret_cast<void *>(param);
1002 uv_after_work_cb afterWorkCb = nullptr;
1003 if (param->callback != nullptr) {
1004 afterWorkCb = [](uv_work_t *work, int status) {
1005 ZLOGI(LOG_LABEL, "callback started");
1006 SendRequestParam *param = reinterpret_cast<SendRequestParam *>(work->data);
1007 napi_handle_scope scope = nullptr;
1008 napi_open_handle_scope(param->env, &scope);
1009 napi_value result = MakeSendRequestResult(param);
1010 napi_value callback = nullptr;
1011 napi_get_reference_value(param->env, param->callback, &callback);
1012 napi_value cbResult = nullptr;
1013 napi_call_function(param->env, nullptr, callback, 1, &result, &cbResult);
1014 napi_delete_reference(param->env, param->jsCodeRef);
1015 napi_delete_reference(param->env, param->jsDataRef);
1016 napi_delete_reference(param->env, param->jsReplyRef);
1017 napi_delete_reference(param->env, param->jsOptionRef);
1018 napi_delete_reference(param->env, param->callback);
1019 napi_close_handle_scope(param->env, scope);
1020 delete param;
1021 delete work;
1022 };
1023 } else {
1024 afterWorkCb = [](uv_work_t *work, int status) {
1025 uint64_t curTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::nanoseconds>(
1026 std::chrono::steady_clock::now().time_since_epoch()).count());
1027 ZLOGI(LOG_LABEL, "promise fullfilled time:%{public}" PRIu64, curTime);
1028 SendRequestParam *param = reinterpret_cast<SendRequestParam *>(work->data);
1029 napi_handle_scope scope = nullptr;
1030 napi_open_handle_scope(param->env, &scope);
1031 napi_value result = MakeSendRequestResult(param);
1032 if (param->errCode == 0) {
1033 napi_resolve_deferred(param->env, param->deferred, result);
1034 } else {
1035 napi_reject_deferred(param->env, param->deferred, result);
1036 }
1037 napi_delete_reference(param->env, param->jsCodeRef);
1038 napi_delete_reference(param->env, param->jsDataRef);
1039 napi_delete_reference(param->env, param->jsReplyRef);
1040 napi_delete_reference(param->env, param->jsOptionRef);
1041 napi_close_handle_scope(param->env, scope);
1042 delete param;
1043 delete work;
1044 };
1045 }
1046 int uvRet = uv_queue_work(loop, work, [](uv_work_t *work) {
1047 ZLOGD(LOG_LABEL, "enter work pool.");
1048 }, afterWorkCb);
1049 if (uvRet != 0) {
1050 ZLOGE(LOG_LABEL, "uv_queue_work failed, ret %{public}d", uvRet);
1051 }
1052 }
1053
StubSendRequestAsync(napi_env env,sptr<IRemoteObject> target,uint32_t code,std::shared_ptr<MessageParcel> data,std::shared_ptr<MessageParcel> reply,MessageOption & option,napi_value * argv)1054 napi_value StubSendRequestAsync(napi_env env, sptr<IRemoteObject> target, uint32_t code,
1055 std::shared_ptr<MessageParcel> data, std::shared_ptr<MessageParcel> reply,
1056 MessageOption &option, napi_value *argv)
1057 {
1058 SendRequestParam *sendRequestParam = new SendRequestParam {
1059 .target = target,
1060 .code = code,
1061 .data = data,
1062 .reply = reply,
1063 .option = option,
1064 .asyncWork = nullptr,
1065 .deferred = nullptr,
1066 .errCode = -1,
1067 .jsCodeRef = nullptr,
1068 .jsDataRef = nullptr,
1069 .jsReplyRef = nullptr,
1070 .jsOptionRef = nullptr,
1071 .callback = nullptr,
1072 .env = env,
1073 .traceId = 0,
1074 };
1075 if (target != nullptr) {
1076 std::string remoteDescriptor = Str16ToStr8(target->GetObjectDescriptor());
1077 if (!remoteDescriptor.empty()) {
1078 sendRequestParam->traceValue = remoteDescriptor + std::to_string(code);
1079 sendRequestParam->traceId = bytraceId.fetch_add(1, std::memory_order_seq_cst);
1080 StartAsyncTrace(HITRACE_TAG_RPC, (sendRequestParam->traceValue).c_str(), sendRequestParam->traceId);
1081 }
1082 }
1083 napi_create_reference(env, argv[ARGV_INDEX_0], 1, &sendRequestParam->jsCodeRef);
1084 napi_create_reference(env, argv[ARGV_INDEX_1], 1, &sendRequestParam->jsDataRef);
1085 napi_create_reference(env, argv[ARGV_INDEX_2], 1, &sendRequestParam->jsReplyRef);
1086 napi_create_reference(env, argv[ARGV_INDEX_3], 1, &sendRequestParam->jsOptionRef);
1087 napi_create_reference(env, argv[ARGV_INDEX_4], 1, &sendRequestParam->callback);
1088 std::thread t(StubExecuteSendRequest, env, sendRequestParam);
1089 t.detach();
1090 napi_value result = nullptr;
1091 napi_get_undefined(env, &result);
1092 return result;
1093 }
1094
StubSendRequestPromise(napi_env env,sptr<IRemoteObject> target,uint32_t code,std::shared_ptr<MessageParcel> data,std::shared_ptr<MessageParcel> reply,MessageOption & option,napi_value * argv)1095 napi_value StubSendRequestPromise(napi_env env, sptr<IRemoteObject> target, uint32_t code,
1096 std::shared_ptr<MessageParcel> data, std::shared_ptr<MessageParcel> reply,
1097 MessageOption &option, napi_value *argv)
1098 {
1099 napi_deferred deferred = nullptr;
1100 napi_value promise = nullptr;
1101 NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
1102 SendRequestParam *sendRequestParam = new SendRequestParam {
1103 .target = target,
1104 .code = code,
1105 .data = data,
1106 .reply = reply,
1107 .option = option,
1108 .asyncWork = nullptr,
1109 .deferred = deferred,
1110 .errCode = -1,
1111 .jsCodeRef = nullptr,
1112 .jsDataRef = nullptr,
1113 .jsReplyRef = nullptr,
1114 .jsOptionRef = nullptr,
1115 .callback = nullptr,
1116 .env = env,
1117 .traceId = 0,
1118 };
1119 if (target != nullptr) {
1120 std::string remoteDescriptor = Str16ToStr8(target->GetObjectDescriptor());
1121 if (!remoteDescriptor.empty()) {
1122 sendRequestParam->traceValue = remoteDescriptor + std::to_string(code);
1123 sendRequestParam->traceId = bytraceId.fetch_add(1, std::memory_order_seq_cst);
1124 StartAsyncTrace(HITRACE_TAG_RPC, (sendRequestParam->traceValue).c_str(), sendRequestParam->traceId);
1125 }
1126 }
1127 napi_create_reference(env, argv[ARGV_INDEX_0], 1, &sendRequestParam->jsCodeRef);
1128 napi_create_reference(env, argv[ARGV_INDEX_1], 1, &sendRequestParam->jsDataRef);
1129 napi_create_reference(env, argv[ARGV_INDEX_2], 1, &sendRequestParam->jsReplyRef);
1130 napi_create_reference(env, argv[ARGV_INDEX_3], 1, &sendRequestParam->jsOptionRef);
1131 std::thread t(StubExecuteSendRequest, env, sendRequestParam);
1132 t.detach();
1133 return promise;
1134 }
1135
NAPI_RemoteObject_sendRequest(napi_env env,napi_callback_info info)1136 static napi_value NAPI_RemoteObject_sendRequest(napi_env env, napi_callback_info info)
1137 {
1138 size_t argc = 4;
1139 size_t argcCallback = 5;
1140 size_t argcPromise = 4;
1141 napi_value argv[ARGV_LENGTH_5] = { 0 };
1142 napi_value thisVar = nullptr;
1143 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1144 NAPI_ASSERT(env, argc == argcPromise || argc == argcCallback, "requires 4 or 5 parameters");
1145 napi_valuetype valueType = napi_null;
1146 napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1147 NAPI_ASSERT(env, valueType == napi_number, "type mismatch for parameter 1");
1148 napi_typeof(env, argv[ARGV_INDEX_1], &valueType);
1149 NAPI_ASSERT(env, valueType == napi_object, "type mismatch for parameter 2");
1150 napi_typeof(env, argv[ARGV_INDEX_2], &valueType);
1151 NAPI_ASSERT(env, valueType == napi_object, "type mismatch for parameter 3");
1152 napi_typeof(env, argv[ARGV_INDEX_3], &valueType);
1153 NAPI_ASSERT(env, valueType == napi_object, "type mismatch for parameter 4");
1154
1155 NAPI_MessageParcel *data = nullptr;
1156 napi_status status = napi_unwrap(env, argv[ARGV_INDEX_1], (void **)&data);
1157 NAPI_ASSERT(env, status == napi_ok, "failed to get data message parcel");
1158 NAPI_MessageParcel *reply = nullptr;
1159 status = napi_unwrap(env, argv[ARGV_INDEX_2], (void **)&reply);
1160 NAPI_ASSERT(env, status == napi_ok, "failed to get reply message parcel");
1161 MessageOption *option = nullptr;
1162 status = napi_unwrap(env, argv[ARGV_INDEX_3], (void **)&option);
1163 NAPI_ASSERT(env, status == napi_ok, "failed to get message option");
1164 int32_t code = 0;
1165 napi_get_value_int32(env, argv[ARGV_INDEX_0], &code);
1166
1167 sptr<IRemoteObject> target = NAPI_ohos_rpc_getNativeRemoteObject(env, thisVar);
1168 if (argc == argcCallback) {
1169 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1170 napi_valuetype valuetype = napi_undefined;
1171 napi_typeof(env, argv[argcPromise], &valuetype);
1172 if (valuetype == napi_function) {
1173 return StubSendRequestAsync(env, target, code, data->GetMessageParcel(),
1174 reply->GetMessageParcel(), *option, argv);
1175 }
1176 }
1177 return StubSendRequestPromise(env, target, code, data->GetMessageParcel(),
1178 reply->GetMessageParcel(), *option, argv);
1179 }
1180
NAPI_RemoteObject_checkSendMessageRequestArgs(napi_env env,size_t argc,size_t argcCallback,size_t argcPromise,napi_value * argv)1181 napi_value NAPI_RemoteObject_checkSendMessageRequestArgs(napi_env env,
1182 size_t argc,
1183 size_t argcCallback,
1184 size_t argcPromise,
1185 napi_value* argv)
1186 {
1187 if (argc != argcPromise && argc != argcCallback) {
1188 ZLOGE(LOG_LABEL, "requires 4 or 5 parameters");
1189 return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1190 }
1191 napi_valuetype valueType = napi_null;
1192 napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1193 if (valueType != napi_number) {
1194 ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1195 return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1196 }
1197 napi_typeof(env, argv[ARGV_INDEX_1], &valueType);
1198 if (valueType != napi_object) {
1199 ZLOGE(LOG_LABEL, "type mismatch for parameter 2");
1200 return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1201 }
1202 napi_typeof(env, argv[ARGV_INDEX_2], &valueType);
1203 if (valueType != napi_object) {
1204 ZLOGE(LOG_LABEL, "type mismatch for parameter 3");
1205 return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1206 }
1207 napi_typeof(env, argv[ARGV_INDEX_3], &valueType);
1208 if (valueType != napi_object) {
1209 ZLOGE(LOG_LABEL, "type mismatch for parameter 4");
1210 return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1211 }
1212 napi_value result = nullptr;
1213 napi_get_undefined(env, &result);
1214 return result;
1215 }
1216
NAPI_RemoteObject_sendMessageRequest(napi_env env,napi_callback_info info)1217 static napi_value NAPI_RemoteObject_sendMessageRequest(napi_env env, napi_callback_info info)
1218 {
1219 size_t argc = 4;
1220 size_t argcCallback = 5;
1221 size_t argcPromise = 4;
1222 napi_value argv[ARGV_LENGTH_5] = { 0 };
1223 napi_value thisVar = nullptr;
1224 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1225 napi_value checkArgsResult = NAPI_RemoteObject_checkSendMessageRequestArgs(env, argc, argcCallback, argcPromise,
1226 argv);
1227 if (checkArgsResult == nullptr) {
1228 return checkArgsResult;
1229 }
1230 NAPI_MessageSequence *data = nullptr;
1231 napi_status status = napi_unwrap(env, argv[ARGV_INDEX_1], (void **)&data);
1232 if (status != napi_ok) {
1233 ZLOGE(LOG_LABEL, "failed to get data message sequence");
1234 return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1235 }
1236 NAPI_MessageSequence *reply = nullptr;
1237 status = napi_unwrap(env, argv[ARGV_INDEX_2], (void **)&reply);
1238 if (status != napi_ok) {
1239 ZLOGE(LOG_LABEL, "failed to get data message sequence");
1240 return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1241 }
1242 MessageOption *option = nullptr;
1243 status = napi_unwrap(env, argv[ARGV_INDEX_3], (void **)&option);
1244 if (status != napi_ok) {
1245 ZLOGE(LOG_LABEL, "failed to get message option");
1246 return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1247 }
1248 int32_t code = 0;
1249 napi_get_value_int32(env, argv[ARGV_INDEX_0], &code);
1250
1251 sptr<IRemoteObject> target = NAPI_ohos_rpc_getNativeRemoteObject(env, thisVar);
1252 if (argc == argcCallback) {
1253 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1254 napi_valuetype valuetype = napi_undefined;
1255 napi_typeof(env, argv[argcPromise], &valuetype);
1256 if (valuetype == napi_function) {
1257 return StubSendRequestAsync(env, target, code, data->GetMessageParcel(),
1258 reply->GetMessageParcel(), *option, argv);
1259 }
1260 }
1261 return StubSendRequestPromise(env, target, code, data->GetMessageParcel(),
1262 reply->GetMessageParcel(), *option, argv);
1263 }
1264
NAPI_RemoteObject_attachLocalInterface(napi_env env,napi_callback_info info)1265 static napi_value NAPI_RemoteObject_attachLocalInterface(napi_env env, napi_callback_info info)
1266 {
1267 size_t argc = 2;
1268 size_t expectedArgc = 2;
1269 napi_value argv[ARGV_LENGTH_2] = { 0 };
1270 napi_value thisVar = nullptr;
1271 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1272 NAPI_ASSERT(env, argc == expectedArgc, "requires 2 parameters");
1273 napi_valuetype valueType = napi_null;
1274 napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1275 NAPI_ASSERT(env, valueType == napi_object, "type mismatch for parameter 1");
1276 napi_typeof(env, argv[ARGV_INDEX_1], &valueType);
1277 NAPI_ASSERT(env, valueType == napi_string, "type mismatch for parameter 2");
1278 size_t bufferSize = 0;
1279 size_t maxLen = 40960;
1280 napi_get_value_string_utf8(env, argv[ARGV_INDEX_1], nullptr, 0, &bufferSize);
1281 NAPI_ASSERT(env, bufferSize < maxLen, "string length too large");
1282 char stringValue[bufferSize + 1];
1283 size_t jsStringLength = 0;
1284 napi_get_value_string_utf8(env, argv[ARGV_INDEX_1], stringValue, bufferSize + 1, &jsStringLength);
1285 NAPI_ASSERT(env, jsStringLength == bufferSize, "string length wrong");
1286 std::string descriptor = stringValue;
1287
1288 NAPIRemoteObjectHolder *holder = nullptr;
1289 napi_unwrap(env, thisVar, (void* *)&holder);
1290 NAPI_ASSERT(env, holder != nullptr, "failed to get napi remote object holder");
1291 holder->attachLocalInterface(argv[ARGV_INDEX_0], descriptor);
1292
1293 napi_value result = nullptr;
1294 napi_get_undefined(env, &result);
1295 return result;
1296 }
1297
NAPI_RemoteObject_checkModifyLocalInterfaceArgs(napi_env env,size_t argc,napi_value * argv)1298 napi_value NAPI_RemoteObject_checkModifyLocalInterfaceArgs(napi_env env, size_t argc, napi_value* argv)
1299 {
1300 size_t expectedArgc = 2;
1301
1302 if (argc != expectedArgc) {
1303 ZLOGE(LOG_LABEL, "requires 2 parameters");
1304 return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1305 }
1306 napi_valuetype valueType = napi_null;
1307 napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
1308 if (valueType != napi_object) {
1309 ZLOGE(LOG_LABEL, "type mismatch for parameter 1");
1310 return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1311 }
1312 napi_typeof(env, argv[ARGV_INDEX_1], &valueType);
1313 if (valueType != napi_string) {
1314 ZLOGE(LOG_LABEL, "type mismatch for parameter 2");
1315 return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1316 }
1317 napi_value result = nullptr;
1318 napi_get_undefined(env, &result);
1319 return result;
1320 }
1321
NAPI_RemoteObject_modifyLocalInterface(napi_env env,napi_callback_info info)1322 static napi_value NAPI_RemoteObject_modifyLocalInterface(napi_env env, napi_callback_info info)
1323 {
1324 size_t argc = 2;
1325 napi_value argv[ARGV_LENGTH_2] = { 0 };
1326 napi_value thisVar = nullptr;
1327 napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
1328 napi_value checkArgsResult = NAPI_RemoteObject_checkModifyLocalInterfaceArgs(env, argc, argv);
1329 if (checkArgsResult == nullptr) {
1330 return checkArgsResult;
1331 }
1332 size_t bufferSize = 0;
1333 size_t maxLen = 40960;
1334 napi_get_value_string_utf8(env, argv[ARGV_INDEX_1], nullptr, 0, &bufferSize);
1335 if (bufferSize >= maxLen) {
1336 ZLOGE(LOG_LABEL, "string length too large");
1337 return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1338 }
1339 char stringValue[bufferSize + 1];
1340 size_t jsStringLength = 0;
1341 napi_get_value_string_utf8(env, argv[ARGV_INDEX_1], stringValue, bufferSize + 1, &jsStringLength);
1342 if (jsStringLength != bufferSize) {
1343 ZLOGE(LOG_LABEL, "string length wrong");
1344 return napiErr.ThrowError(env, errorDesc::CHECK_PARAM_ERROR);
1345 }
1346 std::string descriptor = stringValue;
1347
1348 NAPIRemoteObjectHolder *holder = nullptr;
1349 napi_unwrap(env, thisVar, (void* *)&holder);
1350 if (holder == nullptr) {
1351 ZLOGE(LOG_LABEL, "failed to get napi remote object holder");
1352 return nullptr;
1353 }
1354 holder->attachLocalInterface(argv[ARGV_INDEX_0], descriptor);
1355
1356 napi_value result = nullptr;
1357 napi_get_undefined(env, &result);
1358 return result;
1359 }
1360
NAPI_RemoteObject_addDeathRecipient(napi_env env,napi_callback_info info)1361 static napi_value NAPI_RemoteObject_addDeathRecipient(napi_env env, napi_callback_info info)
1362 {
1363 napi_value result = nullptr;
1364 napi_get_boolean(env, false, &result);
1365 return result;
1366 }
1367
NAPI_RemoteObject_registerDeathRecipient(napi_env env,napi_callback_info info)1368 static napi_value NAPI_RemoteObject_registerDeathRecipient(napi_env env, napi_callback_info info)
1369 {
1370 ZLOGE(LOG_LABEL, "only proxy object permitted");
1371 return napiErr.ThrowError(env, errorDesc::ONLY_PROXY_OBJECT_PERMITTED_ERROR);
1372 }
1373
NAPI_RemoteObject_removeDeathRecipient(napi_env env,napi_callback_info info)1374 static napi_value NAPI_RemoteObject_removeDeathRecipient(napi_env env, napi_callback_info info)
1375 {
1376 napi_value result = nullptr;
1377 napi_get_boolean(env, false, &result);
1378 return result;
1379 }
1380
NAPI_RemoteObject_unregisterDeathRecipient(napi_env env,napi_callback_info info)1381 static napi_value NAPI_RemoteObject_unregisterDeathRecipient(napi_env env, napi_callback_info info)
1382 {
1383 ZLOGE(LOG_LABEL, "only proxy object permitted");
1384 return napiErr.ThrowError(env, errorDesc::ONLY_PROXY_OBJECT_PERMITTED_ERROR);
1385 }
1386
NAPI_RemoteObject_isObjectDead(napi_env env,napi_callback_info info)1387 static napi_value NAPI_RemoteObject_isObjectDead(napi_env env, napi_callback_info info)
1388 {
1389 napi_value result = nullptr;
1390 napi_get_boolean(env, false, &result);
1391 return result;
1392 }
1393
1394 EXTERN_C_START
1395 /*
1396 * function for module exports
1397 */
NAPIRemoteObjectExport(napi_env env,napi_value exports)1398 napi_value NAPIRemoteObjectExport(napi_env env, napi_value exports)
1399 {
1400 const std::string className = "RemoteObject";
1401 napi_property_descriptor properties[] = {
1402 DECLARE_NAPI_FUNCTION("sendRequest", NAPI_RemoteObject_sendRequest),
1403 DECLARE_NAPI_FUNCTION("sendMessageRequest", NAPI_RemoteObject_sendMessageRequest),
1404 DECLARE_NAPI_FUNCTION("getCallingPid", NAPI_RemoteObject_getCallingPid),
1405 DECLARE_NAPI_FUNCTION("getCallingUid", NAPI_RemoteObject_getCallingUid),
1406 DECLARE_NAPI_FUNCTION("getInterfaceDescriptor", NAPI_RemoteObject_getInterfaceDescriptor),
1407 DECLARE_NAPI_FUNCTION("getDescriptor", NAPI_RemoteObject_getDescriptor),
1408 DECLARE_NAPI_FUNCTION("attachLocalInterface", NAPI_RemoteObject_attachLocalInterface),
1409 DECLARE_NAPI_FUNCTION("modifyLocalInterface", NAPI_RemoteObject_modifyLocalInterface),
1410 DECLARE_NAPI_FUNCTION("queryLocalInterface", NAPI_RemoteObject_queryLocalInterface),
1411 DECLARE_NAPI_FUNCTION("getLocalInterface", NAPI_RemoteObject_getLocalInterface),
1412 DECLARE_NAPI_FUNCTION("addDeathRecipient", NAPI_RemoteObject_addDeathRecipient),
1413 DECLARE_NAPI_FUNCTION("registerDeathRecipient", NAPI_RemoteObject_registerDeathRecipient),
1414 DECLARE_NAPI_FUNCTION("removeDeathRecipient", NAPI_RemoteObject_removeDeathRecipient),
1415 DECLARE_NAPI_FUNCTION("unregisterDeathRecipient", NAPI_RemoteObject_unregisterDeathRecipient),
1416 DECLARE_NAPI_FUNCTION("isObjectDead", NAPI_RemoteObject_isObjectDead),
1417 };
1418 napi_value constructor = nullptr;
1419 napi_define_class(env, className.c_str(), className.length(), RemoteObject_JS_Constructor, nullptr,
1420 sizeof(properties) / sizeof(properties[0]), properties, &constructor);
1421 NAPI_ASSERT(env, constructor != nullptr, "define js class RemoteObject failed");
1422 napi_status status = napi_set_named_property(env, exports, "RemoteObject", constructor);
1423 NAPI_ASSERT(env, status == napi_ok, "set property RemoteObject to exports failed");
1424 napi_value global = nullptr;
1425 status = napi_get_global(env, &global);
1426 NAPI_ASSERT(env, status == napi_ok, "get napi global failed");
1427 status = napi_set_named_property(env, global, "IPCStubConstructor_", constructor);
1428 NAPI_ASSERT(env, status == napi_ok, "set stub constructor failed");
1429 return exports;
1430 }
1431 EXTERN_C_END
1432 } // namespace OHOS
1433