1 /*
2  * Copyright (c) 2022-2024 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_tag_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(napi_env env,ReleaseCallFunc releaseCallFunc,sptr<IRemoteObject> callee,std::shared_ptr<CallerCallBack> callerCallBack)53     explicit JsCallerComplex(
54         napi_env env, ReleaseCallFunc releaseCallFunc, sptr<IRemoteObject> callee,
55         std::shared_ptr<CallerCallBack> callerCallBack) : releaseCallFunc_(releaseCallFunc),
56         callee_(callee), releaseCallBackEngine_(env), remoteStateChanegdEngine_(env),
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         TAG_LOGD(AAFwkTag::DEFAULT, "called");
71         if (data == nullptr) {
72             TAG_LOGE(AAFwkTag::DEFAULT, "null data");
73             return false;
74         }
75 
76         if (!data->ChangeCurrentState(OBJSTATE::OBJ_RELEASE)) {
77             auto handler = data->GetEventHandler();
78             if (handler == nullptr) {
79                 TAG_LOGE(AAFwkTag::DEFAULT, "null handler");
80                 return false;
81             }
82             auto releaseObjTask = [pdata = data] () {
83                 if (!FindJsCallerComplex(pdata)) {
84                     TAG_LOGE(AAFwkTag::DEFAULT, "argc 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         TAG_LOGD(AAFwkTag::DEFAULT, "end");
97         return true;
98     }
99 
Finalizer(napi_env env,void * data,void * hint)100     static void Finalizer(napi_env env, void* data, void* hint)
101     {
102         TAG_LOGD(AAFwkTag::DEFAULT, "called");
103         if (data == nullptr) {
104             TAG_LOGE(AAFwkTag::DEFAULT, "null data");
105             return;
106         }
107 
108         auto ptr = static_cast<JsCallerComplex*>(data);
109         if (!FindJsCallerComplex(ptr)) {
110             TAG_LOGE(AAFwkTag::DEFAULT, "argc not found");
111             return;
112         }
113 
114         ReleaseObject(ptr);
115         TAG_LOGD(AAFwkTag::DEFAULT, "end");
116     }
117 
JsReleaseCall(napi_env env,napi_callback_info info)118     static napi_value JsReleaseCall(napi_env env, napi_callback_info info)
119     {
120         if (env == nullptr || info == nullptr) {
121             TAG_LOGE(AAFwkTag::DEFAULT, "null %{public}s", ((env == nullptr) ? "env" : "info"));
122             return nullptr;
123         }
124         GET_NAPI_INFO_AND_CALL(env, info, JsCallerComplex, ReleaseCallInner);
125     }
126 
JsSetOnReleaseCallBack(napi_env env,napi_callback_info info)127     static napi_value JsSetOnReleaseCallBack(napi_env env, napi_callback_info info)
128     {
129         if (env == nullptr || info == nullptr) {
130             TAG_LOGE(AAFwkTag::DEFAULT, "null %{public}s", ((env == nullptr) ? "env" : "info"));
131             return nullptr;
132         }
133         GET_NAPI_INFO_AND_CALL(env, info, JsCallerComplex, SetOnReleaseCallBackInner);
134     }
135 
JsSetOnRemoteStateChanged(napi_env env,napi_callback_info info)136     static napi_value JsSetOnRemoteStateChanged(napi_env env, napi_callback_info info)
137     {
138         if (env == nullptr || info == nullptr) {
139             TAG_LOGE(AAFwkTag::DEFAULT, "null %{public}s", ((env == nullptr) ? "env" : "info"));
140             return nullptr;
141         }
142         GET_NAPI_INFO_AND_CALL(env, info, JsCallerComplex, SetOnRemoteStateChangedInner);
143     }
144 
AddJsCallerComplex(JsCallerComplex * ptr)145     static bool AddJsCallerComplex(JsCallerComplex* ptr)
146     {
147         if (ptr == nullptr) {
148             TAG_LOGE(AAFwkTag::DEFAULT, "null ptr");
149             return false;
150         }
151 
152         std::lock_guard<std::mutex> lck (jsCallerComplexMutex);
153         auto iter = jsCallerComplexManagerList.find(ptr);
154         if (iter != jsCallerComplexManagerList.end()) {
155             TAG_LOGE(AAFwkTag::DEFAULT, "address exist");
156             return false;
157         }
158 
159         auto iterRet = jsCallerComplexManagerList.emplace(ptr);
160         TAG_LOGD(AAFwkTag::DEFAULT, "retval: %{public}s", iterRet.second ? "true" : "false");
161         return iterRet.second;
162     }
163 
RemoveJsCallerComplex(JsCallerComplex * ptr)164     static bool RemoveJsCallerComplex(JsCallerComplex* ptr)
165     {
166         if (ptr == nullptr) {
167             TAG_LOGE(AAFwkTag::DEFAULT, "null ptr");
168             return false;
169         }
170 
171         std::lock_guard<std::mutex> lck (jsCallerComplexMutex);
172         auto iter = jsCallerComplexManagerList.find(ptr);
173         if (iter == jsCallerComplexManagerList.end()) {
174             TAG_LOGE(AAFwkTag::DEFAULT, "argc not found");
175             return false;
176         }
177 
178         jsCallerComplexManagerList.erase(ptr);
179         TAG_LOGD(AAFwkTag::DEFAULT, "end");
180         return true;
181     }
182 
FindJsCallerComplex(JsCallerComplex * ptr)183     static bool FindJsCallerComplex(JsCallerComplex* ptr)
184     {
185         if (ptr == nullptr) {
186             TAG_LOGE(AAFwkTag::DEFAULT, "null ptr");
187             return false;
188         }
189         auto ret = true;
190         std::lock_guard<std::mutex> lck (jsCallerComplexMutex);
191         auto iter = jsCallerComplexManagerList.find(ptr);
192         if (iter == jsCallerComplexManagerList.end()) {
193             ret = false;
194         }
195         TAG_LOGD(AAFwkTag::DEFAULT, "retval %{public}s", ret ? "true" : "false");
196         return ret;
197     }
198 
FindJsCallerComplexAndChangeState(JsCallerComplex * ptr,OBJSTATE state)199     static bool FindJsCallerComplexAndChangeState(JsCallerComplex* ptr, OBJSTATE state)
200     {
201         if (ptr == nullptr) {
202             TAG_LOGE(AAFwkTag::DEFAULT, "null ptr");
203             return false;
204         }
205 
206         std::lock_guard<std::mutex> lck (jsCallerComplexMutex);
207         auto iter = jsCallerComplexManagerList.find(ptr);
208         if (iter == jsCallerComplexManagerList.end()) {
209             TAG_LOGE(AAFwkTag::DEFAULT, "argc not found");
210             return false;
211         }
212 
213         auto ret = ptr->ChangeCurrentState(state);
214         TAG_LOGD(AAFwkTag::DEFAULT, "ChangeCurrentState ret:%{public}s", ret ? "true" : "false");
215 
216         return ret;
217     }
218 
GetRemoteObject()219     sptr<IRemoteObject> GetRemoteObject()
220     {
221         return callee_;
222     }
223 
GetEventHandler()224     std::shared_ptr<AppExecFwk::EventHandler> GetEventHandler()
225     {
226         return handler_;
227     }
228 
ChangeCurrentState(OBJSTATE state)229     bool ChangeCurrentState(OBJSTATE state)
230     {
231         auto ret = false;
232         if (stateMechanismMutex_.try_lock() == false) {
233             TAG_LOGE(AAFwkTag::DEFAULT, "mutex try_lock false");
234             return ret;
235         }
236 
237         if (currentState_ == OBJSTATE::OBJ_NORMAL) {
238             currentState_ = state;
239             ret = true;
240             TAG_LOGD(AAFwkTag::DEFAULT, "currentState_:OBJ_NORMAL");
241         } else if (currentState_ == state) {
242             ret = true;
243             TAG_LOGD(AAFwkTag::DEFAULT, "currentState_:state");
244         } else {
245             ret = false;
246             TAG_LOGD(AAFwkTag::DEFAULT, "ret: false");
247         }
248 
249         stateMechanismMutex_.unlock();
250         return ret;
251     }
252 
GetCurrentState()253     OBJSTATE GetCurrentState()
254     {
255         return currentState_;
256     }
257 
StateReset()258     void StateReset()
259     {
260         currentState_ = OBJSTATE::OBJ_NORMAL;
261     }
262 
SetJsRemoteObj(napi_env env,napi_value value)263     void SetJsRemoteObj(napi_env env, napi_value value)
264     {
265         if (env == nullptr || value == nullptr) {
266             TAG_LOGE(AAFwkTag::DEFAULT, "parameter error");
267             return;
268         }
269         napi_ref ref = nullptr;
270         napi_create_reference(env, value, 1, &ref);
271         jsRemoteObj_.reset(reinterpret_cast<NativeReference*>(ref));
272         jsRemoteObjEnv_ = env;
273     }
274 
ReleaseJsRemoteObj()275     void ReleaseJsRemoteObj()
276     {
277         if (jsRemoteObjEnv_ == nullptr || jsRemoteObj_ == nullptr) {
278             return;
279         }
280         TAG_LOGI(AAFwkTag::DEFAULT, "before release call");
281         napi_value value = jsRemoteObj_->GetNapiValue();
282         NAPI_ohos_rpc_ClearNativeRemoteProxy(jsRemoteObjEnv_, value);
283         jsRemoteObj_.reset();
284         jsRemoteObjEnv_ = nullptr;
285     }
286 
287 private:
288 
OnReleaseNotify(const std::string & str)289     void OnReleaseNotify(const std::string &str)
290     {
291         TAG_LOGD(AAFwkTag::DEFAULT, "begin");
292         if (handler_ == nullptr) {
293             TAG_LOGE(AAFwkTag::DEFAULT, "null handler");
294             return;
295         }
296 
297         auto task = [notify = this, &str] () {
298             if (!FindJsCallerComplex(notify)) {
299                 TAG_LOGE(AAFwkTag::DEFAULT, "address error");
300                 return;
301             }
302             notify->OnReleaseNotifyTask(str);
303         };
304         handler_->PostSyncTask(task, "OnReleaseNotify");
305         TAG_LOGD(AAFwkTag::DEFAULT, "end");
306     }
307 
OnReleaseNotifyTask(const std::string & str)308     void OnReleaseNotifyTask(const std::string &str)
309     {
310         TAG_LOGD(AAFwkTag::DEFAULT, "begin");
311         if (jsReleaseCallBackObj_ == nullptr) {
312             TAG_LOGE(AAFwkTag::DEFAULT, "null jsreleaseObj");
313             return;
314         }
315 
316         napi_value value = jsReleaseCallBackObj_->GetNapiValue();
317         napi_value callback = jsReleaseCallBackObj_->GetNapiValue();
318         napi_value args[] = { CreateJsValue(releaseCallBackEngine_, str) };
319         napi_call_function(releaseCallBackEngine_, value, callback, 1, args, nullptr);
320         callee_ = nullptr;
321         StateReset();
322     }
323 
OnRemoteStateChangedNotify(const std::string & str)324     void OnRemoteStateChangedNotify(const std::string &str)
325     {
326         TAG_LOGD(AAFwkTag::DEFAULT, "begin");
327         if (handler_ == nullptr) {
328             TAG_LOGE(AAFwkTag::DEFAULT, "null handler");
329             return;
330         }
331 
332         auto task = [notify = this, &str] () {
333             if (!FindJsCallerComplex(notify)) {
334                 TAG_LOGE(AAFwkTag::DEFAULT, "ptr not found");
335                 return;
336             }
337             notify->OnRemoteStateChangedNotifyTask(str);
338         };
339         handler_->PostSyncTask(task, "OnRemoteStateChangedNotify");
340         TAG_LOGD(AAFwkTag::DEFAULT, "end");
341     }
342 
OnRemoteStateChangedNotifyTask(const std::string & str)343     void OnRemoteStateChangedNotifyTask(const std::string &str)
344     {
345         TAG_LOGD(AAFwkTag::DEFAULT, "begin");
346         if (jsRemoteStateChangedObj_ == nullptr) {
347             TAG_LOGE(AAFwkTag::DEFAULT, "null jsRemoteStateChangedObj");
348             return;
349         }
350 
351         napi_value value = jsRemoteStateChangedObj_->GetNapiValue();
352         napi_value callback = jsRemoteStateChangedObj_->GetNapiValue();
353         napi_value args[] = { CreateJsValue(remoteStateChanegdEngine_, str) };
354         napi_call_function(remoteStateChanegdEngine_, value, callback, 1, args, nullptr);
355         StateReset();
356         TAG_LOGD(AAFwkTag::DEFAULT, "end");
357     }
358 
ReleaseCallInner(napi_env env,NapiCallbackInfo & info)359     napi_value ReleaseCallInner(napi_env env, NapiCallbackInfo& info)
360     {
361         TAG_LOGD(AAFwkTag::DEFAULT, "called");
362         if (callerCallBackObj_ == nullptr) {
363             TAG_LOGE(AAFwkTag::DEFAULT, "null CallBacker");
364             ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER);
365         }
366 
367         if (!releaseCallFunc_) {
368             TAG_LOGE(AAFwkTag::DEFAULT, "null releaseFunc");
369             ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER);
370         }
371         callee_ = nullptr;
372         callerCallBackObj_->SetCallBack(nullptr);
373         ReleaseJsRemoteObj();
374         int32_t innerErrorCode = releaseCallFunc_(callerCallBackObj_);
375         if (innerErrorCode != ERR_OK) {
376             TAG_LOGE(AAFwkTag::DEFAULT, "ReleaseAbility failed %{public}d", static_cast<int>(innerErrorCode));
377             ThrowError(env, innerErrorCode);
378         }
379 
380         return CreateJsUndefined(env);
381     }
382 
SetOnReleaseCallBackInner(napi_env env,NapiCallbackInfo & info)383     napi_value SetOnReleaseCallBackInner(napi_env env, NapiCallbackInfo& info)
384     {
385         TAG_LOGD(AAFwkTag::DEFAULT, "start");
386         constexpr size_t argcOne = 1;
387         if (info.argc < argcOne) {
388             TAG_LOGE(AAFwkTag::DEFAULT, "Invalid argc");
389             ThrowTooFewParametersError(env);
390         }
391         bool isCallable = false;
392         napi_is_callable(env, info.argv[0], &isCallable);
393         if (!isCallable) {
394             TAG_LOGE(AAFwkTag::DEFAULT, "IsCallable %{public}s", isCallable ? "true" : "false");
395             ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
396         }
397 
398         if (callerCallBackObj_ == nullptr) {
399             TAG_LOGE(AAFwkTag::DEFAULT, "null CallBacker");
400             ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER);
401         }
402 
403         auto param1 = info.argv[0];
404         if (param1 == nullptr) {
405             TAG_LOGE(AAFwkTag::DEFAULT, "null param1");
406             ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER);
407         }
408 
409         napi_ref ref = nullptr;
410         napi_create_reference(releaseCallBackEngine_, param1, 1, &ref);
411         jsReleaseCallBackObj_.reset(reinterpret_cast<NativeReference*>(ref));
412         auto task = [notify = this] (const std::string &str) {
413             if (!FindJsCallerComplexAndChangeState(notify, OBJSTATE::OBJ_EXECUTION)) {
414                 TAG_LOGE(AAFwkTag::DEFAULT, "address error");
415                 return;
416             }
417             notify->OnReleaseNotify(str);
418         };
419         callerCallBackObj_->SetOnRelease(task);
420         return CreateJsUndefined(env);
421     }
422 
SetOnRemoteStateChangedInner(napi_env env,NapiCallbackInfo & info)423     napi_value SetOnRemoteStateChangedInner(napi_env env, NapiCallbackInfo& info)
424     {
425         TAG_LOGD(AAFwkTag::DEFAULT, "begin");
426         constexpr size_t argcOne = 1;
427         if (info.argc < argcOne) {
428             TAG_LOGE(AAFwkTag::DEFAULT, "Invalid argc");
429             ThrowTooFewParametersError(env);
430         }
431         bool isCallable = false;
432         napi_is_callable(env, info.argv[0], &isCallable);
433         if (!isCallable) {
434             TAG_LOGE(AAFwkTag::DEFAULT, "IsCallable %{public}s", isCallable ? "true" : "false");
435             ThrowError(env, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
436         }
437 
438         if (callerCallBackObj_ == nullptr) {
439             TAG_LOGE(AAFwkTag::DEFAULT, "CallBacker null");
440             ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER);
441         }
442 
443         auto param1 = info.argv[0];
444         if (param1 == nullptr) {
445             TAG_LOGE(AAFwkTag::DEFAULT, "param1 null");
446             ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER);
447         }
448 
449         napi_ref ref = nullptr;
450         napi_create_reference(remoteStateChanegdEngine_, param1, 1, &ref);
451         jsRemoteStateChangedObj_.reset(reinterpret_cast<NativeReference*>(ref));
452         auto task = [notify = this] (const std::string &str) {
453             TAG_LOGI(AAFwkTag::DEFAULT, "state changed");
454             if (!FindJsCallerComplexAndChangeState(notify, OBJSTATE::OBJ_EXECUTION)) {
455                 TAG_LOGE(AAFwkTag::DEFAULT, "address error");
456                 return;
457             }
458             notify->OnRemoteStateChangedNotify(str);
459         };
460         callerCallBackObj_->SetOnRemoteStateChanged(task);
461         TAG_LOGD(AAFwkTag::DEFAULT, "end");
462         return CreateJsUndefined(env);
463     }
464 
465 private:
466     ReleaseCallFunc releaseCallFunc_;
467     sptr<IRemoteObject> callee_;
468     napi_env releaseCallBackEngine_;
469     napi_env remoteStateChanegdEngine_;
470     napi_env jsRemoteObjEnv_ = nullptr;
471     std::shared_ptr<CallerCallBack> callerCallBackObj_;
472     std::unique_ptr<NativeReference> jsReleaseCallBackObj_;
473     std::unique_ptr<NativeReference> jsRemoteStateChangedObj_;
474     std::unique_ptr<NativeReference> jsRemoteObj_;
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(napi_env env,ReleaseCallFunc releaseCallFunc,sptr<IRemoteObject> callee,std::shared_ptr<CallerCallBack> callerCallBack)487 napi_value CreateJsCallerComplex(
488     napi_env env, ReleaseCallFunc releaseCallFunc, sptr<IRemoteObject> callee,
489     std::shared_ptr<CallerCallBack> callerCallBack)
490 {
491     TAG_LOGD(AAFwkTag::DEFAULT, "begin");
492     if (callee == nullptr || callerCallBack == nullptr || releaseCallFunc == nullptr) {
493         TAG_LOGE(AAFwkTag::DEFAULT, "%{public}s null",
494             (callee == nullptr) ? ("callee") :
495             ((releaseCallFunc == nullptr) ? ("releaseCallFunc") : ("callerCallBack")));
496         return CreateJsUndefined(env);
497     }
498 
499     napi_value object = nullptr;
500     napi_create_object(env, &object);
501     auto jsCaller = std::make_unique<JsCallerComplex>(env, releaseCallFunc, callee, callerCallBack);
502     auto remoteObj = jsCaller->GetRemoteObject();
503     if (remoteObj == nullptr) {
504         TAG_LOGE(AAFwkTag::DEFAULT, "remoteObj null");
505         return CreateJsUndefined(env);
506     }
507 
508     auto jsRemoteObj = CreateJsCalleeRemoteObject(env, remoteObj);
509     jsCaller->SetJsRemoteObj(env, jsRemoteObj);
510     napi_wrap(env, object, jsCaller.release(), JsCallerComplex::Finalizer, nullptr, nullptr);
511     napi_set_named_property(env, object, "callee", jsRemoteObj);
512     const char *moduleName = "JsCallerComplex";
513     BindNativeFunction(env, object, "release", moduleName, JsCallerComplex::JsReleaseCall);
514     BindNativeFunction(env, object, "onRelease", moduleName, JsCallerComplex::JsSetOnReleaseCallBack);
515     BindNativeFunction(env, object, "onRemoteStateChange", moduleName, JsCallerComplex::JsSetOnRemoteStateChanged);
516 
517     TAG_LOGD(AAFwkTag::DEFAULT, "end");
518     return object;
519 }
520 
CreateJsCalleeRemoteObject(napi_env env,sptr<IRemoteObject> callee)521 napi_value CreateJsCalleeRemoteObject(napi_env env, sptr<IRemoteObject> callee)
522 {
523     if (callee == nullptr) {
524         TAG_LOGE(AAFwkTag::DEFAULT, "null data");
525         return CreateJsUndefined(env);
526     }
527     napi_value napiRemoteObject = NAPI_ohos_rpc_CreateJsRemoteObject(env, callee);
528     if (napiRemoteObject == nullptr) {
529         TAG_LOGE(AAFwkTag::DEFAULT, "remoteObj null");
530     }
531     return napiRemoteObject;
532 }
533 } // AbilityRuntime
534 } // OHOS
535