• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, [&param] { 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