• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 #include <string>
16 #include <set>
17 
18 #include "event_handler.h"
19 #include "hilog_wrapper.h"
20 #include "js_context_utils.h"
21 #include "js_data_struct_converter.h"
22 #include "js_error_utils.h"
23 #include "js_runtime.h"
24 #include "js_runtime_utils.h"
25 #include "napi_common_want.h"
26 #include "napi_remote_object.h"
27 #include "ability_runtime/js_caller_complex.h"
28 
29 namespace OHOS {
30 namespace AbilityRuntime {
31 namespace { // nameless
32 static std::map<NativeValueType, std::string> logcast = {
33     { NATIVE_UNDEFINED, std::string("NATIVE_UNDEFINED") },
34     { NATIVE_NULL, std::string("NATIVE_NULL") },
35     { NATIVE_BOOLEAN, std::string("NATIVE_BOOLEAN") },
36     { NATIVE_NUMBER, std::string("NATIVE_NUMBER") },
37     { NATIVE_STRING, std::string("NATIVE_STRING") },
38     { NATIVE_SYMBOL, std::string("NATIVE_SYMBOL") },
39     { NATIVE_OBJECT, std::string("NATIVE_OBJECT") },
40     { NATIVE_FUNCTION, std::string("NATIVE_FUNCTION") },
41     { NATIVE_EXTERNAL, std::string("NATIVE_EXTERNAL") },
42     { NATIVE_BIGINT, std::string("NATIVE_BIGINT") },
43 };
44 
45 class JsCallerComplex {
46 public:
47     enum class OBJSTATE {
48         OBJ_NORMAL,
49         OBJ_EXECUTION,
50         OBJ_RELEASE
51     };
52 
JsCallerComplex(NativeEngine & engine,ReleaseCallFunc releaseCallFunc,sptr<IRemoteObject> callee,std::shared_ptr<CallerCallBack> callerCallBack)53     explicit JsCallerComplex(
54         NativeEngine& engine, ReleaseCallFunc releaseCallFunc, sptr<IRemoteObject> callee,
55         std::shared_ptr<CallerCallBack> callerCallBack) : releaseCallFunc_(releaseCallFunc),
56         callee_(callee), releaseCallBackEngine_(engine), remoteStateChanegdEngine_(engine),
57         callerCallBackObj_(callerCallBack), jsReleaseCallBackObj_(nullptr), jsRemoteStateChangedObj_(nullptr)
58     {
59         AddJsCallerComplex(this);
60         handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
61         currentState_ = OBJSTATE::OBJ_NORMAL;
62     };
~JsCallerComplex()63     virtual~JsCallerComplex()
64     {
65         RemoveJsCallerComplex(this);
66     };
67 
ReleaseObject(JsCallerComplex * data)68     static bool ReleaseObject(JsCallerComplex* data)
69     {
70         HILOG_DEBUG("ReleaseObject begin");
71         if (data == nullptr) {
72             HILOG_ERROR("ReleaseObject begin, but input parameters is nullptr");
73             return false;
74         }
75 
76         if (!data->ChangeCurrentState(OBJSTATE::OBJ_RELEASE)) {
77             auto handler = data->GetEventHandler();
78             if (handler == nullptr) {
79                 HILOG_ERROR("ReleaseObject error end, Get eventHandler failed");
80                 return false;
81             }
82             auto releaseObjTask = [pdata = data] () {
83                 if (!FindJsCallerComplex(pdata)) {
84                     HILOG_ERROR("ReleaseObject error end, but input parameters does not found");
85                     return;
86                 }
87                 ReleaseObject(pdata);
88             };
89 
90             handler->PostTask(releaseObjTask, "FinalizerRelease");
91             return false;
92         } else {
93             // when the object is about to be destroyed, does not reset state
94             std::unique_ptr<JsCallerComplex> delObj(data);
95         }
96         HILOG_DEBUG("ReleaseObject success end");
97         return true;
98     }
99 
Finalizer(NativeEngine * engine,void * data,void * hint)100     static void Finalizer(NativeEngine* engine, void* data, void* hint)
101     {
102         HILOG_DEBUG("JsCallerComplex::%{public}s begin.", __func__);
103         if (data == nullptr) {
104             HILOG_ERROR("JsCallerComplex::%{public}s is called, but input parameters is nullptr", __func__);
105             return;
106         }
107 
108         auto ptr = static_cast<JsCallerComplex*>(data);
109         if (!FindJsCallerComplex(ptr)) {
110             HILOG_ERROR("JsCallerComplex::%{public}s is called, but input parameters does not found", __func__);
111             return;
112         }
113 
114         ReleaseObject(ptr);
115         HILOG_DEBUG("JsCallerComplex::%{public}s end.", __func__);
116     }
117 
JsReleaseCall(NativeEngine * engine,NativeCallbackInfo * info)118     static NativeValue* JsReleaseCall(NativeEngine* engine, NativeCallbackInfo* info)
119     {
120         if (engine == nullptr || info == nullptr) {
121             HILOG_ERROR("JsCallerComplex::%{public}s is called, but input parameters %{public}s is nullptr",
122                 __func__,
123                 ((engine == nullptr) ? "engine" : "info"));
124             return nullptr;
125         }
126 
127         auto object = CheckParamsAndGetThis<JsCallerComplex>(engine, info);
128         if (object == nullptr) {
129             HILOG_ERROR("JsCallerComplex::%{public}s is called, CheckParamsAndGetThis return nullptr", __func__);
130             return nullptr;
131         }
132 
133         return object->ReleaseCallInner(*engine, *info);
134     }
135 
JsSetOnReleaseCallBack(NativeEngine * engine,NativeCallbackInfo * info)136     static NativeValue* JsSetOnReleaseCallBack(NativeEngine* engine, NativeCallbackInfo* info)
137     {
138         if (engine == nullptr || info == nullptr) {
139             HILOG_ERROR("JsCallerComplex::%{public}s is called, but input parameters %{public}s is nullptr",
140                 __func__,
141                 ((engine == nullptr) ? "engine" : "info"));
142             return nullptr;
143         }
144 
145         auto object = CheckParamsAndGetThis<JsCallerComplex>(engine, info);
146         if (object == nullptr) {
147             HILOG_ERROR("JsCallerComplex::%{public}s is called, CheckParamsAndGetThis return nullptr", __func__);
148             return nullptr;
149         }
150 
151         return object->SetOnReleaseCallBackInner(*engine, *info);
152     }
153 
JsSetOnRemoteStateChanged(NativeEngine * engine,NativeCallbackInfo * info)154     static NativeValue* JsSetOnRemoteStateChanged(NativeEngine* engine, NativeCallbackInfo* info)
155     {
156         if (engine == nullptr || info == nullptr) {
157             HILOG_ERROR("JsCallerComplex::%{public}s is called, but input parameters %{public}s is nullptr",
158                 __func__,
159                 ((engine == nullptr) ? "engine" : "info"));
160             return nullptr;
161         }
162 
163         auto object = CheckParamsAndGetThis<JsCallerComplex>(engine, info);
164         if (object == nullptr) {
165             HILOG_ERROR("JsCallerComplex::%{public}s is called, CheckParamsAndGetThis return nullptr", __func__);
166             return nullptr;
167         }
168 
169         return object->SetOnRemoteStateChangedInner(*engine, *info);
170     }
171 
AddJsCallerComplex(JsCallerComplex * ptr)172     static bool AddJsCallerComplex(JsCallerComplex* ptr)
173     {
174         if (ptr == nullptr) {
175             HILOG_ERROR("JsAbilityContext::%{public}s, input parameters is nullptr", __func__);
176             return false;
177         }
178 
179         std::lock_guard<std::mutex> lck (jsCallerComplexMutex);
180         auto iter = jsCallerComplexManagerList.find(ptr);
181         if (iter != jsCallerComplexManagerList.end()) {
182             HILOG_ERROR("JsAbilityContext::%{public}s, address exists", __func__);
183             return false;
184         }
185 
186         auto iterRet = jsCallerComplexManagerList.emplace(ptr);
187         HILOG_DEBUG("JsAbilityContext::%{public}s, execution ends and retval is %{public}s",
188             __func__, iterRet.second ? "true" : "false");
189         return iterRet.second;
190     }
191 
RemoveJsCallerComplex(JsCallerComplex * ptr)192     static bool RemoveJsCallerComplex(JsCallerComplex* ptr)
193     {
194         if (ptr == nullptr) {
195             HILOG_ERROR("JsAbilityContext::%{public}s, input parameters is nullptr", __func__);
196             return false;
197         }
198 
199         std::lock_guard<std::mutex> lck (jsCallerComplexMutex);
200         auto iter = jsCallerComplexManagerList.find(ptr);
201         if (iter == jsCallerComplexManagerList.end()) {
202             HILOG_ERROR("JsAbilityContext::%{public}s, input parameters not found", __func__);
203             return false;
204         }
205 
206         jsCallerComplexManagerList.erase(ptr);
207         HILOG_DEBUG("JsAbilityContext::%{public}s, called", __func__);
208         return true;
209     }
210 
FindJsCallerComplex(JsCallerComplex * ptr)211     static bool FindJsCallerComplex(JsCallerComplex* ptr)
212     {
213         if (ptr == nullptr) {
214             HILOG_ERROR("JsAbilityContext::%{public}s, input parameters is nullptr", __func__);
215             return false;
216         }
217         auto ret = true;
218         std::lock_guard<std::mutex> lck (jsCallerComplexMutex);
219         auto iter = jsCallerComplexManagerList.find(ptr);
220         if (iter == jsCallerComplexManagerList.end()) {
221             ret = false;
222         }
223         HILOG_DEBUG("JsAbilityContext::%{public}s, execution ends and retval is %{public}s",
224             __func__, ret ? "true" : "false");
225         return ret;
226     }
227 
FindJsCallerComplexAndChangeState(JsCallerComplex * ptr,OBJSTATE state)228     static bool FindJsCallerComplexAndChangeState(JsCallerComplex* ptr, OBJSTATE state)
229     {
230         if (ptr == nullptr) {
231             HILOG_ERROR("JsAbilityContext::%{public}s, input parameters is nullptr", __func__);
232             return false;
233         }
234 
235         std::lock_guard<std::mutex> lck (jsCallerComplexMutex);
236         auto iter = jsCallerComplexManagerList.find(ptr);
237         if (iter == jsCallerComplexManagerList.end()) {
238             HILOG_ERROR("JsAbilityContext::%{public}s, execution end, but not found", __func__);
239             return false;
240         }
241 
242         auto ret = ptr->ChangeCurrentState(state);
243         HILOG_DEBUG("JsAbilityContext::%{public}s, execution ends and ChangeCurrentState retval is %{public}s",
244             __func__, ret ? "true" : "false");
245 
246         return ret;
247     }
248 
GetRemoteObject()249     sptr<IRemoteObject> GetRemoteObject()
250     {
251         return callee_;
252     }
253 
GetEventHandler()254     std::shared_ptr<AppExecFwk::EventHandler> GetEventHandler()
255     {
256         return handler_;
257     }
258 
ChangeCurrentState(OBJSTATE state)259     bool ChangeCurrentState(OBJSTATE state)
260     {
261         auto ret = false;
262         if (stateMechanismMutex_.try_lock() == false) {
263             HILOG_ERROR("mutex try_lock false");
264             return ret;
265         }
266 
267         if (currentState_ == OBJSTATE::OBJ_NORMAL) {
268             currentState_ = state;
269             ret = true;
270             HILOG_DEBUG("currentState_ == OBJSTATE::OBJ_NORMAL");
271         } else if (currentState_ == state) {
272             ret = true;
273             HILOG_DEBUG("currentState_ == state");
274         } else {
275             ret = false;
276             HILOG_DEBUG("ret = false");
277         }
278 
279         stateMechanismMutex_.unlock();
280         return ret;
281     }
282 
GetCurrentState()283     OBJSTATE GetCurrentState()
284     {
285         return currentState_;
286     }
287 
StateReset()288     void StateReset()
289     {
290         currentState_ = OBJSTATE::OBJ_NORMAL;
291     }
292 
293 private:
294 
OnReleaseNotify(const std::string & str)295     void OnReleaseNotify(const std::string &str)
296     {
297         HILOG_DEBUG("OnReleaseNotify begin");
298         if (handler_ == nullptr) {
299             HILOG_ERROR("handler parameters error");
300             return;
301         }
302 
303         auto task = [notify = this, &str] () {
304             if (!FindJsCallerComplex(notify)) {
305                 HILOG_ERROR("ptr not found, address error");
306                 return;
307             }
308             notify->OnReleaseNotifyTask(str);
309         };
310         handler_->PostSyncTask(task, "OnReleaseNotify");
311         HILOG_DEBUG("OnReleaseNotify end");
312     }
313 
OnReleaseNotifyTask(const std::string & str)314     void OnReleaseNotifyTask(const std::string &str)
315     {
316         HILOG_DEBUG("OnReleaseNotifyTask begin");
317         if (jsReleaseCallBackObj_ == nullptr) {
318             HILOG_ERROR("JsCallerComplex::%{public}s, jsreleaseObj is nullptr", __func__);
319             return;
320         }
321 
322         NativeValue* value = jsReleaseCallBackObj_->Get();
323         NativeValue* callback = jsReleaseCallBackObj_->Get();
324         NativeValue* args[] = { CreateJsValue(releaseCallBackEngine_, str) };
325         releaseCallBackEngine_.CallFunction(value, callback, args, 1);
326         HILOG_DEBUG("OnReleaseNotifyTask CallFunction call done");
327         callee_ = nullptr;
328         StateReset();
329         HILOG_DEBUG("OnReleaseNotifyTask end");
330     }
331 
OnRemoteStateChangedNotify(const std::string & str)332     void OnRemoteStateChangedNotify(const std::string &str)
333     {
334         HILOG_DEBUG("OnRemoteStateChangedNotify begin");
335         if (handler_ == nullptr) {
336             HILOG_ERROR("handler parameters error");
337             return;
338         }
339 
340         auto task = [notify = this, &str] () {
341             if (!FindJsCallerComplex(notify)) {
342                 HILOG_ERROR("ptr not found, address error");
343                 return;
344             }
345             notify->OnRemoteStateChangedNotifyTask(str);
346         };
347         handler_->PostSyncTask(task, "OnRemoteStateChangedNotify");
348         HILOG_DEBUG("OnRemoteStateChangedNotify end");
349     }
350 
OnRemoteStateChangedNotifyTask(const std::string & str)351     void OnRemoteStateChangedNotifyTask(const std::string &str)
352     {
353         HILOG_DEBUG("OnRemoteStateChangedNotifyTask begin");
354         if (jsRemoteStateChangedObj_ == nullptr) {
355             HILOG_ERROR("JsCallerComplex::%{public}s, jsRemoteStateChangedObj is nullptr", __func__);
356             return;
357         }
358 
359         NativeValue* value = jsRemoteStateChangedObj_->Get();
360         NativeValue* callback = jsRemoteStateChangedObj_->Get();
361         NativeValue* args[] = { CreateJsValue(remoteStateChanegdEngine_, str) };
362         remoteStateChanegdEngine_.CallFunction(value, callback, args, 1);
363         HILOG_DEBUG("OnRemoteStateChangedNotifyTask CallFunction call done");
364         StateReset();
365         HILOG_DEBUG("OnRemoteStateChangedNotifyTask end");
366     }
367 
ReleaseCallInner(NativeEngine & engine,NativeCallbackInfo & info)368     NativeValue* ReleaseCallInner(NativeEngine& engine, NativeCallbackInfo& info)
369     {
370         HILOG_DEBUG("JsCallerComplex::%{public}s, called", __func__);
371         if (callerCallBackObj_ == nullptr) {
372             HILOG_ERROR("JsCallerComplex::%{public}s, CallBacker is nullptr", __func__);
373             ThrowError(engine, AbilityErrorCode::ERROR_CODE_INNER);
374         }
375 
376         if (!releaseCallFunc_) {
377             HILOG_ERROR("JsCallerComplex::%{public}s, releaseFunc is nullptr", __func__);
378             ThrowError(engine, AbilityErrorCode::ERROR_CODE_INNER);
379         }
380         int32_t innerErrorCode = releaseCallFunc_(callerCallBackObj_);
381         if (innerErrorCode != ERR_OK) {
382             HILOG_ERROR("JsCallerComplex::%{public}s, ReleaseAbility failed %{public}d",
383                 __func__, static_cast<int>(innerErrorCode));
384             ThrowError(engine, innerErrorCode);
385         }
386 
387         return engine.CreateUndefined();
388     }
389 
SetOnReleaseCallBackInner(NativeEngine & engine,NativeCallbackInfo & info)390     NativeValue* SetOnReleaseCallBackInner(NativeEngine& engine, NativeCallbackInfo& info)
391     {
392         HILOG_DEBUG("JsCallerComplex::%{public}s, begin", __func__);
393         constexpr size_t argcOne = 1;
394         if (info.argc < argcOne) {
395             HILOG_ERROR("JsCallerComplex::%{public}s, Invalid input params", __func__);
396             ThrowTooFewParametersError(engine);
397         }
398         if (!info.argv[0]->IsCallable()) {
399             HILOG_ERROR("JsCallerComplex::%{public}s, IsCallable is %{public}s.",
400                 __func__, ((info.argv[0]->IsCallable()) ? "true" : "false"));
401             ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
402         }
403 
404         if (callerCallBackObj_ == nullptr) {
405             HILOG_ERROR("JsCallerComplex::%{public}s, CallBacker is nullptr", __func__);
406             ThrowError(engine, AbilityErrorCode::ERROR_CODE_INNER);
407         }
408 
409         auto param1 = info.argv[0];
410         if (param1 == nullptr) {
411             HILOG_ERROR("JsCallerComplex::%{public}s, param1 is nullptr", __func__);
412             ThrowError(engine, AbilityErrorCode::ERROR_CODE_INNER);
413         }
414 
415         jsReleaseCallBackObj_.reset(releaseCallBackEngine_.CreateReference(param1, 1));
416         auto task = [notify = this] (const std::string &str) {
417             if (!FindJsCallerComplexAndChangeState(notify, OBJSTATE::OBJ_EXECUTION)) {
418                 HILOG_ERROR("ptr not found, address error");
419                 return;
420             }
421             notify->OnReleaseNotify(str);
422         };
423         callerCallBackObj_->SetOnRelease(task);
424         HILOG_DEBUG("JsCallerComplex::%{public}s, end", __func__);
425         return engine.CreateUndefined();
426     }
427 
SetOnRemoteStateChangedInner(NativeEngine & engine,NativeCallbackInfo & info)428     NativeValue* SetOnRemoteStateChangedInner(NativeEngine& engine, NativeCallbackInfo& info)
429     {
430         HILOG_DEBUG("JsCallerComplex::%{public}s, begin", __func__);
431         constexpr size_t argcOne = 1;
432         if (info.argc < argcOne) {
433             HILOG_ERROR("JsCallerComplex::%{public}s, Invalid input params", __func__);
434             ThrowTooFewParametersError(engine);
435         }
436         if (!info.argv[0]->IsCallable()) {
437             HILOG_ERROR("JsCallerComplex::%{public}s, IsCallable is %{public}s.",
438                 __func__, ((info.argv[0]->IsCallable()) ? "true" : "false"));
439             ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
440         }
441 
442         if (callerCallBackObj_ == nullptr) {
443             HILOG_ERROR("JsCallerComplex::%{public}s, CallBacker is nullptr", __func__);
444             ThrowError(engine, AbilityErrorCode::ERROR_CODE_INNER);
445         }
446 
447         auto param1 = info.argv[0];
448         if (param1 == nullptr) {
449             HILOG_ERROR("JsCallerComplex::%{public}s, param1 is nullptr", __func__);
450             ThrowError(engine, AbilityErrorCode::ERROR_CODE_INNER);
451         }
452 
453         jsRemoteStateChangedObj_.reset(remoteStateChanegdEngine_.CreateReference(param1, 1));
454         auto task = [notify = this] (const std::string &str) {
455             HILOG_INFO("state changed");
456             if (!FindJsCallerComplexAndChangeState(notify, OBJSTATE::OBJ_EXECUTION)) {
457                 HILOG_ERROR("ptr not found, address error");
458                 return;
459             }
460             notify->OnRemoteStateChangedNotify(str);
461         };
462         callerCallBackObj_->SetOnRemoteStateChanged(task);
463         HILOG_DEBUG("JsCallerComplex::%{public}s, end", __func__);
464         return engine.CreateUndefined();
465     }
466 
467 private:
468     ReleaseCallFunc releaseCallFunc_;
469     sptr<IRemoteObject> callee_;
470     NativeEngine& releaseCallBackEngine_;
471     NativeEngine& remoteStateChanegdEngine_;
472     std::shared_ptr<CallerCallBack> callerCallBackObj_;
473     std::unique_ptr<NativeReference> jsReleaseCallBackObj_;
474     std::unique_ptr<NativeReference> jsRemoteStateChangedObj_;
475     std::shared_ptr<AppExecFwk::EventHandler> handler_;
476     std::mutex stateMechanismMutex_;
477     OBJSTATE currentState_;
478 
479     static std::set<JsCallerComplex*> jsCallerComplexManagerList;
480     static std::mutex jsCallerComplexMutex;
481 };
482 
483 std::set<JsCallerComplex*> JsCallerComplex::jsCallerComplexManagerList;
484 std::mutex JsCallerComplex::jsCallerComplexMutex;
485 } // nameless
486 
CreateJsCallerComplex(NativeEngine & engine,ReleaseCallFunc releaseCallFunc,sptr<IRemoteObject> callee,std::shared_ptr<CallerCallBack> callerCallBack)487 NativeValue* CreateJsCallerComplex(
488     NativeEngine& engine, ReleaseCallFunc releaseCallFunc, sptr<IRemoteObject> callee,
489     std::shared_ptr<CallerCallBack> callerCallBack)
490 {
491     HILOG_DEBUG("JsCallerComplex::%{public}s, begin", __func__);
492     if (callee == nullptr || callerCallBack == nullptr || releaseCallFunc == nullptr) {
493         HILOG_ERROR("%{public}s is called, input params error. %{public}s is nullptr", __func__,
494             (callee == nullptr) ? ("callee") :
495             ((releaseCallFunc == nullptr) ? ("releaseCallFunc") : ("callerCallBack")));
496         return engine.CreateUndefined();
497     }
498 
499     NativeValue* objValue = engine.CreateObject();
500     NativeObject* object = ConvertNativeValueTo<NativeObject>(objValue);
501 
502     auto jsCaller = std::make_unique<JsCallerComplex>(engine, releaseCallFunc, callee, callerCallBack);
503     auto remoteObj = jsCaller->GetRemoteObject();
504     if (remoteObj == nullptr) {
505         HILOG_ERROR("%{public}s is called,remoteObj is nullptr", __func__);
506         return engine.CreateUndefined();
507     }
508 
509     object->SetNativePointer(jsCaller.release(), JsCallerComplex::Finalizer, nullptr);
510     object->SetProperty("callee", CreateJsCalleeRemoteObject(engine, remoteObj));
511     const char *moduleName = "JsCallerComplex";
512     BindNativeFunction(engine, *object, "release", moduleName, JsCallerComplex::JsReleaseCall);
513     BindNativeFunction(engine, *object, "onRelease", moduleName, JsCallerComplex::JsSetOnReleaseCallBack);
514     BindNativeFunction(engine, *object, "onRemoteStateChange", moduleName, JsCallerComplex::JsSetOnRemoteStateChanged);
515 
516     HILOG_DEBUG("JsCallerComplex::%{public}s, end", __func__);
517     return objValue;
518 }
519 
CreateJsCalleeRemoteObject(NativeEngine & engine,sptr<IRemoteObject> callee)520 NativeValue* CreateJsCalleeRemoteObject(NativeEngine& engine, sptr<IRemoteObject> callee)
521 {
522     if (callee == nullptr) {
523         HILOG_ERROR("%{public}s is called, input params is nullptr", __func__);
524         return engine.CreateUndefined();
525     }
526     napi_value napiRemoteObject = NAPI_ohos_rpc_CreateJsRemoteObject(
527         reinterpret_cast<napi_env>(&engine), callee);
528     NativeValue* nativeRemoteObject = reinterpret_cast<NativeValue*>(napiRemoteObject);
529 
530     if (nativeRemoteObject == nullptr) {
531         HILOG_ERROR("%{public}s is called, but remoteObj is nullptr", __func__);
532     }
533 
534     return nativeRemoteObject;
535 }
536 } // AbilityRuntime
537 } // OHOS
538