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> ¶ms, 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