1 /*
2  * Copyright (c) 2023-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 "js_ui_ability.h"
17 
18 #include <cstdlib>
19 #include <regex>
20 
21 #include "ability_business_error.h"
22 #include "ability_delegator_registry.h"
23 #include "ability_recovery.h"
24 #include "ability_start_setting.h"
25 #include "app_recovery.h"
26 #include "connection_manager.h"
27 #include "context/application_context.h"
28 #include "context/context.h"
29 #include "hilog_tag_wrapper.h"
30 #include "hitrace_meter.h"
31 #include "if_system_ability_manager.h"
32 #include "insight_intent_executor_info.h"
33 #include "insight_intent_executor_mgr.h"
34 #include "insight_intent_execute_param.h"
35 #include "js_ability_context.h"
36 #include "js_data_struct_converter.h"
37 #include "js_runtime.h"
38 #include "js_runtime_utils.h"
39 #include "js_utils.h"
40 #ifdef SUPPORT_GRAPHICS
41 #include "js_window_stage.h"
42 #endif
43 #include "napi_common_configuration.h"
44 #include "napi_common_want.h"
45 #include "napi_remote_object.h"
46 #include "scene_board_judgement.h"
47 #include "string_wrapper.h"
48 #include "system_ability_definition.h"
49 #include "time_util.h"
50 
51 namespace OHOS {
52 namespace AbilityRuntime {
53 namespace {
54 #ifdef SUPPORT_GRAPHICS
55 const std::string PAGE_STACK_PROPERTY_NAME = "pageStack";
56 const std::string SUPPORT_CONTINUE_PAGE_STACK_PROPERTY_NAME = "ohos.extra.param.key.supportContinuePageStack";
57 const std::string METHOD_NAME = "WindowScene::GoForeground";
58 #endif
59 // Numerical base (radix) that determines the valid characters and their interpretation.
60 const int32_t BASE_DISPLAY_ID_NUM (10);
61 constexpr const int32_t API12 = 12;
62 constexpr const int32_t API_VERSION_MOD = 100;
63 
PromiseCallback(napi_env env,napi_callback_info info)64 napi_value PromiseCallback(napi_env env, napi_callback_info info)
65 {
66     void *data = nullptr;
67     NAPI_CALL_NO_THROW(napi_get_cb_info(env, info, nullptr, nullptr, nullptr, &data), nullptr);
68     auto *callbackInfo = static_cast<AppExecFwk::AbilityTransactionCallbackInfo<> *>(data);
69     callbackInfo->Call();
70     AppExecFwk::AbilityTransactionCallbackInfo<>::Destroy(callbackInfo);
71     data = nullptr;
72     return nullptr;
73 }
74 
OnContinuePromiseCallback(napi_env env,napi_callback_info info)75 napi_value OnContinuePromiseCallback(napi_env env, napi_callback_info info)
76 {
77     void *data = nullptr;
78     size_t argc = 1;
79     napi_value argv = {nullptr};
80     NAPI_CALL_NO_THROW(napi_get_cb_info(env, info, &argc, &argv, nullptr, &data), nullptr);
81     int32_t onContinueRes = 0;
82     if (!ConvertFromJsValue(env, argv, onContinueRes)) {
83         TAG_LOGE(AAFwkTag::UIABILITY, "get value failed");
84         return nullptr;
85     }
86     auto *callbackInfo = static_cast<AppExecFwk::AbilityTransactionCallbackInfo<int32_t> *>(data);
87     callbackInfo->Call(onContinueRes);
88     AppExecFwk::AbilityTransactionCallbackInfo<int32_t>::Destroy(callbackInfo);
89     data = nullptr;
90 
91     return nullptr;
92 }
93 } // namespace
94 
AttachJsAbilityContext(napi_env env,void * value,void * extValue)95 napi_value AttachJsAbilityContext(napi_env env, void *value, void *extValue)
96 {
97     TAG_LOGD(AAFwkTag::UIABILITY, "called");
98     if (value == nullptr || extValue == nullptr) {
99         TAG_LOGE(AAFwkTag::UIABILITY, "invalid params");
100         return nullptr;
101     }
102     auto ptr = reinterpret_cast<std::weak_ptr<AbilityRuntime::AbilityContext> *>(value)->lock();
103     if (ptr == nullptr) {
104         TAG_LOGE(AAFwkTag::UIABILITY, "null context");
105         return nullptr;
106     }
107     std::shared_ptr<NativeReference> systemModule = nullptr;
108     auto screenModePtr = reinterpret_cast<std::weak_ptr<int32_t> *>(extValue)->lock();
109     if (screenModePtr == nullptr) {
110         TAG_LOGE(AAFwkTag::UIABILITY, "nul screenModePtr");
111         return nullptr;
112     }
113     if (*screenModePtr == AAFwk::IDLE_SCREEN_MODE) {
114         auto uiAbiObject = CreateJsAbilityContext(env, ptr);
115         CHECK_POINTER_AND_RETURN(uiAbiObject, nullptr);
116         systemModule = std::shared_ptr<NativeReference>(JsRuntime::LoadSystemModuleByEngine(env,
117             "application.AbilityContext", &uiAbiObject, 1).release());
118     } else {
119         auto emUIObject = JsEmbeddableUIAbilityContext::CreateJsEmbeddableUIAbilityContext(env,
120             ptr, nullptr, *screenModePtr);
121         CHECK_POINTER_AND_RETURN(emUIObject, nullptr);
122         systemModule = std::shared_ptr<NativeReference>(JsRuntime::LoadSystemModuleByEngine(env,
123             "application.EmbeddableUIAbilityContext", &emUIObject, 1).release());
124     }
125     CHECK_POINTER_AND_RETURN(systemModule, nullptr);
126     auto contextObj = systemModule->GetNapiValue();
127     napi_coerce_to_native_binding_object(env, contextObj, DetachCallbackFunc, AttachJsAbilityContext, value, extValue);
128     auto workContext = new (std::nothrow) std::weak_ptr<AbilityRuntime::AbilityContext>(ptr);
129     if (workContext != nullptr) {
130         napi_status status = napi_wrap(env, contextObj, workContext,
131             [](napi_env, void* data, void*) {
132               TAG_LOGD(AAFwkTag::UIABILITY, "finalizer for weak_ptr ability context is called");
133               delete static_cast<std::weak_ptr<AbilityRuntime::AbilityContext> *>(data);
134             },
135             nullptr, nullptr);
136         if (status != napi_ok && workContext != nullptr) {
137             TAG_LOGE(AAFwkTag::UIABILITY, "napi_wrap Failed: %{public}d", status);
138             delete workContext;
139             return nullptr;
140         }
141     }
142     return contextObj;
143 }
144 
Create(const std::unique_ptr<Runtime> & runtime)145 UIAbility *JsUIAbility::Create(const std::unique_ptr<Runtime> &runtime)
146 {
147     return new (std::nothrow) JsUIAbility(static_cast<JsRuntime &>(*runtime));
148 }
149 
JsUIAbility(JsRuntime & jsRuntime)150 JsUIAbility::JsUIAbility(JsRuntime &jsRuntime) : jsRuntime_(jsRuntime)
151 {
152     TAG_LOGD(AAFwkTag::UIABILITY, "called");
153 }
154 
~JsUIAbility()155 JsUIAbility::~JsUIAbility()
156 {
157     // maintenance log
158     TAG_LOGI(AAFwkTag::UIABILITY, "called");
159     if (abilityContext_ != nullptr) {
160         abilityContext_->Unbind();
161     }
162 
163     jsRuntime_.FreeNativeReference(std::move(jsAbilityObj_));
164     jsRuntime_.FreeNativeReference(std::move(shellContextRef_));
165 #ifdef SUPPORT_GRAPHICS
166     jsRuntime_.FreeNativeReference(std::move(jsWindowStageObj_));
167 #endif
168 }
169 
Init(std::shared_ptr<AppExecFwk::AbilityLocalRecord> record,const std::shared_ptr<OHOSApplication> application,std::shared_ptr<AbilityHandler> & handler,const sptr<IRemoteObject> & token)170 void JsUIAbility::Init(std::shared_ptr<AppExecFwk::AbilityLocalRecord> record,
171     const std::shared_ptr<OHOSApplication> application, std::shared_ptr<AbilityHandler> &handler,
172     const sptr<IRemoteObject> &token)
173 {
174     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
175     if (record == nullptr) {
176         TAG_LOGE(AAFwkTag::UIABILITY, "null localAbilityRecord");
177         return;
178     }
179     auto abilityInfo = record->GetAbilityInfo();
180     if (abilityInfo == nullptr) {
181         TAG_LOGE(AAFwkTag::UIABILITY, "null abilityInfo");
182         return;
183     }
184     UIAbility::Init(record, application, handler, token);
185 #ifdef SUPPORT_GRAPHICS
186     if (abilityContext_ != nullptr) {
187         AppExecFwk::AppRecovery::GetInstance().AddAbility(
188             shared_from_this(), abilityContext_->GetAbilityInfo(), abilityContext_->GetToken());
189     }
190 #endif
191     std::string srcPath(abilityInfo->package);
192     if (!abilityInfo->isModuleJson) {
193         /* temporary compatibility api8 + config.json */
194         srcPath.append("/assets/js/");
195         if (!abilityInfo->srcPath.empty()) {
196             srcPath.append(abilityInfo->srcPath);
197         }
198         srcPath.append("/").append(abilityInfo->name).append(".abc");
199     } else {
200         if (abilityInfo->srcEntrance.empty()) {
201             TAG_LOGE(AAFwkTag::UIABILITY, "empty srcEntrance");
202             return;
203         }
204         srcPath.append("/");
205         srcPath.append(abilityInfo->srcEntrance);
206         srcPath.erase(srcPath.rfind("."));
207         srcPath.append(".abc");
208         TAG_LOGD(AAFwkTag::UIABILITY, "jsAbility srcPath: %{public}s", srcPath.c_str());
209     }
210 
211     std::string moduleName(abilityInfo->moduleName);
212     moduleName.append("::").append(abilityInfo->name);
213 
214     SetAbilityContext(abilityInfo, record->GetWant(), moduleName, srcPath);
215 }
216 
UpdateAbilityObj(std::shared_ptr<AbilityInfo> abilityInfo,const std::string & moduleName,const std::string & srcPath)217 void JsUIAbility::UpdateAbilityObj(std::shared_ptr<AbilityInfo> abilityInfo,
218     const std::string &moduleName, const std::string &srcPath)
219 {
220     std::string key = moduleName + "::" + srcPath;
221     std::unique_ptr<NativeReference> moduleObj = nullptr;
222     jsAbilityObj_ = jsRuntime_.PopPreloadObj(key, moduleObj) ? std::move(moduleObj) : jsRuntime_.LoadModule(
223         moduleName, srcPath, abilityInfo->hapPath, abilityInfo->compileMode == AppExecFwk::CompileMode::ES_MODULE,
224         false, abilityInfo->srcEntrance);
225 }
226 
SetAbilityContext(std::shared_ptr<AbilityInfo> abilityInfo,std::shared_ptr<AAFwk::Want> want,const std::string & moduleName,const std::string & srcPath)227 void JsUIAbility::SetAbilityContext(std::shared_ptr<AbilityInfo> abilityInfo,
228     std::shared_ptr<AAFwk::Want> want, const std::string &moduleName, const std::string &srcPath)
229 {
230     TAG_LOGI(AAFwkTag::UIABILITY, "called");
231     HandleScope handleScope(jsRuntime_);
232     auto env = jsRuntime_.GetNapiEnv();
233     UpdateAbilityObj(abilityInfo, moduleName, srcPath);
234     if (jsAbilityObj_ == nullptr || abilityContext_ == nullptr || want == nullptr) {
235         TAG_LOGE(AAFwkTag::UIABILITY, "null jsAbilityObj_ or abilityContext_ or want");
236         return;
237     }
238     napi_value obj = jsAbilityObj_->GetNapiValue();
239     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
240         TAG_LOGE(AAFwkTag::UIABILITY, "check type failed");
241         return;
242     }
243     napi_value contextObj = nullptr;
244     int32_t screenMode = want->GetIntParam(AAFwk::SCREEN_MODE_KEY, AAFwk::ScreenMode::IDLE_SCREEN_MODE);
245     CreateJSContext(env, contextObj, screenMode);
246     CHECK_POINTER(shellContextRef_);
247     contextObj = shellContextRef_->GetNapiValue();
248     if (!CheckTypeForNapiValue(env, contextObj, napi_object)) {
249         TAG_LOGE(AAFwkTag::UIABILITY, "get ability native object failed");
250         return;
251     }
252     auto workContext = new (std::nothrow) std::weak_ptr<AbilityRuntime::AbilityContext>(abilityContext_);
253     CHECK_POINTER(workContext);
254     screenModePtr_ = std::make_shared<int32_t>(screenMode);
255     auto workScreenMode = new (std::nothrow) std::weak_ptr<int32_t>(screenModePtr_);
256     if (workScreenMode == nullptr) {
257         TAG_LOGE(AAFwkTag::UIABILITY, "workScreenMode nullptr");
258         delete workContext;
259         return;
260     }
261     napi_coerce_to_native_binding_object(
262         env, contextObj, DetachCallbackFunc, AttachJsAbilityContext, workContext, workScreenMode);
263     abilityContext_->Bind(jsRuntime_, shellContextRef_.get());
264     napi_set_named_property(env, obj, "context", contextObj);
265     TAG_LOGD(AAFwkTag::UIABILITY, "set ability context");
266     if (abilityRecovery_ != nullptr) {
267         abilityRecovery_->SetJsAbility(reinterpret_cast<uintptr_t>(workContext));
268     }
269     napi_status status = napi_wrap(env, contextObj, workContext,
270         [](napi_env, void *data, void *hint) {
271             TAG_LOGD(AAFwkTag::UIABILITY, "finalizer for weak_ptr ability context is called");
272             delete static_cast<std::weak_ptr<AbilityRuntime::AbilityContext> *>(data);
273             delete static_cast<std::weak_ptr<int32_t> *>(hint);
274         }, workScreenMode, nullptr);
275     if (status != napi_ok && workContext != nullptr) {
276         TAG_LOGE(AAFwkTag::UIABILITY, "napi_wrap Failed: %{public}d", status);
277         delete workContext;
278         return;
279     }
280 
281     TAG_LOGI(AAFwkTag::UIABILITY, "End");
282 }
283 
CreateJSContext(napi_env env,napi_value & contextObj,int32_t screenMode)284 void JsUIAbility::CreateJSContext(napi_env env, napi_value &contextObj, int32_t screenMode)
285 {
286     if (screenMode == AAFwk::IDLE_SCREEN_MODE) {
287         contextObj = CreateJsAbilityContext(env, abilityContext_);
288         CHECK_POINTER(contextObj);
289         shellContextRef_ = std::shared_ptr<NativeReference>(JsRuntime::LoadSystemModuleByEngine(
290             env, "application.AbilityContext", &contextObj, 1).release());
291     } else {
292         contextObj = JsEmbeddableUIAbilityContext::CreateJsEmbeddableUIAbilityContext(env,
293             abilityContext_, nullptr, screenMode);
294         CHECK_POINTER(contextObj);
295         shellContextRef_ = std::shared_ptr<NativeReference>(JsRuntime::LoadSystemModuleByEngine(
296             env, "application.EmbeddableUIAbilityContext", &contextObj, 1).release());
297     }
298 }
299 
OnStart(const Want & want,sptr<AAFwk::SessionInfo> sessionInfo)300 void JsUIAbility::OnStart(const Want &want, sptr<AAFwk::SessionInfo> sessionInfo)
301 {
302     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
303     TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str());
304     UIAbility::OnStart(want, sessionInfo);
305 
306     if (!jsAbilityObj_) {
307         TAG_LOGE(AAFwkTag::UIABILITY, "not found Ability.js");
308         return;
309     }
310 
311     HandleScope handleScope(jsRuntime_);
312     auto env = jsRuntime_.GetNapiEnv();
313 
314     napi_value obj = jsAbilityObj_->GetNapiValue();
315     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
316         TAG_LOGE(AAFwkTag::UIABILITY, "get ability object failed");
317         return;
318     }
319 
320     napi_value jsWant = OHOS::AppExecFwk::WrapWant(env, want);
321     if (jsWant == nullptr) {
322         TAG_LOGE(AAFwkTag::UIABILITY, "null jsWant");
323         return;
324     }
325 
326     napi_set_named_property(env, obj, "launchWant", jsWant);
327     napi_set_named_property(env, obj, "lastRequestWant", jsWant);
328     auto launchParam = GetLaunchParam();
329     if (InsightIntentExecuteParam::IsInsightIntentExecute(want)) {
330         launchParam.launchReason = AAFwk::LaunchReason::LAUNCHREASON_INSIGHT_INTENT;
331     }
332     napi_value argv[] = {
333         jsWant,
334         CreateJsLaunchParam(env, launchParam),
335     };
336     std::string methodName = "OnStart";
337 
338     auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
339     if (applicationContext != nullptr) {
340         applicationContext->DispatchOnAbilityWillCreate(jsAbilityObj_);
341     }
342 
343     AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
344     CallObjectMethod("onCreate", argv, ArraySize(argv));
345     AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
346 
347     auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
348     if (delegator) {
349         TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformStart");
350         delegator->PostPerformStart(CreateADelegatorAbilityProperty());
351     }
352 
353     applicationContext = AbilityRuntime::Context::GetApplicationContext();
354     if (applicationContext != nullptr) {
355         applicationContext->DispatchOnAbilityCreate(jsAbilityObj_);
356     }
357     TAG_LOGD(AAFwkTag::UIABILITY, "end");
358 }
359 
AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState state,const std::string & methodName) const360 void JsUIAbility::AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState state, const std::string &methodName) const
361 {
362     FreezeUtil::LifecycleFlow flow = { AbilityContext::token_, state };
363     auto entry = std::string("JsUIAbility::") + methodName + "; the " + methodName + " begin.";
364     FreezeUtil::GetInstance().AddLifecycleEvent(flow, entry);
365 }
366 
AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState state,const std::string & methodName) const367 void JsUIAbility::AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState state, const std::string &methodName) const
368 {
369     FreezeUtil::LifecycleFlow flow = { AbilityContext::token_, state };
370     auto entry = std::string("JsUIAbility::") + methodName + "; the " + methodName + " end.";
371     FreezeUtil::GetInstance().AddLifecycleEvent(flow, entry);
372 }
373 
OnShare(WantParams & wantParam)374 int32_t JsUIAbility::OnShare(WantParams &wantParam)
375 {
376     TAG_LOGD(AAFwkTag::UIABILITY, "called");
377     HandleScope handleScope(jsRuntime_);
378     auto env = jsRuntime_.GetNapiEnv();
379     if (jsAbilityObj_ == nullptr) {
380         TAG_LOGE(AAFwkTag::UIABILITY, "null ability object");
381         return ERR_INVALID_VALUE;
382     }
383     napi_value obj = jsAbilityObj_->GetNapiValue();
384     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
385         TAG_LOGE(AAFwkTag::UIABILITY, "ability napi value failed");
386         return ERR_INVALID_VALUE;
387     }
388 
389     napi_value jsWantParams = OHOS::AppExecFwk::WrapWantParams(env, wantParam);
390     napi_value argv[] = {
391         jsWantParams,
392     };
393     CallObjectMethod("onShare", argv, ArraySize(argv));
394     OHOS::AppExecFwk::UnwrapWantParams(env, jsWantParams, wantParam);
395     TAG_LOGD(AAFwkTag::UIABILITY, "end");
396     return ERR_OK;
397 }
398 
OnStop()399 void JsUIAbility::OnStop()
400 {
401     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
402     TAG_LOGD(AAFwkTag::UIABILITY, "called");
403     if (abilityContext_) {
404         TAG_LOGD(AAFwkTag::UIABILITY, "set terminating true");
405         abilityContext_->SetTerminating(true);
406     }
407     UIAbility::OnStop();
408     HandleScope handleScope(jsRuntime_);
409     auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
410     if (applicationContext != nullptr) {
411         applicationContext->DispatchOnAbilityWillDestroy(jsAbilityObj_);
412     }
413     CallObjectMethod("onDestroy");
414     OnStopCallback();
415     TAG_LOGD(AAFwkTag::UIABILITY, "end");
416 }
417 
OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> * callbackInfo,bool & isAsyncCallback)418 void JsUIAbility::OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo, bool &isAsyncCallback)
419 {
420     if (callbackInfo == nullptr) {
421         isAsyncCallback = false;
422         OnStop();
423         return;
424     }
425 
426     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
427     TAG_LOGD(AAFwkTag::UIABILITY, "Begin");
428     if (abilityContext_) {
429         TAG_LOGD(AAFwkTag::UIABILITY, "set terminating true");
430         abilityContext_->SetTerminating(true);
431     }
432 
433     UIAbility::OnStop();
434 
435     HandleScope handleScope(jsRuntime_);
436     auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
437     if (applicationContext != nullptr) {
438         applicationContext->DispatchOnAbilityWillDestroy(jsAbilityObj_);
439     }
440     napi_value result = CallObjectMethod("onDestroy", nullptr, 0, true);
441     if (!CheckPromise(result)) {
442         OnStopCallback();
443         isAsyncCallback = false;
444         return;
445     }
446 
447     std::weak_ptr<UIAbility> weakPtr = shared_from_this();
448     auto asyncCallback = [abilityWeakPtr = weakPtr]() {
449         auto ability = abilityWeakPtr.lock();
450         if (ability == nullptr) {
451             TAG_LOGE(AAFwkTag::UIABILITY, "null ability");
452             return;
453         }
454         ability->OnStopCallback();
455     };
456     callbackInfo->Push(asyncCallback);
457     isAsyncCallback = CallPromise(result, callbackInfo);
458     if (!isAsyncCallback) {
459         TAG_LOGE(AAFwkTag::UIABILITY, "call promise failed");
460         OnStopCallback();
461     }
462     TAG_LOGD(AAFwkTag::UIABILITY, "end");
463 }
464 
OnStopCallback()465 void JsUIAbility::OnStopCallback()
466 {
467     auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
468     if (delegator) {
469         TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformStop");
470         delegator->PostPerformStop(CreateADelegatorAbilityProperty());
471     }
472 
473     bool ret = ConnectionManager::GetInstance().DisconnectCaller(AbilityContext::token_);
474     if (ret) {
475         ConnectionManager::GetInstance().ReportConnectionLeakEvent(getpid(), gettid());
476         TAG_LOGD(AAFwkTag::UIABILITY, "the service connection is not disconnected");
477     }
478 
479     auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
480     if (applicationContext != nullptr) {
481         applicationContext->DispatchOnAbilityDestroy(jsAbilityObj_);
482     }
483 }
484 
485 #ifdef SUPPORT_GRAPHICS
OnSceneCreated()486 void JsUIAbility::OnSceneCreated()
487 {
488     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
489     TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str());
490     UIAbility::OnSceneCreated();
491     auto jsAppWindowStage = CreateAppWindowStage();
492     if (jsAppWindowStage == nullptr) {
493         TAG_LOGE(AAFwkTag::UIABILITY, "null jsAppWindowStage");
494         return;
495     }
496 
497     HandleScope handleScope(jsRuntime_);
498     UpdateJsWindowStage(jsAppWindowStage->GetNapiValue());
499     napi_value argv[] = {jsAppWindowStage->GetNapiValue()};
500     jsWindowStageObj_ = std::shared_ptr<NativeReference>(jsAppWindowStage.release());
501     auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
502     if (applicationContext != nullptr) {
503         applicationContext->DispatchOnWindowStageWillCreate(jsAbilityObj_, jsWindowStageObj_);
504     }
505     {
506         HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, "onWindowStageCreate");
507         std::string methodName = "OnSceneCreated";
508         AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
509         CallObjectMethod("onWindowStageCreate", argv, ArraySize(argv));
510         AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
511     }
512 
513     auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
514     if (delegator) {
515         TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformScenceCreated");
516         delegator->PostPerformScenceCreated(CreateADelegatorAbilityProperty());
517     }
518 
519     applicationContext = AbilityRuntime::Context::GetApplicationContext();
520     if (applicationContext != nullptr) {
521         applicationContext->DispatchOnWindowStageCreate(jsAbilityObj_, jsWindowStageObj_);
522     }
523 
524     TAG_LOGD(AAFwkTag::UIABILITY, "end");
525 }
526 
OnSceneRestored()527 void JsUIAbility::OnSceneRestored()
528 {
529     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
530     UIAbility::OnSceneRestored();
531     TAG_LOGD(AAFwkTag::UIABILITY, "called");
532     HandleScope handleScope(jsRuntime_);
533     auto jsAppWindowStage = CreateAppWindowStage();
534     if (jsAppWindowStage == nullptr) {
535         TAG_LOGE(AAFwkTag::UIABILITY, "null jsAppWindowStage");
536         return;
537     }
538     UpdateJsWindowStage(jsAppWindowStage->GetNapiValue());
539     napi_value argv[] = {jsAppWindowStage->GetNapiValue()};
540     jsWindowStageObj_ = std::shared_ptr<NativeReference>(jsAppWindowStage.release());
541     auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
542     if (applicationContext != nullptr) {
543         applicationContext->DispatchOnWindowStageWillRestore(jsAbilityObj_, jsWindowStageObj_);
544     }
545     CallObjectMethod("onWindowStageRestore", argv, ArraySize(argv));
546     if (applicationContext != nullptr) {
547         applicationContext->DispatchOnWindowStageRestore(jsAbilityObj_, jsWindowStageObj_);
548     }
549 
550     auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
551     if (delegator) {
552         TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformScenceRestored");
553         delegator->PostPerformScenceRestored(CreateADelegatorAbilityProperty());
554     }
555 }
556 
OnSceneWillDestroy()557 void JsUIAbility::OnSceneWillDestroy()
558 {
559     TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str());
560     HandleScope handleScope(jsRuntime_);
561     if (jsWindowStageObj_ == nullptr) {
562         TAG_LOGE(AAFwkTag::UIABILITY, "null jsWindowStageObj_");
563         return;
564     }
565     napi_value argv[] = {jsWindowStageObj_->GetNapiValue()};
566     {
567         HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, "onWindowStageWillDestroy");
568         std::string methodName = "onWindowStageWillDestroy";
569         CallObjectMethod("onWindowStageWillDestroy", argv, ArraySize(argv));
570     }
571 }
572 
onSceneDestroyed()573 void JsUIAbility::onSceneDestroyed()
574 {
575     TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str());
576     UIAbility::onSceneDestroyed();
577 
578     auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
579     if (applicationContext != nullptr) {
580         applicationContext->DispatchOnWindowStageWillDestroy(jsAbilityObj_, jsWindowStageObj_);
581     }
582     HandleScope handleScope(jsRuntime_);
583     UpdateJsWindowStage(nullptr);
584     CallObjectMethod("onWindowStageDestroy");
585 
586     if (scene_ != nullptr) {
587         auto window = scene_->GetMainWindow();
588         if (window != nullptr) {
589             TAG_LOGD(AAFwkTag::UIABILITY, "unRegisterDisplaymovelistener");
590             window->UnregisterDisplayMoveListener(abilityDisplayMoveListener_);
591         }
592     }
593 
594     auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
595     if (delegator) {
596         TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformScenceDestroyed");
597         delegator->PostPerformScenceDestroyed(CreateADelegatorAbilityProperty());
598     }
599 
600     applicationContext = AbilityRuntime::Context::GetApplicationContext();
601     if (applicationContext != nullptr) {
602         applicationContext->DispatchOnWindowStageDestroy(jsAbilityObj_, jsWindowStageObj_);
603     }
604     TAG_LOGD(AAFwkTag::UIABILITY, "end");
605 }
606 
OnForeground(const Want & want)607 void JsUIAbility::OnForeground(const Want &want)
608 {
609     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
610     TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str());
611     if (abilityInfo_) {
612         jsRuntime_.UpdateModuleNameAndAssetPath(abilityInfo_->moduleName);
613     }
614 
615     UIAbility::OnForeground(want);
616     if (CheckIsSilentForeground()) {
617         TAG_LOGD(AAFwkTag::UIABILITY, "silent foreground, do not call 'onForeground'");
618         return;
619     }
620     CallOnForegroundFunc(want);
621 }
622 
CallOnForegroundFunc(const Want & want)623 void JsUIAbility::CallOnForegroundFunc(const Want &want)
624 {
625     HandleScope handleScope(jsRuntime_);
626     auto env = jsRuntime_.GetNapiEnv();
627     if (jsAbilityObj_ == nullptr) {
628         TAG_LOGE(AAFwkTag::UIABILITY, "null jsAbilityObj_");
629         return;
630     }
631     napi_value obj = jsAbilityObj_->GetNapiValue();
632     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
633         TAG_LOGE(AAFwkTag::UIABILITY, "get Ability object failed");
634         return;
635     }
636 
637     napi_value jsWant = OHOS::AppExecFwk::WrapWant(env, want);
638     if (jsWant == nullptr) {
639         TAG_LOGE(AAFwkTag::UIABILITY, "null jsWant");
640         return;
641     }
642 
643     auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
644     if (applicationContext != nullptr) {
645         applicationContext->DispatchOnAbilityWillForeground(jsAbilityObj_);
646     }
647 
648     napi_set_named_property(env, obj, "lastRequestWant", jsWant);
649     std::string methodName = "OnForeground";
650     AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
651     CallObjectMethod("onForeground", &jsWant, 1);
652     AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
653 
654     auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
655     if (delegator) {
656         TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformForeground");
657         delegator->PostPerformForeground(CreateADelegatorAbilityProperty());
658     }
659 
660     applicationContext = AbilityRuntime::Context::GetApplicationContext();
661     if (applicationContext != nullptr) {
662         applicationContext->DispatchOnAbilityForeground(jsAbilityObj_);
663     }
664     TAG_LOGD(AAFwkTag::UIABILITY, "end");
665 }
666 
OnBackground()667 void JsUIAbility::OnBackground()
668 {
669     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
670     TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str());
671     auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
672     if (applicationContext != nullptr) {
673         applicationContext->DispatchOnAbilityWillBackground(jsAbilityObj_);
674     }
675     std::string methodName = "OnBackground";
676     HandleScope handleScope(jsRuntime_);
677     AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::BACKGROUND, methodName);
678     CallObjectMethod("onBackground");
679     AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::BACKGROUND, methodName);
680 
681     UIAbility::OnBackground();
682 
683     auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
684     if (delegator) {
685         TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformBackground");
686         delegator->PostPerformBackground(CreateADelegatorAbilityProperty());
687     }
688 
689     applicationContext = AbilityRuntime::Context::GetApplicationContext();
690     if (applicationContext != nullptr) {
691         applicationContext->DispatchOnAbilityBackground(jsAbilityObj_);
692     }
693     TAG_LOGD(AAFwkTag::UIABILITY, "end");
694 }
695 
OnBackPress()696 bool JsUIAbility::OnBackPress()
697 {
698     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
699     TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str());
700     UIAbility::OnBackPress();
701     HandleScope handleScope(jsRuntime_);
702     auto env = jsRuntime_.GetNapiEnv();
703     napi_value jsValue = CallObjectMethod("onBackPressed", nullptr, 0, true, false);
704     bool defaultRet = BackPressDefaultValue();
705     if (jsValue == nullptr) {
706         TAG_LOGD(AAFwkTag::UIABILITY, "null jsValue, return defaultRet %{public}d", defaultRet);
707         return defaultRet;
708     }
709     bool ret = defaultRet;
710     if (!ConvertFromJsValue(env, jsValue, ret)) {
711         TAG_LOGE(AAFwkTag::UIABILITY, "get js value failed");
712         return defaultRet;
713     }
714     TAG_LOGD(AAFwkTag::UIABILITY, "end ret: %{public}d", ret);
715     return ret;
716 }
717 
OnPrepareTerminate()718 bool JsUIAbility::OnPrepareTerminate()
719 {
720     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
721     TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str());
722     UIAbility::OnPrepareTerminate();
723     HandleScope handleScope(jsRuntime_);
724     auto env = jsRuntime_.GetNapiEnv();
725     napi_value jsValue = CallObjectMethod("onPrepareToTerminate", nullptr, 0, true);
726     bool ret = false;
727     if (!ConvertFromJsValue(env, jsValue, ret)) {
728         TAG_LOGE(AAFwkTag::UIABILITY, "get js value failed");
729         return false;
730     }
731     TAG_LOGD(AAFwkTag::UIABILITY, "end ret: %{public}d", ret);
732     return ret;
733 }
734 
CreateAppWindowStage()735 std::unique_ptr<NativeReference> JsUIAbility::CreateAppWindowStage()
736 {
737     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
738     HandleScope handleScope(jsRuntime_);
739     auto env = jsRuntime_.GetNapiEnv();
740     napi_value jsWindowStage = Rosen::CreateJsWindowStage(env, GetScene());
741     if (jsWindowStage == nullptr) {
742         TAG_LOGE(AAFwkTag::UIABILITY, "create jsWindowSatge failed");
743         return nullptr;
744     }
745     return JsRuntime::LoadSystemModuleByEngine(env, "application.WindowStage", &jsWindowStage, 1);
746 }
747 
GetPageStackFromWant(const Want & want,std::string & pageStack)748 void JsUIAbility::GetPageStackFromWant(const Want &want, std::string &pageStack)
749 {
750     auto stringObj = AAFwk::IString::Query(want.GetParams().GetParam(PAGE_STACK_PROPERTY_NAME));
751     if (stringObj != nullptr) {
752         pageStack = AAFwk::String::Unbox(stringObj);
753     }
754 }
755 
IsRestorePageStack(const Want & want)756 bool JsUIAbility::IsRestorePageStack(const Want &want)
757 {
758     return want.GetBoolParam(SUPPORT_CONTINUE_PAGE_STACK_PROPERTY_NAME, true);
759 }
760 
RestorePageStack(const Want & want)761 void JsUIAbility::RestorePageStack(const Want &want)
762 {
763     if (IsRestorePageStack(want)) {
764         std::string pageStack;
765         GetPageStackFromWant(want, pageStack);
766         HandleScope handleScope(jsRuntime_);
767         auto env = jsRuntime_.GetNapiEnv();
768         if (abilityContext_->GetContentStorage()) {
769             scene_->GetMainWindow()->NapiSetUIContent(pageStack, env,
770                 abilityContext_->GetContentStorage()->GetNapiValue(), Rosen::BackupAndRestoreType::CONTINUATION);
771         } else {
772             TAG_LOGE(AAFwkTag::UIABILITY, "null content storage");
773         }
774     }
775 }
776 
AbilityContinuationOrRecover(const Want & want)777 void JsUIAbility::AbilityContinuationOrRecover(const Want &want)
778 {
779     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
780     // multi-instance ability continuation
781     TAG_LOGD(AAFwkTag::UIABILITY, "launch reason: %{public}d", launchParam_.launchReason);
782     if (IsRestoredInContinuation()) {
783         RestorePageStack(want);
784         OnSceneRestored();
785         NotifyContinuationResult(want, true);
786     } else if (ShouldRecoverState(want)) {
787         std::string pageStack = abilityRecovery_->GetSavedPageStack(AppExecFwk::StateReason::DEVELOPER_REQUEST);
788         HandleScope handleScope(jsRuntime_);
789         auto env = jsRuntime_.GetNapiEnv();
790         auto mainWindow = scene_->GetMainWindow();
791         if (mainWindow != nullptr) {
792             mainWindow->NapiSetUIContent(pageStack, env, abilityContext_->GetContentStorage()->GetNapiValue(),
793                 Rosen::BackupAndRestoreType::APP_RECOVERY);
794         } else {
795             TAG_LOGE(AAFwkTag::UIABILITY, "null MainWindow");
796         }
797         OnSceneRestored();
798     } else {
799         if (ShouldDefaultRecoverState(want) && abilityRecovery_ != nullptr && scene_ != nullptr) {
800             TAG_LOGD(AAFwkTag::UIABILITY, "need restore");
801             std::string pageStack = abilityRecovery_->GetSavedPageStack(AppExecFwk::StateReason::DEVELOPER_REQUEST);
802             auto mainWindow = scene_->GetMainWindow();
803             if (!pageStack.empty() && mainWindow != nullptr) {
804                 mainWindow->SetRestoredRouterStack(pageStack);
805             }
806         }
807         OnSceneCreated();
808     }
809 }
810 
DoOnForeground(const Want & want)811 void JsUIAbility::DoOnForeground(const Want &want)
812 {
813     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
814     if (scene_ == nullptr) {
815         if ((abilityContext_ == nullptr) || (sceneListener_ == nullptr)) {
816             TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext or sceneListener_");
817             return;
818         }
819         DoOnForegroundForSceneIsNull(want);
820     } else {
821         auto window = scene_->GetMainWindow();
822         if (window != nullptr && want.HasParameter(Want::PARAM_RESV_WINDOW_MODE)) {
823             auto windowMode = want.GetIntParam(
824                 Want::PARAM_RESV_WINDOW_MODE, AAFwk::AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_UNDEFINED);
825             window->SetWindowMode(static_cast<Rosen::WindowMode>(windowMode));
826             windowMode_ = windowMode;
827             TAG_LOGD(AAFwkTag::UIABILITY, "set window mode: %{public}d", windowMode);
828         }
829     }
830 
831     auto window = scene_->GetMainWindow();
832     if (window != nullptr && securityFlag_) {
833         window->SetSystemPrivacyMode(true);
834     }
835 
836     if (CheckIsSilentForeground()) {
837         TAG_LOGI(AAFwkTag::UIABILITY, "silent foreground, do not show window");
838         return;
839     }
840 
841     TAG_LOGD(AAFwkTag::UIABILITY, "move scene to foreground, sceneFlag_: %{public}d", UIAbility::sceneFlag_);
842     AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, METHOD_NAME);
843     scene_->GoForeground(UIAbility::sceneFlag_);
844     TAG_LOGD(AAFwkTag::UIABILITY, "end");
845 }
846 
DoOnForegroundForSceneIsNull(const Want & want)847 void JsUIAbility::DoOnForegroundForSceneIsNull(const Want &want)
848 {
849     scene_ = std::make_shared<Rosen::WindowScene>();
850     int32_t displayId = static_cast<int32_t>(Rosen::DisplayManager::GetInstance().GetDefaultDisplayId());
851     if (setting_ != nullptr) {
852         std::string strDisplayId = setting_->GetProperty(OHOS::AppExecFwk::AbilityStartSetting::WINDOW_DISPLAY_ID_KEY);
853         std::regex formatRegex("[0-9]{0,9}$");
854         std::smatch sm;
855         bool flag = std::regex_match(strDisplayId, sm, formatRegex);
856         if (flag && !strDisplayId.empty()) {
857             displayId = strtol(strDisplayId.c_str(), nullptr, BASE_DISPLAY_ID_NUM);
858             TAG_LOGD(AAFwkTag::UIABILITY, "displayId: %{public}d", displayId);
859         } else {
860             TAG_LOGE(AAFwkTag::UIABILITY, "formatRegex: [%{public}s] failed", strDisplayId.c_str());
861         }
862     }
863     auto option = GetWindowOption(want);
864     Rosen::WMError ret = Rosen::WMError::WM_OK;
865     auto sessionToken = GetSessionToken();
866     auto identityToken = GetIdentityToken();
867     if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled() && sessionToken != nullptr) {
868         abilityContext_->SetWeakSessionToken(sessionToken);
869         ret = scene_->Init(displayId, abilityContext_, sceneListener_, option, sessionToken, identityToken);
870     } else {
871         ret = scene_->Init(displayId, abilityContext_, sceneListener_, option);
872     }
873     if (ret != Rosen::WMError::WM_OK) {
874         TAG_LOGE(AAFwkTag::UIABILITY, "init window scene failed");
875         FreezeUtil::LifecycleFlow flow = { AbilityContext::token_, FreezeUtil::TimeoutState::FOREGROUND };
876         FreezeUtil::GetInstance().AppendLifecycleEvent(flow,
877             std::string("ERROR JsUIAbility::DoOnForegroundForSceneIsNull: ") + std::to_string(static_cast<int>(ret)));
878         return;
879     }
880 
881     AbilityContinuationOrRecover(want);
882     auto window = scene_->GetMainWindow();
883     if (window) {
884         TAG_LOGD(AAFwkTag::UIABILITY, "registerDisplayMoveListener, windowId: %{public}d", window->GetWindowId());
885         abilityDisplayMoveListener_ = new AbilityDisplayMoveListener(weak_from_this());
886         if (abilityDisplayMoveListener_ == nullptr) {
887             TAG_LOGE(AAFwkTag::UIABILITY, "null abilityDisplayMoveListener_");
888             return;
889         }
890         window->RegisterDisplayMoveListener(abilityDisplayMoveListener_);
891     }
892 }
893 
RequestFocus(const Want & want)894 void JsUIAbility::RequestFocus(const Want &want)
895 {
896     TAG_LOGI(AAFwkTag::UIABILITY, "called");
897     if (scene_ == nullptr) {
898         TAG_LOGE(AAFwkTag::UIABILITY, "null scene_");
899         return;
900     }
901     auto window = scene_->GetMainWindow();
902     if (window != nullptr && want.HasParameter(Want::PARAM_RESV_WINDOW_MODE)) {
903         auto windowMode = want.GetIntParam(
904             Want::PARAM_RESV_WINDOW_MODE, AAFwk::AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_UNDEFINED);
905         window->SetWindowMode(static_cast<Rosen::WindowMode>(windowMode));
906         TAG_LOGD(AAFwkTag::UIABILITY, "set window mode: %{public}d", windowMode);
907     }
908     AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, METHOD_NAME);
909     scene_->GoForeground(UIAbility::sceneFlag_);
910     TAG_LOGI(AAFwkTag::UIABILITY, "end");
911 }
912 
ContinuationRestore(const Want & want)913 void JsUIAbility::ContinuationRestore(const Want &want)
914 {
915     TAG_LOGD(AAFwkTag::UIABILITY, "called");
916     if (!IsRestoredInContinuation() || scene_ == nullptr) {
917         TAG_LOGE(AAFwkTag::UIABILITY, "is not in continuation or null scene_");
918         return;
919     }
920     RestorePageStack(want);
921     OnSceneRestored();
922     NotifyContinuationResult(want, true);
923 }
924 
GetJsWindowStage()925 std::shared_ptr<NativeReference> JsUIAbility::GetJsWindowStage()
926 {
927     TAG_LOGD(AAFwkTag::UIABILITY, "called");
928     if (jsWindowStageObj_ == nullptr) {
929         TAG_LOGE(AAFwkTag::UIABILITY, "null jsWindowStageObj_");
930     }
931     return jsWindowStageObj_;
932 }
933 
GetJsRuntime()934 const JsRuntime &JsUIAbility::GetJsRuntime()
935 {
936     return jsRuntime_;
937 }
938 
ExecuteInsightIntentRepeateForeground(const Want & want,const std::shared_ptr<InsightIntentExecuteParam> & executeParam,std::unique_ptr<InsightIntentExecutorAsyncCallback> callback)939 void JsUIAbility::ExecuteInsightIntentRepeateForeground(const Want &want,
940     const std::shared_ptr<InsightIntentExecuteParam> &executeParam,
941     std::unique_ptr<InsightIntentExecutorAsyncCallback> callback)
942 {
943     TAG_LOGD(AAFwkTag::UIABILITY, "called");
944     if (executeParam == nullptr) {
945         TAG_LOGW(AAFwkTag::UIABILITY, "invalid param");
946         RequestFocus(want);
947         InsightIntentExecutorMgr::TriggerCallbackInner(std::move(callback), ERR_OK);
948         return;
949     }
950 
951     auto asyncCallback = [weak = weak_from_this(), want](InsightIntentExecuteResult result) {
952         TAG_LOGD(AAFwkTag::UIABILITY, "request focus");
953         auto ability = weak.lock();
954         if (ability == nullptr) {
955             TAG_LOGE(AAFwkTag::UIABILITY, "null ability");
956             return;
957         }
958         ability->RequestFocus(want);
959     };
960     callback->Push(asyncCallback);
961 
962     InsightIntentExecutorInfo executeInfo;
963     auto ret = GetInsightIntentExecutorInfo(want, executeParam, executeInfo);
964     if (!ret) {
965         TAG_LOGE(AAFwkTag::UIABILITY, "get intentExecutor failed");
966         InsightIntentExecutorMgr::TriggerCallbackInner(std::move(callback),
967             static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_PARAM));
968         return;
969     }
970 
971     ret = DelayedSingleton<InsightIntentExecutorMgr>::GetInstance()->ExecuteInsightIntent(
972         jsRuntime_, executeInfo, std::move(callback));
973     if (!ret) {
974         // callback has removed, release in insight intent executor.
975         TAG_LOGE(AAFwkTag::UIABILITY, "execute insightIntent failed");
976     }
977 }
978 
ExecuteInsightIntentMoveToForeground(const Want & want,const std::shared_ptr<InsightIntentExecuteParam> & executeParam,std::unique_ptr<InsightIntentExecutorAsyncCallback> callback)979 void JsUIAbility::ExecuteInsightIntentMoveToForeground(const Want &want,
980     const std::shared_ptr<InsightIntentExecuteParam> &executeParam,
981     std::unique_ptr<InsightIntentExecutorAsyncCallback> callback)
982 {
983     TAG_LOGD(AAFwkTag::UIABILITY, "called");
984     if (executeParam == nullptr) {
985         TAG_LOGW(AAFwkTag::UIABILITY, "param invalid");
986         OnForeground(want);
987         InsightIntentExecutorMgr::TriggerCallbackInner(std::move(callback), ERR_OK);
988         return;
989     }
990 
991     if (abilityInfo_) {
992         jsRuntime_.UpdateModuleNameAndAssetPath(abilityInfo_->moduleName);
993     }
994     UIAbility::OnForeground(want);
995 
996     auto asyncCallback = [weak = weak_from_this(), want](InsightIntentExecuteResult result) {
997         TAG_LOGD(AAFwkTag::UIABILITY, "begin call onForeground");
998         auto ability = weak.lock();
999         if (ability == nullptr) {
1000             TAG_LOGE(AAFwkTag::UIABILITY, "null ability");
1001             return;
1002         }
1003         ability->CallOnForegroundFunc(want);
1004     };
1005     callback->Push(asyncCallback);
1006 
1007     InsightIntentExecutorInfo executeInfo;
1008     auto ret = GetInsightIntentExecutorInfo(want, executeParam, executeInfo);
1009     if (!ret) {
1010         TAG_LOGE(AAFwkTag::UIABILITY, "get intentExecutor failed");
1011         InsightIntentExecutorMgr::TriggerCallbackInner(std::move(callback),
1012             static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_PARAM));
1013         return;
1014     }
1015 
1016     ret = DelayedSingleton<InsightIntentExecutorMgr>::GetInstance()->ExecuteInsightIntent(
1017         jsRuntime_, executeInfo, std::move(callback));
1018     if (!ret) {
1019         // callback has removed, release in insight intent executor.
1020         TAG_LOGE(AAFwkTag::UIABILITY, "execute insightIntent failed");
1021     }
1022 }
1023 
ExecuteInsightIntentBackground(const Want & want,const std::shared_ptr<InsightIntentExecuteParam> & executeParam,std::unique_ptr<InsightIntentExecutorAsyncCallback> callback)1024 void JsUIAbility::ExecuteInsightIntentBackground(const Want &want,
1025     const std::shared_ptr<InsightIntentExecuteParam> &executeParam,
1026     std::unique_ptr<InsightIntentExecutorAsyncCallback> callback)
1027 {
1028     TAG_LOGD(AAFwkTag::UIABILITY, "called");
1029     if (executeParam == nullptr) {
1030         TAG_LOGW(AAFwkTag::UIABILITY, "invalid executeParam");
1031         InsightIntentExecutorMgr::TriggerCallbackInner(std::move(callback), ERR_OK);
1032         return;
1033     }
1034 
1035     if (abilityInfo_) {
1036         jsRuntime_.UpdateModuleNameAndAssetPath(abilityInfo_->moduleName);
1037     }
1038 
1039     InsightIntentExecutorInfo executeInfo;
1040     auto ret = GetInsightIntentExecutorInfo(want, executeParam, executeInfo);
1041     if (!ret) {
1042         TAG_LOGE(AAFwkTag::UIABILITY, "get intentExecutor failed");
1043         InsightIntentExecutorMgr::TriggerCallbackInner(std::move(callback),
1044             static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_PARAM));
1045         return;
1046     }
1047 
1048     ret = DelayedSingleton<InsightIntentExecutorMgr>::GetInstance()->ExecuteInsightIntent(
1049         jsRuntime_, executeInfo, std::move(callback));
1050     if (!ret) {
1051         // callback has removed, release in insight intent executor.
1052         TAG_LOGE(AAFwkTag::UIABILITY, "execute insightIntent failed");
1053     }
1054 }
1055 
GetInsightIntentExecutorInfo(const Want & want,const std::shared_ptr<InsightIntentExecuteParam> & executeParam,InsightIntentExecutorInfo & executeInfo)1056 bool JsUIAbility::GetInsightIntentExecutorInfo(const Want &want,
1057     const std::shared_ptr<InsightIntentExecuteParam> &executeParam,
1058     InsightIntentExecutorInfo& executeInfo)
1059 {
1060     TAG_LOGD(AAFwkTag::UIABILITY, "called");
1061 
1062     auto context = GetAbilityContext();
1063     if (executeParam == nullptr || context == nullptr || abilityInfo_ == nullptr) {
1064         TAG_LOGE(AAFwkTag::UIABILITY, "param invalid");
1065         return false;
1066     }
1067 
1068     if (executeParam->executeMode_ == AppExecFwk::ExecuteMode::UI_ABILITY_FOREGROUND
1069         && jsWindowStageObj_ == nullptr) {
1070         TAG_LOGE(AAFwkTag::UIABILITY, "param invalid");
1071         return false;
1072     }
1073 
1074     const WantParams &wantParams = want.GetParams();
1075     executeInfo.srcEntry = wantParams.GetStringParam("ohos.insightIntent.srcEntry");
1076     executeInfo.hapPath = abilityInfo_->hapPath;
1077     executeInfo.esmodule = abilityInfo_->compileMode == AppExecFwk::CompileMode::ES_MODULE;
1078     executeInfo.windowMode = windowMode_;
1079     executeInfo.token = context->GetToken();
1080     if (jsWindowStageObj_ != nullptr) {
1081         executeInfo.pageLoader = jsWindowStageObj_;
1082     }
1083     executeInfo.executeParam = executeParam;
1084     return true;
1085 }
1086 #endif
1087 
OnContinue(WantParams & wantParams)1088 int32_t JsUIAbility::OnContinue(WantParams &wantParams)
1089 {
1090     TAG_LOGI(AAFwkTag::UIABILITY, "called");
1091     HandleScope handleScope(jsRuntime_);
1092     auto env = jsRuntime_.GetNapiEnv();
1093     if (jsAbilityObj_ == nullptr) {
1094         TAG_LOGE(AAFwkTag::UIABILITY, "null jsAbilityObj_");
1095         return AppExecFwk::ContinuationManagerStage::OnContinueResult::REJECT;
1096     }
1097     napi_value obj = jsAbilityObj_->GetNapiValue();
1098     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
1099         TAG_LOGE(AAFwkTag::UIABILITY, "failed get ability");
1100         return AppExecFwk::ContinuationManagerStage::OnContinueResult::REJECT;
1101     }
1102 
1103     auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
1104     if (applicationContext != nullptr) {
1105         applicationContext->DispatchOnAbilityWillContinue(jsAbilityObj_);
1106     }
1107 
1108     napi_value jsWantParams = OHOS::AppExecFwk::WrapWantParams(env, wantParams);
1109     napi_value result = CallObjectMethod("onContinue", &jsWantParams, 1, true);
1110     int32_t onContinueRes = 0;
1111     if (!CheckPromise(result)) {
1112         if (!ConvertFromJsValue(env, result, onContinueRes)) {
1113             TAG_LOGE(AAFwkTag::UIABILITY, "'onContinue' is not implemented");
1114             return AppExecFwk::ContinuationManagerStage::OnContinueResult::REJECT;
1115         }
1116     } else {
1117         if (!CallPromise(result, onContinueRes)) {
1118             TAG_LOGE(AAFwkTag::UIABILITY, "call promise failed");
1119             return AppExecFwk::ContinuationManagerStage::OnContinueResult::REJECT;
1120         }
1121     }
1122     OHOS::AppExecFwk::UnwrapWantParams(env, jsWantParams, wantParams);
1123     if (applicationContext != nullptr) {
1124         applicationContext->DispatchOnAbilityContinue(jsAbilityObj_);
1125     }
1126     TAG_LOGI(AAFwkTag::UIABILITY, "end");
1127     return onContinueRes;
1128 }
1129 
OnSaveState(int32_t reason,WantParams & wantParams)1130 int32_t JsUIAbility::OnSaveState(int32_t reason, WantParams &wantParams)
1131 {
1132     HandleScope handleScope(jsRuntime_);
1133     auto env = jsRuntime_.GetNapiEnv();
1134     if (jsAbilityObj_ == nullptr) {
1135         TAG_LOGE(AAFwkTag::UIABILITY, "null jsAbilityObj_");
1136         return -1;
1137     }
1138     napi_value obj = jsAbilityObj_->GetNapiValue();
1139     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
1140         TAG_LOGE(AAFwkTag::UIABILITY, "failed to get ability object");
1141         return -1;
1142     }
1143 
1144     auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
1145     if (applicationContext != nullptr) {
1146         applicationContext->DispatchOnAbilityWillSaveState(jsAbilityObj_);
1147     }
1148 
1149     napi_value methodOnSaveState = nullptr;
1150     napi_get_named_property(env, obj, "onSaveState", &methodOnSaveState);
1151     if (methodOnSaveState == nullptr) {
1152         TAG_LOGE(AAFwkTag::UIABILITY, "failed to get 'onSaveState' fun");
1153         return -1;
1154     }
1155 
1156     napi_value jsWantParams = OHOS::AppExecFwk::WrapWantParams(env, wantParams);
1157     napi_value jsReason = CreateJsValue(env, reason);
1158     napi_value args[] = { jsReason, jsWantParams };
1159     napi_value result = nullptr;
1160     napi_call_function(env, obj, methodOnSaveState, 2, args, &result); // 2:args size
1161     OHOS::AppExecFwk::UnwrapWantParams(env, jsWantParams, wantParams);
1162 
1163     int32_t numberResult = 0;
1164     if (!ConvertFromJsValue(env, result, numberResult)) {
1165         TAG_LOGE(AAFwkTag::UIABILITY, "no result return from onSaveState");
1166         return -1;
1167     }
1168 
1169     if (applicationContext != nullptr) {
1170         applicationContext->DispatchOnAbilitySaveState(jsAbilityObj_);
1171     }
1172 
1173     return numberResult;
1174 }
1175 
OnConfigurationUpdated(const Configuration & configuration)1176 void JsUIAbility::OnConfigurationUpdated(const Configuration &configuration)
1177 {
1178     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
1179     UIAbility::OnConfigurationUpdated(configuration);
1180     TAG_LOGD(AAFwkTag::UIABILITY, "called");
1181     if (abilityContext_ == nullptr) {
1182         TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext");
1183         return;
1184     }
1185 
1186     HandleScope handleScope(jsRuntime_);
1187     auto env = jsRuntime_.GetNapiEnv();
1188     auto fullConfig = abilityContext_->GetConfiguration();
1189     if (fullConfig == nullptr) {
1190         TAG_LOGE(AAFwkTag::UIABILITY, "null configuration");
1191         return;
1192     }
1193 
1194     TAG_LOGD(AAFwkTag::UIABILITY, "fullConfig: %{public}s", fullConfig->GetName().c_str());
1195     napi_value napiConfiguration = OHOS::AppExecFwk::WrapConfiguration(env, *fullConfig);
1196     CallObjectMethod("onConfigurationUpdated", &napiConfiguration, 1);
1197     CallObjectMethod("onConfigurationUpdate", &napiConfiguration, 1);
1198     JsAbilityContext::ConfigurationUpdated(env, shellContextRef_, fullConfig);
1199 }
1200 
OnMemoryLevel(int level)1201 void JsUIAbility::OnMemoryLevel(int level)
1202 {
1203     UIAbility::OnMemoryLevel(level);
1204     TAG_LOGD(AAFwkTag::UIABILITY, "called");
1205 
1206     HandleScope handleScope(jsRuntime_);
1207     auto env = jsRuntime_.GetNapiEnv();
1208     if (jsAbilityObj_ == nullptr) {
1209         TAG_LOGE(AAFwkTag::UIABILITY, "null jsAbilityObj_");
1210         return;
1211     }
1212     napi_value obj = jsAbilityObj_->GetNapiValue();
1213     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
1214         TAG_LOGE(AAFwkTag::UIABILITY, "get ability object failed");
1215         return;
1216     }
1217 
1218     napi_value jslevel = CreateJsValue(env, level);
1219     napi_value argv[] = { jslevel };
1220     CallObjectMethod("onMemoryLevel", argv, ArraySize(argv));
1221 }
1222 
UpdateContextConfiguration()1223 void JsUIAbility::UpdateContextConfiguration()
1224 {
1225     TAG_LOGD(AAFwkTag::UIABILITY, "called");
1226     if (abilityContext_ == nullptr) {
1227         TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext_");
1228         return;
1229     }
1230     HandleScope handleScope(jsRuntime_);
1231     auto env = jsRuntime_.GetNapiEnv();
1232     JsAbilityContext::ConfigurationUpdated(env, shellContextRef_, abilityContext_->GetConfiguration());
1233 }
1234 
OnNewWant(const Want & want)1235 void JsUIAbility::OnNewWant(const Want &want)
1236 {
1237     TAG_LOGD(AAFwkTag::UIABILITY, "called");
1238     UIAbility::OnNewWant(want);
1239 
1240 #ifdef SUPPORT_GRAPHICS
1241     if (scene_) {
1242         scene_->OnNewWant(want);
1243     }
1244 #endif
1245 
1246     HandleScope handleScope(jsRuntime_);
1247     auto env = jsRuntime_.GetNapiEnv();
1248     if (jsAbilityObj_ == nullptr) {
1249         TAG_LOGE(AAFwkTag::UIABILITY, "null jsAbilityObj_");
1250         return;
1251     }
1252     napi_value obj = jsAbilityObj_->GetNapiValue();
1253     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
1254         TAG_LOGE(AAFwkTag::UIABILITY, "ability object failed");
1255         return;
1256     }
1257 
1258     napi_value jsWant = OHOS::AppExecFwk::WrapWant(env, want);
1259     if (jsWant == nullptr) {
1260         TAG_LOGE(AAFwkTag::UIABILITY, "null want");
1261         return;
1262     }
1263 
1264     auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
1265     if (applicationContext != nullptr) {
1266         applicationContext->DispatchOnWillNewWant(jsAbilityObj_);
1267     }
1268 
1269     napi_set_named_property(env, obj, "lastRequestWant", jsWant);
1270     auto launchParam = GetLaunchParam();
1271     if (InsightIntentExecuteParam::IsInsightIntentExecute(want)) {
1272         launchParam.launchReason = AAFwk::LaunchReason::LAUNCHREASON_INSIGHT_INTENT;
1273     }
1274     napi_value argv[] = {
1275         jsWant,
1276         CreateJsLaunchParam(env, launchParam),
1277     };
1278     std::string methodName = "OnNewWant";
1279     AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
1280     CallObjectMethod("onNewWant", argv, ArraySize(argv));
1281     AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
1282 
1283     applicationContext = AbilityRuntime::Context::GetApplicationContext();
1284     if (applicationContext != nullptr) {
1285         applicationContext->DispatchOnNewWant(jsAbilityObj_);
1286     }
1287     TAG_LOGD(AAFwkTag::UIABILITY, "end");
1288 }
1289 
OnAbilityResult(int requestCode,int resultCode,const Want & resultData)1290 void JsUIAbility::OnAbilityResult(int requestCode, int resultCode, const Want &resultData)
1291 {
1292     TAG_LOGD(AAFwkTag::UIABILITY, "called");
1293     UIAbility::OnAbilityResult(requestCode, resultCode, resultData);
1294     if (abilityContext_ == nullptr) {
1295         TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext_");
1296         return;
1297     }
1298     abilityContext_->OnAbilityResult(requestCode, resultCode, resultData);
1299     TAG_LOGD(AAFwkTag::UIABILITY, "end");
1300 }
1301 
CallRequest()1302 sptr<IRemoteObject> JsUIAbility::CallRequest()
1303 {
1304     TAG_LOGD(AAFwkTag::UIABILITY, "called");
1305     if (jsAbilityObj_ == nullptr) {
1306         TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext_");
1307         return nullptr;
1308     }
1309 
1310     if (remoteCallee_ != nullptr) {
1311         TAG_LOGE(AAFwkTag::UIABILITY, "null remoteCallee_");
1312         return remoteCallee_;
1313     }
1314 
1315     HandleScope handleScope(jsRuntime_);
1316     auto env = jsRuntime_.GetNapiEnv();
1317     auto obj = jsAbilityObj_->GetNapiValue();
1318     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
1319         TAG_LOGE(AAFwkTag::UIABILITY, "null value");
1320         return nullptr;
1321     }
1322 
1323     napi_value method = nullptr;
1324     napi_get_named_property(env, obj, "onCallRequest", &method);
1325     bool isCallable = false;
1326     napi_is_callable(env, method, &isCallable);
1327     if (!isCallable) {
1328         TAG_LOGE(AAFwkTag::UIABILITY, "method: %{public}s", method == nullptr ? "nullptr" : "not func");
1329         return nullptr;
1330     }
1331 
1332     napi_value remoteJsObj = nullptr;
1333     napi_call_function(env, obj, method, 0, nullptr, &remoteJsObj);
1334     if (remoteJsObj == nullptr) {
1335         TAG_LOGE(AAFwkTag::UIABILITY, "null remoteJsObj");
1336         return nullptr;
1337     }
1338 
1339     remoteCallee_ = SetNewRuleFlagToCallee(env, remoteJsObj);
1340     TAG_LOGD(AAFwkTag::UIABILITY, "end");
1341     return remoteCallee_;
1342 }
1343 
CallObjectMethod(const char * name,napi_value const * argv,size_t argc,bool withResult,bool showMethodNotFoundLog)1344 napi_value JsUIAbility::CallObjectMethod(const char *name, napi_value const *argv, size_t argc, bool withResult,
1345     bool showMethodNotFoundLog)
1346 {
1347     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, std::string("CallObjectMethod:") + name);
1348     TAG_LOGD(AAFwkTag::UIABILITY, "name %{public}s", name);
1349     if (jsAbilityObj_ == nullptr) {
1350         TAG_LOGE(AAFwkTag::UIABILITY, "not found ability.js");
1351         return nullptr;
1352     }
1353 
1354     HandleEscape handleEscape(jsRuntime_);
1355     auto env = jsRuntime_.GetNapiEnv();
1356 
1357     napi_value obj = jsAbilityObj_->GetNapiValue();
1358     if (!CheckTypeForNapiValue(env, obj, napi_object)) {
1359         TAG_LOGE(AAFwkTag::UIABILITY, "get ability object failed");
1360         return nullptr;
1361     }
1362 
1363     napi_value methodOnCreate = nullptr;
1364     napi_get_named_property(env, obj, name, &methodOnCreate);
1365     if (methodOnCreate == nullptr) {
1366         if (showMethodNotFoundLog) {
1367             TAG_LOGE(AAFwkTag::UIABILITY, "get '%{public}s' from ability object failed", name);
1368         }
1369         return nullptr;
1370     }
1371     TryCatch tryCatch(env);
1372     if (withResult) {
1373         napi_value result = nullptr;
1374         napi_status withResultStatus = napi_call_function(env, obj, methodOnCreate, argc, argv, &result);
1375         if (withResultStatus != napi_ok) {
1376             TAG_LOGE(AAFwkTag::UIABILITY, "JsUIAbility call js, withResult failed: %{public}d", withResultStatus);
1377         }
1378         if (tryCatch.HasCaught()) {
1379             reinterpret_cast<NativeEngine*>(env)->HandleUncaughtException();
1380         }
1381         return handleEscape.Escape(result);
1382     }
1383     int64_t timeStart = AbilityRuntime::TimeUtil::SystemTimeMillisecond();
1384     napi_status status = napi_call_function(env, obj, methodOnCreate, argc, argv, nullptr);
1385     if (status != napi_ok) {
1386         TAG_LOGE(AAFwkTag::UIABILITY, "JsUIAbility call js, failed: %{public}d", status);
1387     }
1388     int64_t timeEnd = AbilityRuntime::TimeUtil::SystemTimeMillisecond();
1389     if (tryCatch.HasCaught()) {
1390         reinterpret_cast<NativeEngine*>(env)->HandleUncaughtException();
1391     }
1392     TAG_LOGI(AAFwkTag::UIABILITY, "end, name: %{public}s, time: %{public}s",
1393         name, std::to_string(timeEnd - timeStart).c_str());
1394     return nullptr;
1395 }
1396 
CheckPromise(napi_value result)1397 bool JsUIAbility::CheckPromise(napi_value result)
1398 {
1399     if (result == nullptr) {
1400         TAG_LOGE(AAFwkTag::UIABILITY, "null result");
1401         return false;
1402     }
1403     auto env = jsRuntime_.GetNapiEnv();
1404     bool isPromise = false;
1405     napi_is_promise(env, result, &isPromise);
1406     if (!isPromise) {
1407         TAG_LOGD(AAFwkTag::UIABILITY, "result is not promise");
1408         return false;
1409     }
1410     return true;
1411 }
1412 
CallPromise(napi_value result,AppExecFwk::AbilityTransactionCallbackInfo<> * callbackInfo)1413 bool JsUIAbility::CallPromise(napi_value result, AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo)
1414 {
1415     auto env = jsRuntime_.GetNapiEnv();
1416     if (!CheckTypeForNapiValue(env, result, napi_object)) {
1417         TAG_LOGE(AAFwkTag::UIABILITY, "convert native value to NativeObject failed");
1418         return false;
1419     }
1420     napi_value then = nullptr;
1421     napi_get_named_property(env, result, "then", &then);
1422     if (then == nullptr) {
1423         TAG_LOGE(AAFwkTag::UIABILITY, "get property: then failed");
1424         return false;
1425     }
1426     bool isCallable = false;
1427     napi_is_callable(env, then, &isCallable);
1428     if (!isCallable) {
1429         TAG_LOGE(AAFwkTag::UIABILITY, "property then is not callable");
1430         return false;
1431     }
1432     HandleScope handleScope(jsRuntime_);
1433     napi_value promiseCallback = nullptr;
1434     napi_create_function(env, "promiseCallback", strlen("promiseCallback"), PromiseCallback,
1435         callbackInfo, &promiseCallback);
1436     napi_value argv[1] = { promiseCallback };
1437     napi_call_function(env, result, then, 1, argv, nullptr);
1438     TAG_LOGD(AAFwkTag::UIABILITY, "end");
1439     return true;
1440 }
1441 
CallPromise(napi_value result,int32_t & onContinueRes)1442 bool JsUIAbility::CallPromise(napi_value result, int32_t &onContinueRes)
1443 {
1444     auto env = jsRuntime_.GetNapiEnv();
1445     if (!CheckTypeForNapiValue(env, result, napi_object)) {
1446         TAG_LOGE(AAFwkTag::UIABILITY, "convert native value to NativeObject error");
1447         return false;
1448     }
1449     napi_value then = nullptr;
1450     napi_get_named_property(env, result, "then", &then);
1451     if (then == nullptr) {
1452         TAG_LOGE(AAFwkTag::UIABILITY, "null then");
1453         return false;
1454     }
1455     bool isCallable = false;
1456     napi_is_callable(env, then, &isCallable);
1457     if (!isCallable) {
1458         TAG_LOGE(AAFwkTag::UIABILITY, "property then is not callable");
1459         return false;
1460     }
1461 
1462     std::weak_ptr<UIAbility> weakPtr = shared_from_this();
1463     auto asyncCallback = [abilityWeakPtr = weakPtr, this, &onContinueRes](int32_t &result) {
1464         auto ability = abilityWeakPtr.lock();
1465         if (ability == nullptr) {
1466             TAG_LOGE(AAFwkTag::UIABILITY, "null ability");
1467             return;
1468         }
1469         onContinueRes = result;
1470     };
1471     auto *callbackInfo = AppExecFwk::AbilityTransactionCallbackInfo<int32_t>::Create();
1472     if (callbackInfo != nullptr) {
1473         callbackInfo->Push(asyncCallback);
1474     }
1475 
1476     HandleScope handleScope(jsRuntime_);
1477     napi_value promiseCallback = nullptr;
1478     napi_create_function(env, nullptr, NAPI_AUTO_LENGTH, OnContinuePromiseCallback,
1479         callbackInfo, &promiseCallback);
1480     napi_value argv[1] = { promiseCallback };
1481     napi_call_function(env, result, then, 1, argv, nullptr);
1482     TAG_LOGD(AAFwkTag::UIABILITY, "end");
1483     return true;
1484 }
1485 
CreateADelegatorAbilityProperty()1486 std::shared_ptr<AppExecFwk::ADelegatorAbilityProperty> JsUIAbility::CreateADelegatorAbilityProperty()
1487 {
1488     if (abilityContext_ == nullptr) {
1489         TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext_");
1490         return nullptr;
1491     }
1492     auto property = std::make_shared<AppExecFwk::ADelegatorAbilityProperty>();
1493     property->token_ = abilityContext_->GetToken();
1494     property->name_ = GetAbilityName();
1495     property->moduleName_ = GetModuleName();
1496     if (GetApplicationInfo() == nullptr || GetApplicationInfo()->bundleName.empty()) {
1497         property->fullName_ = GetAbilityName();
1498     } else {
1499         std::string::size_type pos = GetAbilityName().find(GetApplicationInfo()->bundleName);
1500         if (pos == std::string::npos || pos != 0) {
1501             property->fullName_ = GetApplicationInfo()->bundleName + "." + GetAbilityName();
1502         } else {
1503             property->fullName_ = GetAbilityName();
1504         }
1505     }
1506     property->lifecycleState_ = GetState();
1507     property->object_ = jsAbilityObj_;
1508     return property;
1509 }
1510 
Dump(const std::vector<std::string> & params,std::vector<std::string> & info)1511 void JsUIAbility::Dump(const std::vector<std::string> &params, std::vector<std::string> &info)
1512 {
1513     UIAbility::Dump(params, info);
1514     TAG_LOGD(AAFwkTag::UIABILITY, "called");
1515     HandleScope handleScope(jsRuntime_);
1516     auto env = jsRuntime_.GetNapiEnv();
1517     // create js array object of params
1518     napi_value argv[] = { CreateNativeArray(env, params) };
1519     napi_value dumpInfo = CallObjectMethod("dump", argv, ArraySize(argv), true);
1520     napi_value onDumpInfo = CallObjectMethod("onDump", argv, ArraySize(argv), true);
1521 
1522     GetDumpInfo(env, dumpInfo, onDumpInfo, info);
1523     TAG_LOGD(AAFwkTag::UIABILITY, "dump info size: %{public}zu", info.size());
1524 }
1525 
GetDumpInfo(napi_env env,napi_value dumpInfo,napi_value onDumpInfo,std::vector<std::string> & info)1526 void JsUIAbility::GetDumpInfo(
1527     napi_env env, napi_value dumpInfo, napi_value onDumpInfo, std::vector<std::string> &info)
1528 {
1529     if (dumpInfo != nullptr) {
1530         uint32_t len = 0;
1531         napi_get_array_length(env, dumpInfo, &len);
1532         for (uint32_t i = 0; i < len; i++) {
1533             std::string dumpInfoStr;
1534             napi_value element = nullptr;
1535             napi_get_element(env, dumpInfo, i, &element);
1536             if (!ConvertFromJsValue(env, element, dumpInfoStr)) {
1537                 TAG_LOGE(AAFwkTag::UIABILITY, "parse dumpInfoStr failed");
1538                 return;
1539             }
1540             info.push_back(dumpInfoStr);
1541         }
1542     }
1543 
1544     if (onDumpInfo != nullptr) {
1545         uint32_t len = 0;
1546         napi_get_array_length(env, onDumpInfo, &len);
1547         for (uint32_t i = 0; i < len; i++) {
1548             std::string dumpInfoStr;
1549             napi_value element = nullptr;
1550             napi_get_element(env, onDumpInfo, i, &element);
1551             if (!ConvertFromJsValue(env, element, dumpInfoStr)) {
1552                 TAG_LOGE(AAFwkTag::UIABILITY, "invalid dumpInfoStr from onDumpInfoNative");
1553                 return;
1554             }
1555             info.push_back(dumpInfoStr);
1556         }
1557     }
1558 }
1559 
GetJsAbility()1560 std::shared_ptr<NativeReference> JsUIAbility::GetJsAbility()
1561 {
1562     TAG_LOGD(AAFwkTag::UIABILITY, "called");
1563     if (jsAbilityObj_ == nullptr) {
1564         TAG_LOGE(AAFwkTag::UIABILITY, "null jsAbilityObj_");
1565     }
1566     return jsAbilityObj_;
1567 }
1568 
SetNewRuleFlagToCallee(napi_env env,napi_value remoteJsObj)1569 sptr<IRemoteObject> JsUIAbility::SetNewRuleFlagToCallee(napi_env env, napi_value remoteJsObj)
1570 {
1571     if (!CheckTypeForNapiValue(env, remoteJsObj, napi_object)) {
1572         TAG_LOGE(AAFwkTag::UIABILITY, "null callee");
1573         return nullptr;
1574     }
1575     napi_value setFlagMethod = nullptr;
1576     napi_get_named_property(env, remoteJsObj, "setNewRuleFlag", &setFlagMethod);
1577     bool isCallable = false;
1578     napi_is_callable(env, setFlagMethod, &isCallable);
1579     if (!isCallable) {
1580         TAG_LOGE(AAFwkTag::UIABILITY, "setFlagMethod: %{public}s", setFlagMethod == nullptr ? "nullptr" : "not func");
1581         return nullptr;
1582     }
1583     auto flag = CreateJsValue(env, IsUseNewStartUpRule());
1584     napi_value argv[1] = { flag };
1585     napi_call_function(env, remoteJsObj, setFlagMethod, 1, argv, nullptr);
1586 
1587     auto remoteObj = NAPI_ohos_rpc_getNativeRemoteObject(env, remoteJsObj);
1588     if (remoteObj == nullptr) {
1589         TAG_LOGE(AAFwkTag::UIABILITY, "null remoteObj");
1590         return nullptr;
1591     }
1592     return remoteObj;
1593 }
1594 
UpdateJsWindowStage(napi_value windowStage)1595 void JsUIAbility::UpdateJsWindowStage(napi_value windowStage)
1596 {
1597     TAG_LOGD(AAFwkTag::UIABILITY, "called");
1598     if (shellContextRef_ == nullptr) {
1599         TAG_LOGE(AAFwkTag::UIABILITY, "null shellContextRef_");
1600         return;
1601     }
1602     napi_value contextObj = shellContextRef_->GetNapiValue();
1603     napi_env env = jsRuntime_.GetNapiEnv();
1604     if (!CheckTypeForNapiValue(env, contextObj, napi_object)) {
1605         TAG_LOGE(AAFwkTag::UIABILITY, "get native context obj failed");
1606         return;
1607     }
1608     if (windowStage == nullptr) {
1609         TAG_LOGE(AAFwkTag::UIABILITY, "null windowStage");
1610         napi_set_named_property(env, contextObj, "windowStage", CreateJsUndefined(env));
1611         return;
1612     }
1613     TAG_LOGD(AAFwkTag::UIABILITY, "set context windowStage");
1614     napi_set_named_property(env, contextObj, "windowStage", windowStage);
1615 }
1616 
CheckSatisfyTargetAPIVersion(int32_t version)1617 bool JsUIAbility::CheckSatisfyTargetAPIVersion(int32_t version)
1618 {
1619     auto applicationInfo = GetApplicationInfo();
1620     if (!applicationInfo) {
1621         TAG_LOGE(AAFwkTag::UIABILITY, "null targetAPIVersion");
1622         return false;
1623     }
1624     TAG_LOGD(AAFwkTag::UIABILITY, "targetAPIVersion: %{public}d", applicationInfo->apiTargetVersion);
1625     return applicationInfo->apiTargetVersion % API_VERSION_MOD >= version;
1626 }
1627 
BackPressDefaultValue()1628 bool JsUIAbility::BackPressDefaultValue()
1629 {
1630     return CheckSatisfyTargetAPIVersion(API12) ? true : false;
1631 }
1632 } // namespace AbilityRuntime
1633 } // namespace OHOS
1634