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