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