• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 
16 #include <cstdlib>
17 #include <regex>
18 
19 #include "system_ability_definition.h"
20 #include "if_system_ability_manager.h"
21 #include "ability_delegator_registry.h"
22 #include "ability_runtime/js_ability.h"
23 
24 #include "ability_runtime/js_ability_context.h"
25 #include "ability_start_setting.h"
26 #include "connection_manager.h"
27 #include "display_util.h"
28 #include "hilog_tag_wrapper.h"
29 #include "js_data_struct_converter.h"
30 #include "js_runtime.h"
31 #include "js_runtime_utils.h"
32 #include "napi_common_configuration.h"
33 #ifdef SUPPORT_SCREEN
34 #include "js_window_stage.h"
35 #include "scene_board_judgement.h"
36 #endif
37 #include "napi_common_want.h"
38 #include "napi_remote_object.h"
39 #include "string_wrapper.h"
40 #include "time_util.h"
41 #include "context/context.h"
42 #include "context/application_context.h"
43 #include "hitrace_meter.h"
44 
45 namespace OHOS {
46 namespace AbilityRuntime {
47 namespace {
48 #ifdef SUPPORT_SCREEN
49 const std::string METHOD_NAME = "WindowScene::GoForeground";
50 #endif
51 
DetachNewJsAbilityContext(napi_env,void * nativeObject,void *)52 void* DetachNewJsAbilityContext(napi_env, void* nativeObject, void*)
53 {
54     auto* origContext = static_cast<std::weak_ptr<AbilityContext> *>(nativeObject);
55     if (origContext == nullptr) {
56         TAG_LOGE(AAFwkTag::APPKIT, "origContext is null");
57         return nullptr;
58     }
59     TAG_LOGD(AAFwkTag::APPKIT, "New detached base context");
60     auto* detachNewContext = new (std::nothrow) std::weak_ptr<AbilityContext>(*origContext);
61     return detachNewContext;
62 }
63 
DetachFinalizeJsAbilityContext(void * detachedObject,void *)64 void DetachFinalizeJsAbilityContext(void* detachedObject, void*)
65 {
66     TAG_LOGD(AAFwkTag::APPKIT, "Finalizer detached base context");
67     delete static_cast<std::weak_ptr<AbilityContext> *>(detachedObject);
68 }
69 
PromiseCallback(napi_env env,napi_callback_info info)70 napi_value PromiseCallback(napi_env env, napi_callback_info info)
71 {
72     void *data = nullptr;
73     NAPI_CALL_NO_THROW(napi_get_cb_info(env, info, nullptr, nullptr, nullptr, &data), nullptr);
74     auto *callbackInfo = static_cast<AppExecFwk::AbilityTransactionCallbackInfo<> *>(data);
75     callbackInfo->Call();
76     AppExecFwk::AbilityTransactionCallbackInfo<>::Destroy(callbackInfo);
77     data = nullptr;
78     return nullptr;
79 }
80 }
81 
AttachJsAbilityContext(napi_env env,void * value,void *)82 napi_value AttachJsAbilityContext(napi_env env, void *value, void *)
83 {
84     TAG_LOGD(AAFwkTag::ABILITY, "called");
85     if (value == nullptr) {
86         TAG_LOGW(AAFwkTag::ABILITY, "null value");
87         return nullptr;
88     }
89     auto ptr = reinterpret_cast<std::weak_ptr<AbilityRuntime::AbilityContext>*>(value)->lock();
90     if (ptr == nullptr) {
91         TAG_LOGW(AAFwkTag::ABILITY, "null ptr");
92         return nullptr;
93     }
94     napi_value object = CreateJsAbilityContext(env, ptr);
95     auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "application.AbilityContext", &object, 1);
96     if (systemModule == nullptr) {
97         TAG_LOGW(AAFwkTag::ABILITY, "null systemModule");
98         return nullptr;
99     }
100     auto contextObj = systemModule->GetNapiValue();
101     auto workContext = new (std::nothrow) std::weak_ptr<AbilityRuntime::AbilityContext>(ptr);
102     napi_coerce_to_native_binding_object(
103         env, contextObj, DetachNewJsAbilityContext, AttachJsAbilityContext, workContext, nullptr);
104     napi_add_detached_finalizer(env, contextObj, DetachFinalizeJsAbilityContext, nullptr);
105     napi_status status = napi_wrap(env, contextObj, workContext,
106         [](napi_env, void* data, void*) {
107             TAG_LOGD(AAFwkTag::ABILITY, "finalizer for weak_ptr ability context is called");
108             delete static_cast<std::weak_ptr<AbilityRuntime::AbilityContext> *>(data);
109         },
110         nullptr, nullptr);
111     if (status != napi_ok && workContext != nullptr) {
112         TAG_LOGE(AAFwkTag::ABILITY, "napi_wrap Failed: %{public}d", status);
113         delete workContext;
114         return nullptr;
115     }
116 
117     return contextObj;
118 }
119 
Create(const std::unique_ptr<Runtime> & runtime)120 Ability *JsAbility::Create(const std::unique_ptr<Runtime> &runtime)
121 {
122     return new JsAbility(static_cast<JsRuntime &>(*runtime));
123 }
124 
JsAbility(JsRuntime & jsRuntime)125 JsAbility::JsAbility(JsRuntime &jsRuntime) : jsRuntime_(jsRuntime)
126 {}
~JsAbility()127 JsAbility::~JsAbility()
128 {
129     TAG_LOGD(AAFwkTag::ABILITY, "destructor");
130     auto context = GetAbilityContext();
131     if (context) {
132         context->Unbind();
133     }
134 
135     jsRuntime_.FreeNativeReference(std::move(jsAbilityObj_));
136     jsRuntime_.FreeNativeReference(std::move(shellContextRef_));
137 #ifdef SUPPORT_SCREEN
138     jsRuntime_.FreeNativeReference(std::move(jsWindowStageObj_));
139 #endif
140 }
141 
Init(const std::shared_ptr<AbilityInfo> & abilityInfo,const std::shared_ptr<OHOSApplication> application,std::shared_ptr<AbilityHandler> & handler,const sptr<IRemoteObject> & token)142 void JsAbility::Init(const std::shared_ptr<AbilityInfo> &abilityInfo,
143     const std::shared_ptr<OHOSApplication> application, std::shared_ptr<AbilityHandler> &handler,
144     const sptr<IRemoteObject> &token)
145 {
146     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
147     Ability::Init(abilityInfo, application, handler, token);
148 
149     if (!abilityInfo) {
150         TAG_LOGE(AAFwkTag::ABILITY, "null abilityInfo");
151         return;
152     }
153     auto srcPath = GenerateSrcPath(abilityInfo);
154     if (srcPath.empty()) {
155         return;
156     }
157 
158     std::string moduleName(abilityInfo->moduleName);
159     moduleName.append("::").append(abilityInfo->name);
160 
161     HandleScope handleScope(jsRuntime_);
162 
163     jsAbilityObj_ = jsRuntime_.LoadModule(
164         moduleName, srcPath, abilityInfo->hapPath, abilityInfo->compileMode == AppExecFwk::CompileMode::ES_MODULE);
165     if (jsAbilityObj_ == nullptr) {
166         TAG_LOGE(AAFwkTag::ABILITY, "null jsAbilityObj_");
167         return;
168     }
169 
170     BindContext();
171 }
172 
GenerateSrcPath(std::shared_ptr<AbilityInfo> abilityInfo) const173 std::string JsAbility::GenerateSrcPath(std::shared_ptr<AbilityInfo> abilityInfo) const
174 {
175     if (abilityInfo == nullptr) {
176         TAG_LOGE(AAFwkTag::ABILITY, "null abilityInfo");
177         return "";
178     }
179 
180     std::string srcPath(abilityInfo->package);
181     if (!abilityInfo->isModuleJson) {
182         /* temporary compatibility api8 + config.json */
183         srcPath.append("/assets/js/");
184         if (!abilityInfo->srcPath.empty()) {
185             srcPath.append(abilityInfo->srcPath);
186         }
187         srcPath.append("/").append(abilityInfo->name).append(".abc");
188     } else {
189         if (abilityInfo->srcEntrance.empty()) {
190             TAG_LOGE(AAFwkTag::ABILITY, "abilityInfo srcEntrance empty");
191             return "";
192         }
193         srcPath.append("/");
194         srcPath.append(abilityInfo->srcEntrance);
195         srcPath.erase(srcPath.rfind("."));
196         srcPath.append(".abc");
197         TAG_LOGI(AAFwkTag::ABILITY, "%{public}s", srcPath.c_str());
198     }
199     return srcPath;
200 }
201 
BindContext()202 void JsAbility::BindContext()
203 {
204     auto env = jsRuntime_.GetNapiEnv();
205     napi_value obj = jsAbilityObj_->GetNapiValue();
206     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
207         TAG_LOGE(AAFwkTag::ABILITY, "check type failed");
208         return;
209     }
210 
211     auto context = GetAbilityContext();
212     napi_value contextObj = CreateJsAbilityContext(env, context);
213     shellContextRef_ = std::shared_ptr<NativeReference>(JsRuntime::LoadSystemModuleByEngine(
214         env, "application.AbilityContext", &contextObj, 1).release());
215     if (shellContextRef_ == nullptr) {
216         TAG_LOGE(AAFwkTag::ABILITY, "load module failed");
217         return;
218     }
219     contextObj = shellContextRef_->GetNapiValue();
220     if (!CheckTypeForNapiValue(env, contextObj, napi_object)) {
221         TAG_LOGE(AAFwkTag::ABILITY, "ability native object failed");
222         return;
223     }
224     auto workContext = new (std::nothrow) std::weak_ptr<AbilityRuntime::AbilityContext>(context);
225     napi_coerce_to_native_binding_object(
226         env, contextObj, DetachCallbackFunc, AttachJsAbilityContext, workContext, nullptr);
227     context->Bind(jsRuntime_, shellContextRef_.get());
228     napi_set_named_property(env, obj, "context", contextObj);
229     TAG_LOGD(AAFwkTag::ABILITY, "set ability context");
230 
231     napi_status status = napi_wrap(env, contextObj, workContext,
232         [](napi_env, void *data, void *) {
233             TAG_LOGD(AAFwkTag::ABILITY, "finalizer for weak_ptr ability context is called");
234             delete static_cast<std::weak_ptr<AbilityRuntime::AbilityContext> *>(data);
235         },
236         nullptr, nullptr);
237     if (status != napi_ok && workContext != nullptr) {
238         TAG_LOGE(AAFwkTag::ABILITY, "napi_wrap Failed: %{public}d", status);
239         delete workContext;
240         return;
241     }
242 }
243 
OnStart(const Want & want,sptr<AAFwk::SessionInfo> sessionInfo)244 void JsAbility::OnStart(const Want &want, sptr<AAFwk::SessionInfo> sessionInfo)
245 {
246     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
247     TAG_LOGD(AAFwkTag::ABILITY, "begin, ability: %{public}s", GetAbilityName().c_str());
248     Ability::OnStart(want, sessionInfo);
249 
250     if (!jsAbilityObj_) {
251         TAG_LOGW(AAFwkTag::ABILITY, "not found Ability.js");
252         return;
253     }
254 
255     HandleScope handleScope(jsRuntime_);
256     auto env = jsRuntime_.GetNapiEnv();
257 
258     napi_value obj = jsAbilityObj_->GetNapiValue();
259     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
260         TAG_LOGE(AAFwkTag::ABILITY, "Ability object failed");
261         return;
262     }
263 
264     napi_value jsWant = OHOS::AppExecFwk::WrapWant(env, want);
265     if (jsWant == nullptr) {
266         TAG_LOGE(AAFwkTag::ABILITY, "null jsWant");
267         return;
268     }
269 
270     napi_set_named_property(env, obj, "launchWant", jsWant);
271     napi_set_named_property(env, obj, "lastRequestWant", jsWant);
272 
273     napi_value argv[] = {
274         jsWant,
275         CreateJsLaunchParam(env, GetLaunchParam()),
276     };
277     std::string methodName = "OnStart";
278     AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
279     CallObjectMethod("onCreate", argv, ArraySize(argv));
280     AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
281 
282     auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
283     if (delegator) {
284         TAG_LOGD(AAFwkTag::ABILITY, "call PostPerformStart");
285         delegator->PostPerformStart(CreateADelegatorAbilityProperty());
286     }
287     auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
288     if (applicationContext != nullptr) {
289         applicationContext->DispatchOnAbilityCreate(jsAbilityObj_);
290     }
291     TAG_LOGD(AAFwkTag::ABILITY, "end, ability:%{public}s", GetAbilityName().c_str());
292 }
293 
AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState state,const std::string & methodName) const294 void JsAbility::AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState state, const std::string &methodName) const
295 {
296     auto entry = std::string("JsAbility::") + methodName + " begin";
297     FreezeUtil::GetInstance().AddLifecycleEvent(AbilityContext::token_, entry);
298 }
299 
AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState state,const std::string & methodName) const300 void JsAbility::AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState state, const std::string &methodName) const
301 {
302     auto entry = std::string("JsAbility::") + methodName + " end";
303     FreezeUtil::GetInstance().AddLifecycleEvent(AbilityContext::token_, entry);
304 }
305 
OnShare(WantParams & wantParam)306 int32_t JsAbility::OnShare(WantParams &wantParam)
307 {
308     TAG_LOGD(AAFwkTag::ABILITY, "called");
309     HandleScope handleScope(jsRuntime_);
310     auto env = jsRuntime_.GetNapiEnv();
311     if (jsAbilityObj_ == nullptr) {
312         TAG_LOGE(AAFwkTag::ABILITY, "null jsAbilityObj_");
313         return ERR_INVALID_VALUE;
314     }
315     napi_value obj = jsAbilityObj_->GetNapiValue();
316     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
317         TAG_LOGE(AAFwkTag::ABILITY, "Ability object failed");
318         return ERR_INVALID_VALUE;
319     }
320 
321     napi_value jsWantParams = OHOS::AppExecFwk::WrapWantParams(env, wantParam);
322     napi_value argv[] = {
323         jsWantParams,
324     };
325     CallObjectMethod("onShare", argv, ArraySize(argv));
326     OHOS::AppExecFwk::UnwrapWantParams(env, jsWantParams, wantParam);
327     return ERR_OK;
328 }
329 
OnStop()330 void JsAbility::OnStop()
331 {
332     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
333     TAG_LOGD(AAFwkTag::ABILITY, "called");
334     if (abilityContext_) {
335         TAG_LOGD(AAFwkTag::ABILITY, "set terminating true");
336         abilityContext_->SetTerminating(true);
337     }
338     Ability::OnStop();
339     HandleScope handleScope(jsRuntime_);
340     CallObjectMethod("onDestroy");
341     OnStopCallback();
342 }
343 
OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> * callbackInfo,bool & isAsyncCallback)344 void JsAbility::OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo, bool &isAsyncCallback)
345 {
346     if (callbackInfo == nullptr) {
347         isAsyncCallback = false;
348         OnStop();
349         return;
350     }
351 
352     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
353     TAG_LOGD(AAFwkTag::ABILITY, "called");
354     if (abilityContext_) {
355         TAG_LOGD(AAFwkTag::ABILITY, "set terminating true");
356         abilityContext_->SetTerminating(true);
357     }
358 
359     Ability::OnStop();
360 
361     HandleScope handleScope(jsRuntime_);
362     napi_value result = CallObjectMethod("onDestroy", nullptr, 0, true);
363     if (!CheckPromise(result)) {
364         OnStopCallback();
365         isAsyncCallback = false;
366         return;
367     }
368 
369     std::weak_ptr<Ability> weakPtr = shared_from_this();
370     auto asyncCallback = [abilityWeakPtr = weakPtr]() {
371         auto ability = abilityWeakPtr.lock();
372         if (ability == nullptr) {
373             TAG_LOGE(AAFwkTag::ABILITY, "null ability");
374             return;
375         }
376         ability->OnStopCallback();
377     };
378     callbackInfo->Push(asyncCallback);
379     isAsyncCallback = CallPromise(result, callbackInfo);
380     if (!isAsyncCallback) {
381         TAG_LOGE(AAFwkTag::ABILITY, "call promise");
382         OnStopCallback();
383     }
384 }
385 
OnStopCallback()386 void JsAbility::OnStopCallback()
387 {
388     auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
389     if (delegator) {
390         TAG_LOGD(AAFwkTag::ABILITY, "call PostPerformStop");
391         delegator->PostPerformStop(CreateADelegatorAbilityProperty());
392     }
393 
394     bool ret = ConnectionManager::GetInstance().DisconnectCaller(AbilityContext::token_);
395     if (ret) {
396         ConnectionManager::GetInstance().ReportConnectionLeakEvent(getpid(), gettid());
397         TAG_LOGD(AAFwkTag::ABILITY, "service connection not disconnected");
398     }
399 
400     auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
401     if (applicationContext != nullptr) {
402         applicationContext->DispatchOnAbilityDestroy(jsAbilityObj_);
403     }
404 }
405 
406 #ifdef SUPPORT_SCREEN
407 const std::string PAGE_STACK_PROPERTY_NAME = "pageStack";
408 const std::string SUPPORT_CONTINUE_PAGE_STACK_PROPERTY_NAME = "ohos.extra.param.key.supportContinuePageStack";
409 
OnSceneCreated()410 void JsAbility::OnSceneCreated()
411 {
412     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
413     TAG_LOGD(AAFwkTag::ABILITY, "ability: %{public}s", GetAbilityName().c_str());
414     Ability::OnSceneCreated();
415     auto jsAppWindowStage = CreateAppWindowStage();
416     if (jsAppWindowStage == nullptr) {
417         TAG_LOGE(AAFwkTag::ABILITY, "null jsAppWindowStage");
418         return;
419     }
420 
421     HandleScope handleScope(jsRuntime_);
422     napi_value argv[] = {jsAppWindowStage->GetNapiValue()};
423     {
424         HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, "onWindowStageCreate");
425         std::string methodName = "OnSceneCreated";
426         AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
427         CallObjectMethod("onWindowStageCreate", argv, ArraySize(argv));
428         AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
429     }
430 
431     auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
432     if (delegator) {
433         TAG_LOGD(AAFwkTag::ABILITY, "call PostPerformScenceCreated");
434         delegator->PostPerformScenceCreated(CreateADelegatorAbilityProperty());
435     }
436 
437     jsWindowStageObj_ = std::shared_ptr<NativeReference>(jsAppWindowStage.release());
438     auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
439     if (applicationContext != nullptr) {
440         applicationContext->DispatchOnWindowStageCreate(jsAbilityObj_, jsWindowStageObj_);
441     }
442 
443     TAG_LOGD(AAFwkTag::ABILITY, "end, ability:%{public}s", GetAbilityName().c_str());
444 }
445 
OnSceneRestored()446 void JsAbility::OnSceneRestored()
447 {
448     Ability::OnSceneRestored();
449     TAG_LOGD(AAFwkTag::ABILITY, "called");
450     HandleScope handleScope(jsRuntime_);
451     auto jsAppWindowStage = CreateAppWindowStage();
452     if (jsAppWindowStage == nullptr) {
453         TAG_LOGE(AAFwkTag::ABILITY, "null jsAppWindowStage");
454         return;
455     }
456     napi_value argv[] = {jsAppWindowStage->GetNapiValue()};
457     CallObjectMethod("onWindowStageRestore", argv, ArraySize(argv));
458 
459     auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
460     if (delegator) {
461         TAG_LOGD(AAFwkTag::ABILITY, "call PostPerformScenceRestored");
462         delegator->PostPerformScenceRestored(CreateADelegatorAbilityProperty());
463     }
464 
465     jsWindowStageObj_ = std::shared_ptr<NativeReference>(jsAppWindowStage.release());
466 }
467 
onSceneDestroyed()468 void JsAbility::onSceneDestroyed()
469 {
470     TAG_LOGD(AAFwkTag::ABILITY, "begin, ability:%{public}s", GetAbilityName().c_str());
471     Ability::onSceneDestroyed();
472     HandleScope handleScope(jsRuntime_);
473     CallObjectMethod("onWindowStageDestroy");
474 
475     if (scene_ != nullptr) {
476         auto window = scene_->GetMainWindow();
477         if (window != nullptr) {
478             TAG_LOGD(AAFwkTag::ABILITY, "call UnregisterDisplayMoveListener");
479             window->UnregisterDisplayMoveListener(abilityDisplayMoveListener_);
480         }
481     }
482 
483     auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
484     if (delegator) {
485         TAG_LOGD(AAFwkTag::ABILITY, "call PostPerformScenceDestroyed");
486         delegator->PostPerformScenceDestroyed(CreateADelegatorAbilityProperty());
487     }
488 
489     auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
490     if (applicationContext != nullptr) {
491         applicationContext->DispatchOnWindowStageDestroy(jsAbilityObj_, jsWindowStageObj_);
492     }
493     TAG_LOGD(AAFwkTag::ABILITY, "end, ability:%{public}s", GetAbilityName().c_str());
494 }
495 
OnForeground(const Want & want)496 void JsAbility::OnForeground(const Want &want)
497 {
498     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
499     TAG_LOGD(AAFwkTag::ABILITY, "begin, ability:%{public}s", GetAbilityName().c_str());
500     if (abilityInfo_) {
501         jsRuntime_.UpdateModuleNameAndAssetPath(abilityInfo_->moduleName);
502     }
503 
504     Ability::OnForeground(want);
505 
506     HandleScope handleScope(jsRuntime_);
507     auto env = jsRuntime_.GetNapiEnv();
508     if (jsAbilityObj_ == nullptr) {
509         TAG_LOGE(AAFwkTag::ABILITY, "null jsAbilityObj_");
510         return;
511     }
512     napi_value obj = jsAbilityObj_->GetNapiValue();
513     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
514         TAG_LOGE(AAFwkTag::ABILITY, "Ability object failed");
515         return;
516     }
517 
518     napi_value jsWant = OHOS::AppExecFwk::WrapWant(env, want);
519     if (jsWant == nullptr) {
520         TAG_LOGE(AAFwkTag::ABILITY, "null jsWant");
521         return;
522     }
523 
524     napi_set_named_property(env, obj, "lastRequestWant", jsWant);
525     std::string methodName = "OnForeground";
526     AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
527     CallObjectMethod("onForeground", &jsWant, 1);
528     AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
529 
530     auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
531     if (delegator) {
532         TAG_LOGD(AAFwkTag::ABILITY, "call PostPerformForeground");
533         delegator->PostPerformForeground(CreateADelegatorAbilityProperty());
534     }
535 
536     auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
537     if (applicationContext != nullptr) {
538         applicationContext->DispatchOnAbilityForeground(jsAbilityObj_);
539     }
540     TAG_LOGD(AAFwkTag::ABILITY, "end, ability:%{public}s", GetAbilityName().c_str());
541 }
542 
OnBackground()543 void JsAbility::OnBackground()
544 {
545     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
546     TAG_LOGD(AAFwkTag::ABILITY, "begin, ability:%{public}s", GetAbilityName().c_str());
547     std::string methodName = "OnBackground";
548     HandleScope handleScope(jsRuntime_);
549     AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::BACKGROUND, methodName);
550     CallObjectMethod("onBackground");
551     AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::BACKGROUND, methodName);
552 
553     Ability::OnBackground();
554 
555     auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
556     if (delegator) {
557         TAG_LOGD(AAFwkTag::ABILITY, "call PostPerformBackground");
558         delegator->PostPerformBackground(CreateADelegatorAbilityProperty());
559     }
560 
561     auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
562     if (applicationContext != nullptr) {
563         applicationContext->DispatchOnAbilityBackground(jsAbilityObj_);
564     }
565     TAG_LOGD(AAFwkTag::ABILITY, "end, ability:%{public}s", GetAbilityName().c_str());
566 }
567 
OnBackPress()568 bool JsAbility::OnBackPress()
569 {
570     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
571     TAG_LOGD(AAFwkTag::ABILITY, "call, ability:%{public}s", GetAbilityName().c_str());
572     Ability::OnBackPress();
573     HandleScope handleScope(jsRuntime_);
574     auto env = jsRuntime_.GetNapiEnv();
575     napi_value jsValue = CallObjectMethod("onBackPressed", nullptr, 0, true);
576     bool ret = false;
577     if (!ConvertFromJsValue(env, jsValue, ret)) {
578         TAG_LOGW(AAFwkTag::ABILITY, "get js value failed");
579         return false;
580     }
581     TAG_LOGD(AAFwkTag::ABILITY, "end, ret:%{public}d", ret);
582     return ret;
583 }
584 
OnPrepareTerminate()585 bool JsAbility::OnPrepareTerminate()
586 {
587     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
588     TAG_LOGD(AAFwkTag::ABILITY, "call, ability: %{public}s", GetAbilityName().c_str());
589     Ability::OnPrepareTerminate();
590     HandleScope handleScope(jsRuntime_);
591     auto env = jsRuntime_.GetNapiEnv();
592     napi_value jsValue = CallObjectMethod("onPrepareToTerminate", nullptr, 0, true);
593     bool ret = false;
594     if (!ConvertFromJsValue(env, jsValue, ret)) {
595         TAG_LOGW(AAFwkTag::ABILITY, "get js value failed");
596         return false;
597     }
598     return ret;
599 }
600 
CreateAppWindowStage()601 std::unique_ptr<NativeReference> JsAbility::CreateAppWindowStage()
602 {
603     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
604     HandleScope handleScope(jsRuntime_);
605     auto env = jsRuntime_.GetNapiEnv();
606     napi_value jsWindowStage = Rosen::CreateJsWindowStage(env, GetScene());
607     if (jsWindowStage == nullptr) {
608         TAG_LOGE(AAFwkTag::ABILITY, "null jsWindowStage");
609         return nullptr;
610     }
611     return JsRuntime::LoadSystemModuleByEngine(env, "application.WindowStage", &jsWindowStage, 1);
612 }
613 
GetPageStackFromWant(const Want & want,std::string & pageStack)614 void JsAbility::GetPageStackFromWant(const Want &want, std::string &pageStack)
615 {
616     auto stringObj = AAFwk::IString::Query(want.GetParams().GetParam(PAGE_STACK_PROPERTY_NAME));
617     if (stringObj != nullptr) {
618         pageStack = AAFwk::String::Unbox(stringObj);
619     }
620 }
621 
IsRestorePageStack(const Want & want)622 bool JsAbility::IsRestorePageStack(const Want &want)
623 {
624     return want.GetBoolParam(SUPPORT_CONTINUE_PAGE_STACK_PROPERTY_NAME, true);
625 }
626 
RestorePageStack(const Want & want)627 void JsAbility::RestorePageStack(const Want &want)
628 {
629     if (IsRestorePageStack(want)) {
630         std::string pageStack;
631         GetPageStackFromWant(want, pageStack);
632         HandleScope handleScope(jsRuntime_);
633         auto env = jsRuntime_.GetNapiEnv();
634         if (abilityContext_->GetContentStorage()) {
635             scene_->GetMainWindow()->NapiSetUIContent(pageStack, env,
636                 abilityContext_->GetContentStorage()->GetNapiValue(), Rosen::BackupAndRestoreType::CONTINUATION);
637         } else {
638             TAG_LOGE(AAFwkTag::ABILITY, "null contentStorage");
639         }
640     }
641 }
642 
AbilityContinuationOrRecover(const Want & want)643 void JsAbility::AbilityContinuationOrRecover(const Want &want)
644 {
645     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
646     // multi-instance ability continuation
647     TAG_LOGD(AAFwkTag::ABILITY, "launch reason = %{public}d", launchParam_.launchReason);
648     if (IsRestoredInContinuation()) {
649         RestorePageStack(want);
650         OnSceneRestored();
651         NotifyContinuationResult(want, true);
652     } else if (ShouldRecoverState(want)) {
653         OnSceneRestored();
654     } else {
655         OnSceneCreated();
656     }
657 }
658 
DoOnForeground(const Want & want)659 void JsAbility::DoOnForeground(const Want &want)
660 {
661     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
662     if (scene_ == nullptr) {
663         if (!InitWindowScene(want)) {
664             return;
665         }
666         AbilityContinuationOrRecover(want);
667         auto window = scene_->GetMainWindow();
668         if (window) {
669             TAG_LOGD(AAFwkTag::ABILITY, "call RegisterDisplayMoveListener, windowId: %{public}d",
670                 window->GetWindowId());
671             abilityDisplayMoveListener_ = new AbilityDisplayMoveListener(weak_from_this());
672             window->RegisterDisplayMoveListener(abilityDisplayMoveListener_);
673         }
674     } else {
675         auto window = scene_->GetMainWindow();
676         if (window != nullptr && want.HasParameter(Want::PARAM_RESV_WINDOW_MODE)) {
677             auto windowMode = want.GetIntParam(Want::PARAM_RESV_WINDOW_MODE,
678                 AAFwk::AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_UNDEFINED);
679             window->SetWindowMode(static_cast<Rosen::WindowMode>(windowMode));
680             TAG_LOGD(AAFwkTag::ABILITY, "set window mode:%{public}d", windowMode);
681         }
682     }
683 
684     auto window = scene_->GetMainWindow();
685     if (window != nullptr && securityFlag_) {
686         window->SetSystemPrivacyMode(true);
687     }
688 
689     TAG_LOGI(AAFwkTag::ABILITY, "move scene to foreground, sceneFlag_:%{public}d", Ability::sceneFlag_);
690     AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, METHOD_NAME);
691     scene_->GoForeground(Ability::sceneFlag_);
692     TAG_LOGD(AAFwkTag::ABILITY, "end");
693 }
694 
InitWindowScene(const Want & want)695 bool JsAbility::InitWindowScene(const Want &want)
696 {
697     if ((abilityContext_ == nullptr) || (sceneListener_ == nullptr)) {
698         TAG_LOGE(AAFwkTag::ABILITY, "null abilityContext_ or sceneListener_");
699         return false;
700     }
701     scene_ = std::make_shared<Rosen::WindowScene>();
702     int32_t displayId = AAFwk::DisplayUtil::GetDefaultDisplayId();
703     if (setting_ != nullptr) {
704         std::string strDisplayId =
705             setting_->GetProperty(OHOS::AppExecFwk::AbilityStartSetting::WINDOW_DISPLAY_ID_KEY);
706         std::regex formatRegex("[0-9]{0,9}$");
707         std::smatch sm;
708         bool flag = std::regex_match(strDisplayId, sm, formatRegex);
709         if (flag && !strDisplayId.empty()) {
710             int base = 10; // Numerical base (radix) that determines the valid characters and their interpretation.
711             displayId = strtol(strDisplayId.c_str(), nullptr, base);
712             TAG_LOGD(AAFwkTag::ABILITY, "displayId:%{public}d", displayId);
713         } else {
714             TAG_LOGW(AAFwkTag::ABILITY, "formatRegex:[%{public}s]", strDisplayId.c_str());
715         }
716     }
717     auto option = GetWindowOption(want);
718     Rosen::WMError ret = Rosen::WMError::WM_OK;
719     if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
720         auto sessionToken = GetSessionToken();
721         if (sessionToken == nullptr) {
722             TAG_LOGE(AAFwkTag::ABILITY, "null sessionToken");
723             return false;
724         }
725         abilityContext_->SetWeakSessionToken(sessionToken);
726         ret = scene_->Init(displayId, abilityContext_, sceneListener_, option, sessionToken);
727     } else {
728         ret = scene_->Init(displayId, abilityContext_, sceneListener_, option);
729     }
730     if (ret != Rosen::WMError::WM_OK) {
731         TAG_LOGE(AAFwkTag::ABILITY, "init window scene");
732         return false;
733     }
734     return true;
735 }
736 
RequestFocus(const Want & want)737 void JsAbility::RequestFocus(const Want &want)
738 {
739     TAG_LOGI(AAFwkTag::ABILITY, "begin");
740     if (scene_ == nullptr) {
741         TAG_LOGE(AAFwkTag::ABILITY, "null scene_");
742         return;
743     }
744     auto window = scene_->GetMainWindow();
745     if (window != nullptr && want.HasParameter(Want::PARAM_RESV_WINDOW_MODE)) {
746         auto windowMode = want.GetIntParam(Want::PARAM_RESV_WINDOW_MODE,
747             AAFwk::AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_UNDEFINED);
748         window->SetWindowMode(static_cast<Rosen::WindowMode>(windowMode));
749         TAG_LOGD(AAFwkTag::ABILITY, "set window mode = %{public}d", windowMode);
750     }
751     AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, METHOD_NAME);
752     scene_->GoForeground(Ability::sceneFlag_);
753 }
754 
ContinuationRestore(const Want & want)755 void JsAbility::ContinuationRestore(const Want &want)
756 {
757     TAG_LOGD(AAFwkTag::ABILITY, "called");
758     if (!IsRestoredInContinuation() || scene_ == nullptr) {
759         return;
760     }
761     RestorePageStack(want);
762     OnSceneRestored();
763     NotifyContinuationResult(want, true);
764 }
765 
GetJsWindowStage()766 std::shared_ptr<NativeReference> JsAbility::GetJsWindowStage()
767 {
768     TAG_LOGD(AAFwkTag::ABILITY, "called");
769     if (jsWindowStageObj_ == nullptr) {
770         TAG_LOGE(AAFwkTag::ABILITY, "null jsWindowStage");
771     }
772     return jsWindowStageObj_;
773 }
774 
GetJsRuntime()775 const JsRuntime& JsAbility::GetJsRuntime()
776 {
777     return jsRuntime_;
778 }
779 
780 #endif
781 
OnContinue(WantParams & wantParams)782 int32_t JsAbility::OnContinue(WantParams &wantParams)
783 {
784     HandleScope handleScope(jsRuntime_);
785     auto env = jsRuntime_.GetNapiEnv();
786     if (jsAbilityObj_ == nullptr) {
787         TAG_LOGE(AAFwkTag::ABILITY, "null jsAbilityObj_");
788         return AppExecFwk::ContinuationManager::OnContinueResult::ON_CONTINUE_ERR;
789     }
790     napi_value obj = jsAbilityObj_->GetNapiValue();
791     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
792         TAG_LOGE(AAFwkTag::ABILITY, "Ability object");
793         return AppExecFwk::ContinuationManager::OnContinueResult::ON_CONTINUE_ERR;
794     }
795 
796     napi_value methodOnCreate = nullptr;
797     napi_get_named_property(env, obj, "onContinue", &methodOnCreate);
798     if (methodOnCreate == nullptr) {
799         TAG_LOGE(AAFwkTag::ABILITY, "null methodOnCreate");
800         return AppExecFwk::ContinuationManager::OnContinueResult::ON_CONTINUE_ERR;
801     }
802 
803     napi_value jsWantParams = OHOS::AppExecFwk::WrapWantParams(env, wantParams);
804     napi_value result = nullptr;
805     napi_call_function(env, obj, methodOnCreate, 1, &jsWantParams, &result);
806 
807     OHOS::AppExecFwk::UnwrapWantParams(env, jsWantParams, wantParams);
808 
809     int32_t numberResult = 0;
810     if (!ConvertFromJsValue(env, result, numberResult)) {
811         TAG_LOGE(AAFwkTag::ABILITY, "'onContinue' not implemented");
812         return AppExecFwk::ContinuationManager::OnContinueResult::ON_CONTINUE_ERR;
813     }
814 
815     auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
816     if (applicationContext != nullptr) {
817         applicationContext->DispatchOnAbilityContinue(jsAbilityObj_);
818     }
819 
820     return numberResult;
821 }
822 
OnSaveState(int32_t reason,WantParams & wantParams)823 int32_t JsAbility::OnSaveState(int32_t reason, WantParams &wantParams)
824 {
825     HandleScope handleScope(jsRuntime_);
826     auto env = jsRuntime_.GetNapiEnv();
827     if (jsAbilityObj_ == nullptr) {
828         TAG_LOGE(AAFwkTag::ABILITY, "null jsAbilityObj_");
829         return -1;
830     }
831     napi_value obj = jsAbilityObj_->GetNapiValue();
832     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
833         TAG_LOGE(AAFwkTag::ABILITY, "appRecovery get Ability object");
834         return -1;
835     }
836 
837     napi_value methodOnSaveState = nullptr;
838     napi_get_named_property(env, obj, "onSaveState", &methodOnSaveState);
839     if (methodOnSaveState == nullptr) {
840         TAG_LOGE(AAFwkTag::ABILITY, "null methodOnSaveState");
841         return -1;
842     }
843 
844     napi_value jsWantParams = OHOS::AppExecFwk::WrapWantParams(env, wantParams);
845     napi_value jsReason = CreateJsValue(env, reason);
846     napi_value args[] = { jsReason, jsWantParams };
847     napi_value result = nullptr;
848     napi_call_function(env, obj, methodOnSaveState, 2, args, &result); // 2:args size
849     OHOS::AppExecFwk::UnwrapWantParams(env, jsWantParams, wantParams);
850 
851     int32_t numberResult = 0;
852     if (!ConvertFromJsValue(env, result, numberResult)) {
853         TAG_LOGE(AAFwkTag::ABILITY, "appRecovery no result");
854         return -1;
855     }
856     return numberResult;
857 }
858 
OnConfigurationUpdated(const Configuration & configuration)859 void JsAbility::OnConfigurationUpdated(const Configuration &configuration)
860 {
861     Ability::OnConfigurationUpdated(configuration);
862     TAG_LOGD(AAFwkTag::ABILITY, "called");
863 
864     HandleScope handleScope(jsRuntime_);
865     auto env = jsRuntime_.GetNapiEnv();
866     auto fullConfig = GetAbilityContext()->GetConfiguration();
867     if (!fullConfig) {
868         TAG_LOGE(AAFwkTag::ABILITY, "configuration");
869         return;
870     }
871 
872     napi_value napiConfiguration = OHOS::AppExecFwk::WrapConfiguration(env, configuration);
873     CallObjectMethod("onConfigurationUpdated", &napiConfiguration, 1);
874     CallObjectMethod("onConfigurationUpdate", &napiConfiguration, 1);
875     JsAbilityContext::ConfigurationUpdated(env, shellContextRef_, fullConfig);
876 }
877 
OnMemoryLevel(int level)878 void JsAbility::OnMemoryLevel(int level)
879 {
880     Ability::OnMemoryLevel(level);
881     TAG_LOGD(AAFwkTag::ABILITY, "called");
882 
883     HandleScope handleScope(jsRuntime_);
884     auto env = jsRuntime_.GetNapiEnv();
885     if (jsAbilityObj_ == nullptr) {
886         TAG_LOGE(AAFwkTag::ABILITY, "null jsAbilityObj_");
887         return;
888     }
889     napi_value obj = jsAbilityObj_->GetNapiValue();
890     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
891         TAG_LOGE(AAFwkTag::ABILITY, "Ability object failed");
892         return;
893     }
894 
895     napi_value jslevel = CreateJsValue(env, level);
896     napi_value argv[] = {
897         jslevel,
898     };
899     CallObjectMethod("onMemoryLevel", argv, ArraySize(argv));
900 }
901 
UpdateContextConfiguration()902 void JsAbility::UpdateContextConfiguration()
903 {
904     TAG_LOGD(AAFwkTag::ABILITY, "called");
905     HandleScope handleScope(jsRuntime_);
906     auto env = jsRuntime_.GetNapiEnv();
907     JsAbilityContext::ConfigurationUpdated(env, shellContextRef_, GetAbilityContext()->GetConfiguration());
908 }
909 
OnNewWant(const Want & want)910 void JsAbility::OnNewWant(const Want &want)
911 {
912     TAG_LOGD(AAFwkTag::ABILITY, "called");
913     Ability::OnNewWant(want);
914 
915 #ifdef SUPPORT_SCREEN
916     if (scene_) {
917         scene_->OnNewWant(want);
918     }
919 #endif
920 
921     HandleScope handleScope(jsRuntime_);
922     auto env = jsRuntime_.GetNapiEnv();
923     if (jsAbilityObj_ == nullptr) {
924         TAG_LOGE(AAFwkTag::ABILITY, "null jsAbilityObj_");
925         return;
926     }
927     napi_value obj = jsAbilityObj_->GetNapiValue();
928     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
929         TAG_LOGE(AAFwkTag::ABILITY, "Ability object failed");
930         return;
931     }
932 
933     napi_value jsWant = OHOS::AppExecFwk::WrapWant(env, want);
934     if (jsWant == nullptr) {
935         TAG_LOGE(AAFwkTag::ABILITY, "null want");
936         return;
937     }
938 
939     napi_set_named_property(env, obj, "lastRequestWant", jsWant);
940 
941     napi_value argv[] = {
942         jsWant,
943         CreateJsLaunchParam(env, GetLaunchParam()),
944     };
945     std::string methodName = "OnNewWant";
946     AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
947     CallObjectMethod("onNewWant", argv, ArraySize(argv));
948     AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
949 
950     TAG_LOGD(AAFwkTag::ABILITY, "end");
951 }
952 
OnAbilityResult(int requestCode,int resultCode,const Want & resultData)953 void JsAbility::OnAbilityResult(int requestCode, int resultCode, const Want &resultData)
954 {
955     TAG_LOGD(AAFwkTag::ABILITY, "called");
956     Ability::OnAbilityResult(requestCode, resultCode, resultData);
957     std::shared_ptr<AbilityRuntime::AbilityContext> context = GetAbilityContext();
958     if (context == nullptr) {
959         TAG_LOGW(AAFwkTag::ABILITY, "null context");
960         return;
961     }
962     context->OnAbilityResult(requestCode, resultCode, resultData);
963     TAG_LOGD(AAFwkTag::ABILITY, "end");
964 }
965 
CallRequest()966 sptr<IRemoteObject> JsAbility::CallRequest()
967 {
968     TAG_LOGD(AAFwkTag::ABILITY, "called");
969     if (jsAbilityObj_ == nullptr) {
970         TAG_LOGW(AAFwkTag::ABILITY, "null Obj");
971         return nullptr;
972     }
973 
974     if (remoteCallee_ != nullptr) {
975         TAG_LOGD(AAFwkTag::ABILITY, "get Callee remoteObj");
976         return remoteCallee_;
977     }
978 
979     HandleScope handleScope(jsRuntime_);
980     TAG_LOGD(AAFwkTag::ABILITY, "set runtime scope");
981     auto env = jsRuntime_.GetNapiEnv();
982     auto obj = jsAbilityObj_->GetNapiValue();
983     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
984         TAG_LOGE(AAFwkTag::ABILITY, "object failed");
985         return nullptr;
986     }
987 
988     napi_value method = nullptr;
989     napi_get_named_property(env, obj, "onCallRequest", &method);
990     bool isCallable = false;
991     napi_is_callable(env, method, &isCallable);
992     if (!isCallable) {
993         TAG_LOGE(AAFwkTag::ABILITY, "method:%{public}s",
994             method == nullptr ? "nullptr" : "not func");
995         return nullptr;
996     }
997 
998     napi_value remoteJsObj = nullptr;
999     napi_call_function(env, obj, method, 0, nullptr, &remoteJsObj);
1000     if (remoteJsObj == nullptr) {
1001         TAG_LOGE(AAFwkTag::ABILITY, "null remoteJsObj");
1002         return nullptr;
1003     }
1004 
1005     remoteCallee_ = SetNewRuleFlagToCallee(env, remoteJsObj);
1006     TAG_LOGD(AAFwkTag::ABILITY, "end");
1007     return remoteCallee_;
1008 }
1009 
CallObjectMethod(const char * name,napi_value const * argv,size_t argc,bool withResult)1010 napi_value JsAbility::CallObjectMethod(const char *name, napi_value const *argv, size_t argc, bool withResult)
1011 {
1012     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
1013     TAG_LOGI(AAFwkTag::ABILITY, "begin:%{public}s", name);
1014 
1015     if (!jsAbilityObj_) {
1016         TAG_LOGW(AAFwkTag::ABILITY, "not found Ability.js");
1017         return nullptr;
1018     }
1019 
1020     HandleEscape handleEscape(jsRuntime_);
1021     auto env = jsRuntime_.GetNapiEnv();
1022 
1023     napi_value obj = jsAbilityObj_->GetNapiValue();
1024     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
1025         TAG_LOGE(AAFwkTag::ABILITY, "Ability object failed");
1026         return nullptr;
1027     }
1028 
1029     napi_value methodOnCreate = nullptr;
1030     napi_get_named_property(env, obj, name, &methodOnCreate);
1031     if (methodOnCreate == nullptr) {
1032         TAG_LOGE(AAFwkTag::ABILITY, "null methodOnCreate");
1033         return nullptr;
1034     }
1035     if (withResult) {
1036         napi_value result = nullptr;
1037         napi_call_function(env, obj, methodOnCreate, argc, argv, &result);
1038         return handleEscape.Escape(result);
1039     }
1040     napi_call_function(env, obj, methodOnCreate, argc, argv, nullptr);
1041     TAG_LOGI(AAFwkTag::ABILITY, "end:%{public}s", name);
1042     return nullptr;
1043 }
1044 
CheckPromise(napi_value result)1045 bool JsAbility::CheckPromise(napi_value result)
1046 {
1047     if (result == nullptr) {
1048         TAG_LOGD(AAFwkTag::ABILITY, "null result");
1049         return false;
1050     }
1051     auto env = jsRuntime_.GetNapiEnv();
1052     bool isPromise = false;
1053     napi_is_promise(env, result, &isPromise);
1054     if (!isPromise) {
1055         TAG_LOGD(AAFwkTag::ABILITY, "result not promise");
1056         return false;
1057     }
1058     return true;
1059 }
1060 
CallPromise(napi_value result,AppExecFwk::AbilityTransactionCallbackInfo<> * callbackInfo)1061 bool JsAbility::CallPromise(napi_value result, AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo)
1062 {
1063     auto env = jsRuntime_.GetNapiEnv();
1064     if (!CheckTypeForNapiValue(env, result, napi_object)) {
1065         TAG_LOGE(AAFwkTag::ABILITY, "convert failed");
1066         return false;
1067     }
1068     napi_value then = nullptr;
1069     napi_get_named_property(env, result, "then", &then);
1070     if (then == nullptr) {
1071         TAG_LOGE(AAFwkTag::ABILITY, "null then");
1072         return false;
1073     }
1074     bool isCallable = false;
1075     napi_is_callable(env, then, &isCallable);
1076     if (!isCallable) {
1077         TAG_LOGE(AAFwkTag::ABILITY, "property not callable");
1078         return false;
1079     }
1080     HandleScope handleScope(jsRuntime_);
1081     napi_value promiseCallback = nullptr;
1082     napi_create_function(env, "promiseCallback", strlen("promiseCallback"), PromiseCallback,
1083         callbackInfo, &promiseCallback);
1084     napi_value argv[1] = { promiseCallback };
1085     napi_call_function(env, result, then, 1, argv, nullptr);
1086     TAG_LOGD(AAFwkTag::ABILITY, "callPromise complete");
1087     return true;
1088 }
1089 
CreateADelegatorAbilityProperty()1090 std::shared_ptr<AppExecFwk::ADelegatorAbilityProperty> JsAbility::CreateADelegatorAbilityProperty()
1091 {
1092     auto property = std::make_shared<AppExecFwk::ADelegatorAbilityProperty>();
1093     property->token_          = GetAbilityContext()->GetToken();
1094     property->name_           = GetAbilityName();
1095     property->moduleName_     = GetModuleName();
1096     if (GetApplicationInfo() == nullptr || GetApplicationInfo()->bundleName.empty()) {
1097         property->fullName_ = GetAbilityName();
1098     } else {
1099         std::string::size_type pos = GetAbilityName().find(GetApplicationInfo()->bundleName);
1100         if (pos == std::string::npos || pos != 0) {
1101             property->fullName_ = GetApplicationInfo()->bundleName + "." + GetAbilityName();
1102         } else {
1103             property->fullName_ = GetAbilityName();
1104         }
1105     }
1106     property->lifecycleState_ = GetState();
1107     property->object_         = jsAbilityObj_;
1108 
1109     return property;
1110 }
1111 
Dump(const std::vector<std::string> & params,std::vector<std::string> & info)1112 void JsAbility::Dump(const std::vector<std::string> &params, std::vector<std::string> &info)
1113 {
1114     Ability::Dump(params, info);
1115     TAG_LOGD(AAFwkTag::ABILITY, "called");
1116     HandleScope handleScope(jsRuntime_);
1117 
1118     if (!jsAbilityObj_) {
1119         TAG_LOGW(AAFwkTag::ABILITY, "not found .js");
1120         return;
1121     }
1122 
1123     auto env = jsRuntime_.GetNapiEnv();
1124     napi_value obj = jsAbilityObj_->GetNapiValue();
1125     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
1126         TAG_LOGE(AAFwkTag::ABILITY, "get object failed");
1127         return;
1128     }
1129 
1130     if (!AddDumpInfo(env, obj, params, info, "dump")) {
1131         return;
1132     }
1133     if (!AddDumpInfo(env, obj, params, info, "onDump")) {
1134         return;
1135     }
1136 
1137     TAG_LOGD(AAFwkTag::ABILITY, "dump info size:%{public}zu", info.size());
1138 }
1139 
AddDumpInfo(napi_env env,napi_value obj,const std::vector<std::string> & params,std::vector<std::string> & info,const std::string & methodName) const1140 bool JsAbility::AddDumpInfo(napi_env env, napi_value obj, const std::vector<std::string> &params,
1141     std::vector<std::string> &info, const std::string &methodName) const
1142 {
1143     // create js array object of params
1144     napi_value argv[] = { CreateNativeArray(env, params) };
1145 
1146     napi_value method = nullptr;
1147     napi_get_named_property(env, obj, methodName.c_str(), &method);
1148 
1149     napi_value dumpInfo = nullptr;
1150     if (method != nullptr) {
1151         napi_call_function(env, obj, method, 1, argv, &dumpInfo);
1152     }
1153 
1154     if (dumpInfo == nullptr) {
1155         uint32_t len = 0;
1156         napi_get_array_length(env, dumpInfo, &len);
1157         for (uint32_t i = 0; i < len; i++) {
1158             std::string dumpInfoStr;
1159             napi_value element = nullptr;
1160             napi_get_element(env, dumpInfo, i, &element);
1161             if (!ConvertFromJsValue(env, element, dumpInfoStr)) {
1162                 TAG_LOGE(AAFwkTag::ABILITY, "parse dumpInfoStr failed");
1163                 return false;
1164             }
1165             info.push_back(dumpInfoStr);
1166         }
1167     }
1168     return true;
1169 }
1170 
GetJsAbility()1171 std::shared_ptr<NativeReference> JsAbility::GetJsAbility()
1172 {
1173     TAG_LOGD(AAFwkTag::ABILITY, "called");
1174     if (jsAbilityObj_ == nullptr) {
1175         TAG_LOGE(AAFwkTag::ABILITY, "null jsAbilityObj_");
1176     }
1177     return jsAbilityObj_;
1178 }
1179 
SetNewRuleFlagToCallee(napi_env env,napi_value remoteJsObj)1180 sptr<IRemoteObject> JsAbility::SetNewRuleFlagToCallee(napi_env env, napi_value remoteJsObj)
1181 {
1182     if (!CheckTypeForNapiValue(env, remoteJsObj, napi_object)) {
1183         TAG_LOGE(AAFwkTag::ABILITY, "null calleeObj");
1184         return nullptr;
1185     }
1186     napi_value setFlagMethod = nullptr;
1187     napi_get_named_property(env, remoteJsObj, "setNewRuleFlag", &setFlagMethod);
1188     bool isCallable = false;
1189     napi_is_callable(env, setFlagMethod, &isCallable);
1190     if (!isCallable) {
1191         TAG_LOGE(AAFwkTag::ABILITY, "setFlagMethod:%{public}s",
1192             setFlagMethod == nullptr ? "nullptr" : "not func");
1193         return nullptr;
1194     }
1195     auto flag = CreateJsValue(env, IsUseNewStartUpRule());
1196     napi_value argv[1] = { flag };
1197     napi_call_function(env, remoteJsObj, setFlagMethod, 1, argv, nullptr);
1198 
1199     auto remoteObj = NAPI_ohos_rpc_getNativeRemoteObject(env, remoteJsObj);
1200     if (remoteObj == nullptr) {
1201         TAG_LOGE(AAFwkTag::ABILITY, "null remoteObj");
1202         return nullptr;
1203     }
1204     return remoteObj;
1205 }
1206 }  // namespace AbilityRuntime
1207 }  // namespace OHOS
1208