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