1 /*
2 * Copyright (c) 2023-2025 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_manager_client.h"
24 #include "ability_recovery.h"
25 #include "ability_start_setting.h"
26 #include "app_recovery.h"
27 #include "connection_manager.h"
28 #include "context/application_context.h"
29 #include "context/context.h"
30 #include "display_util.h"
31 #include "hilog_tag_wrapper.h"
32 #include "hitrace_meter.h"
33 #include "if_system_ability_manager.h"
34 #include "insight_intent_executor_info.h"
35 #include "insight_intent_executor_mgr.h"
36 #include "insight_intent_execute_param.h"
37 #include "js_ability_context.h"
38 #include "js_data_struct_converter.h"
39 #include "js_insight_intent_page.h"
40 #include "js_runtime.h"
41 #include "js_runtime_utils.h"
42 #include "js_utils.h"
43 #ifdef SUPPORT_SCREEN
44 #include "distributed_client.h"
45 #include "js_window_stage.h"
46 #include "scene_board_judgement.h"
47 #endif
48 #include "ohos_application.h"
49 #include "napi_common_configuration.h"
50 #include "napi_common_want.h"
51 #include "napi_remote_object.h"
52 #include "string_wrapper.h"
53 #include "system_ability_definition.h"
54 #include "time_util.h"
55
56 namespace OHOS {
57 namespace AbilityRuntime {
58 namespace {
59 #ifdef SUPPORT_GRAPHICS
60 const std::string PAGE_STACK_PROPERTY_NAME = "pageStack";
61 const std::string SUPPORT_CONTINUE_PAGE_STACK_PROPERTY_NAME = "ohos.extra.param.key.supportContinuePageStack";
62 const std::string METHOD_NAME = "WindowScene::GoForeground";
63 #endif
64 // Numerical base (radix) that determines the valid characters and their interpretation.
65 #ifdef SUPPORT_SCREEN
66 const int32_t BASE_DISPLAY_ID_NUM (10);
67 constexpr const char* IS_CALLING_FROM_DMS = "supportCollaborativeCallingFromDmsInAAFwk";
68 constexpr const char* SUPPORT_COLLABORATE_INDEX = "ohos.extra.param.key.supportCollaborateIndex";
69 constexpr const char* COLLABORATE_KEY = "ohos.dms.collabToken";
70 enum CollaborateResult {
71 ACCEPT = 0,
72 REJECT = 1,
73 ON_COLLABORATE_NOT_IMPLEMENTED = 10,
74 ON_COLLABORATE_ERR = 11,
75 };
76 #endif
77 constexpr const char* REUSING_WINDOW = "ohos.ability_runtime.reusing_window";
78 constexpr const int32_t API12 = 12;
79 constexpr const int32_t API_VERSION_MOD = 100;
80 constexpr const int32_t PROMISE_CALLBACK_PARAM_NUM = 2;
81 constexpr const int32_t CALL_BACK_ERROR = -1;
82
PromiseCallback(napi_env env,napi_callback_info info)83 napi_value PromiseCallback(napi_env env, napi_callback_info info)
84 {
85 void *data = nullptr;
86 NAPI_CALL_NO_THROW(napi_get_cb_info(env, info, nullptr, nullptr, nullptr, &data), nullptr);
87 auto *callbackInfo = static_cast<AppExecFwk::AbilityTransactionCallbackInfo<> *>(data);
88 callbackInfo->Call();
89 AppExecFwk::AbilityTransactionCallbackInfo<>::Destroy(callbackInfo);
90 data = nullptr;
91 return nullptr;
92 }
93
OnContinuePromiseCallback(napi_env env,napi_callback_info info)94 napi_value OnContinuePromiseCallback(napi_env env, napi_callback_info info)
95 {
96 void *data = nullptr;
97 size_t argc = 1;
98 napi_value argv = {nullptr};
99 NAPI_CALL_NO_THROW(napi_get_cb_info(env, info, &argc, &argv, nullptr, &data), nullptr);
100 int32_t onContinueRes = 0;
101 if (!ConvertFromJsValue(env, argv, onContinueRes)) {
102 TAG_LOGE(AAFwkTag::UIABILITY, "get value failed");
103 onContinueRes = AppExecFwk::ContinuationManagerStage::OnContinueResult::ON_CONTINUE_ERR;
104 }
105 auto *callbackInfo = static_cast<AppExecFwk::AbilityTransactionCallbackInfo<int32_t> *>(data);
106 callbackInfo->Call(onContinueRes);
107 data = nullptr;
108
109 return nullptr;
110 }
111
OnPrepareTerminatePromiseCallback(napi_env env,napi_callback_info info)112 napi_value OnPrepareTerminatePromiseCallback(napi_env env, napi_callback_info info)
113 {
114 TAG_LOGI(AAFwkTag::UIABILITY, "OnPrepareTerminatePromiseCallback begin");
115 void *data = nullptr;
116 size_t argc = ARGC_MAX_COUNT;
117 napi_value argv[ARGC_MAX_COUNT] = {nullptr};
118 NAPI_CALL_NO_THROW(napi_get_cb_info(env, info, &argc, argv, nullptr, &data), nullptr);
119 auto *callbackInfo = static_cast<AppExecFwk::AbilityTransactionCallbackInfo<bool> *>(data);
120 bool prepareTermination = false;
121 if (callbackInfo == nullptr || (argc > 0 && !ConvertFromJsValue(env, argv[0], prepareTermination))) {
122 TAG_LOGE(AAFwkTag::UIABILITY, "null callbackInfo or unwrap prepareTermination result failed");
123 return nullptr;
124 }
125 callbackInfo->Call(prepareTermination);
126 AppExecFwk::AbilityTransactionCallbackInfo<bool>::Destroy(callbackInfo);
127 data = nullptr;
128 TAG_LOGI(AAFwkTag::UIABILITY, "OnPrepareTerminatePromiseCallback end");
129 return nullptr;
130 }
131
OnSaveStateCallback(napi_env env,napi_callback_info info)132 napi_value OnSaveStateCallback(napi_env env, napi_callback_info info)
133 {
134 void *data = nullptr;
135 size_t argc = ARGC_MAX_COUNT;
136 napi_value argv[ARGC_MAX_COUNT] = {nullptr};
137 NAPI_CALL_NO_THROW(napi_get_cb_info(env, info, &argc, argv, nullptr, &data), nullptr);
138 auto callInfo = static_cast<CallOnSaveStateInfo *>(data);
139 if (callInfo == nullptr) {
140 TAG_LOGE(AAFwkTag::UIABILITY, "null info");
141 return nullptr;
142 }
143 int32_t status = 0;
144 if (callInfo->callbackInfo == nullptr || (argc > 0 && !ConvertFromJsValue(env, argv[0], status))) {
145 TAG_LOGE(AAFwkTag::UIABILITY, "null callbackInfo or unwrap onSaveState result failed");
146 return nullptr;
147 }
148 AppExecFwk::OnSaveStateResult saveStateResult = {status, callInfo->wantParams, callInfo->reason};
149 callInfo->callbackInfo->Call(saveStateResult);
150 AppExecFwk::AbilityTransactionCallbackInfo<AppExecFwk::OnSaveStateResult>::Destroy(callInfo->callbackInfo);
151 data = nullptr;
152 return nullptr;
153 }
154
AttachJsAbilityContext(napi_env env,void * value,void *)155 napi_value AttachJsAbilityContext(napi_env env, void *value, void *)
156 {
157 TAG_LOGD(AAFwkTag::UIABILITY, "called");
158 if (value == nullptr) {
159 TAG_LOGE(AAFwkTag::UIABILITY, "invalid params");
160 return nullptr;
161 }
162 auto ptr = reinterpret_cast<std::weak_ptr<AbilityRuntime::AbilityContext> *>(value)->lock();
163 if (ptr == nullptr) {
164 TAG_LOGE(AAFwkTag::UIABILITY, "null ptr");
165 return nullptr;
166 }
167 std::shared_ptr<NativeReference> systemModule = nullptr;
168 int32_t screenMode = ptr->GetScreenMode();
169 if (screenMode == AAFwk::IDLE_SCREEN_MODE) {
170 auto uiAbiObject = CreateJsAbilityContext(env, ptr);
171 CHECK_POINTER_AND_RETURN(uiAbiObject, nullptr);
172 systemModule = std::shared_ptr<NativeReference>(JsRuntime::LoadSystemModuleByEngine(env,
173 "application.AbilityContext", &uiAbiObject, 1).release());
174 } else {
175 auto emUIObject = JsEmbeddableUIAbilityContext::CreateJsEmbeddableUIAbilityContext(env,
176 ptr, nullptr, screenMode);
177 CHECK_POINTER_AND_RETURN(emUIObject, nullptr);
178 systemModule = std::shared_ptr<NativeReference>(JsRuntime::LoadSystemModuleByEngine(env,
179 "application.EmbeddableUIAbilityContext", &emUIObject, 1).release());
180 }
181 CHECK_POINTER_AND_RETURN(systemModule, nullptr);
182 auto contextObj = systemModule->GetNapiValue();
183 napi_coerce_to_native_binding_object(env, contextObj, DetachCallbackFunc, AttachJsAbilityContext, value, nullptr);
184 auto workContext = new (std::nothrow) std::weak_ptr<AbilityRuntime::AbilityContext>(ptr);
185 if (workContext != nullptr) {
186 napi_status status = napi_wrap(env, contextObj, workContext,
187 [](napi_env, void* data, void*) {
188 TAG_LOGD(AAFwkTag::UIABILITY, "finalizer for weak_ptr ability context is called");
189 delete static_cast<std::weak_ptr<AbilityRuntime::AbilityContext> *>(data);
190 },
191 nullptr, nullptr);
192 if (status != napi_ok && workContext != nullptr) {
193 TAG_LOGE(AAFwkTag::UIABILITY, "napi_wrap Failed: %{public}d", status);
194 delete workContext;
195 return nullptr;
196 }
197 }
198 return contextObj;
199 }
200
BindContext(napi_env env,std::unique_ptr<NativeReference> contextRef,JsRuntime & jsRuntime,const std::shared_ptr<AbilityRuntime::AbilityContext> abilityContext)201 void BindContext(napi_env env, std::unique_ptr<NativeReference> contextRef, JsRuntime& jsRuntime,
202 const std::shared_ptr<AbilityRuntime::AbilityContext> abilityContext)
203 {
204 CHECK_POINTER(contextRef);
205 napi_value contextObj = contextRef->GetNapiValue();
206 if (!CheckTypeForNapiValue(env, contextObj, napi_object)) {
207 TAG_LOGE(AAFwkTag::UIABILITY, "get ability native object failed");
208 return;
209 }
210 auto workContext = new (std::nothrow) std::weak_ptr<AbilityRuntime::AbilityContext>(abilityContext);
211 CHECK_POINTER(workContext);
212 napi_coerce_to_native_binding_object(
213 env, contextObj, DetachCallbackFunc, AttachJsAbilityContext, workContext, nullptr);
214 abilityContext->Bind(jsRuntime, contextRef.release());
215 napi_wrap(
216 env, contextObj, workContext,
217 [](napi_env, void* data, void* hint) {
218 TAG_LOGD(AAFwkTag::UIABILITY, "finalizer for weak_ptr ability context is called");
219 delete static_cast<std::weak_ptr<AbilityRuntime::AbilityContext>*>(data);
220 },
221 nullptr, nullptr);
222 }
223 } // namespace
224
Create(const std::unique_ptr<Runtime> & runtime)225 UIAbility *JsUIAbility::Create(const std::unique_ptr<Runtime> &runtime)
226 {
227 return new (std::nothrow) JsUIAbility(static_cast<JsRuntime &>(*runtime));
228 }
229
JsUIAbility(JsRuntime & jsRuntime)230 JsUIAbility::JsUIAbility(JsRuntime &jsRuntime) : jsRuntime_(jsRuntime)
231 {
232 TAG_LOGD(AAFwkTag::UIABILITY, "called");
233 }
234
~JsUIAbility()235 JsUIAbility::~JsUIAbility()
236 {
237 // maintenance log
238 TAG_LOGI(AAFwkTag::UIABILITY, "called");
239 if (abilityContext_ != nullptr) {
240 abilityContext_->Unbind();
241 }
242
243 jsRuntime_.FreeNativeReference(std::move(jsAbilityObj_));
244 jsRuntime_.FreeNativeReference(std::move(shellContextRef_));
245 #ifdef SUPPORT_SCREEN
246 jsRuntime_.FreeNativeReference(std::move(jsWindowStageObj_));
247 #endif
248 }
249
Init(std::shared_ptr<AppExecFwk::AbilityLocalRecord> record,const std::shared_ptr<OHOSApplication> application,std::shared_ptr<AbilityHandler> & handler,const sptr<IRemoteObject> & token)250 void JsUIAbility::Init(std::shared_ptr<AppExecFwk::AbilityLocalRecord> record,
251 const std::shared_ptr<OHOSApplication> application, std::shared_ptr<AbilityHandler> &handler,
252 const sptr<IRemoteObject> &token)
253 {
254 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
255 if (record == nullptr) {
256 TAG_LOGE(AAFwkTag::UIABILITY, "null localAbilityRecord");
257 return;
258 }
259 auto abilityInfo = record->GetAbilityInfo();
260 if (abilityInfo == nullptr) {
261 TAG_LOGE(AAFwkTag::UIABILITY, "null abilityInfo");
262 return;
263 }
264 UIAbility::Init(record, application, handler, token);
265 #ifdef SUPPORT_GRAPHICS
266 if (abilityContext_ != nullptr) {
267 AppExecFwk::AppRecovery::GetInstance().AddAbility(
268 shared_from_this(), abilityContext_->GetAbilityInfo(), abilityContext_->GetToken());
269 }
270 #endif
271 std::string srcPath(abilityInfo->package);
272 if (!abilityInfo->isModuleJson) {
273 /* temporary compatibility api8 + config.json */
274 srcPath.append("/assets/js/");
275 if (!abilityInfo->srcPath.empty()) {
276 srcPath.append(abilityInfo->srcPath);
277 }
278 srcPath.append("/").append(abilityInfo->name).append(".abc");
279 } else {
280 if (abilityInfo->srcEntrance.empty()) {
281 TAG_LOGE(AAFwkTag::UIABILITY, "empty srcEntrance");
282 return;
283 }
284 srcPath.append("/");
285 srcPath.append(abilityInfo->srcEntrance);
286 srcPath.erase(srcPath.rfind("."));
287 srcPath.append(".abc");
288 TAG_LOGD(AAFwkTag::UIABILITY, "jsAbility srcPath: %{public}s", srcPath.c_str());
289 }
290
291 std::string moduleName(abilityInfo->moduleName);
292 moduleName.append("::").append(abilityInfo->name);
293
294 SetAbilityContext(abilityInfo, record->GetWant(), moduleName, srcPath);
295 }
296
UpdateAbilityObj(std::shared_ptr<AbilityInfo> abilityInfo,const std::string & moduleName,const std::string & srcPath)297 void JsUIAbility::UpdateAbilityObj(std::shared_ptr<AbilityInfo> abilityInfo,
298 const std::string &moduleName, const std::string &srcPath)
299 {
300 std::string key = moduleName + "::" + srcPath;
301 std::unique_ptr<NativeReference> moduleObj = nullptr;
302 jsAbilityObj_ = jsRuntime_.PopPreloadObj(key, moduleObj) ? std::move(moduleObj) : jsRuntime_.LoadModule(
303 moduleName, srcPath, abilityInfo->hapPath, abilityInfo->compileMode == AppExecFwk::CompileMode::ES_MODULE,
304 false, abilityInfo->srcEntrance);
305 }
306
CreateAndBindContext(const std::shared_ptr<AbilityRuntime::AbilityContext> & abilityContext,const std::unique_ptr<Runtime> & runtime)307 void JsUIAbility::CreateAndBindContext(const std::shared_ptr<AbilityRuntime::AbilityContext> &abilityContext,
308 const std::unique_ptr<Runtime>& runtime)
309 {
310 TAG_LOGD(AAFwkTag::UIABILITY, "called");
311 if (abilityContext == nullptr) {
312 TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext");
313 return;
314 }
315 if (runtime == nullptr) {
316 TAG_LOGE(AAFwkTag::UIABILITY, "null runtime");
317 return;
318 }
319 if (runtime->GetLanguage() != Runtime::Language::JS) {
320 TAG_LOGE(AAFwkTag::UIABILITY, "wrong runtime language");
321 return;
322 }
323 auto& jsRuntime = static_cast<JsRuntime&>(*runtime);
324 HandleScope handleScope(jsRuntime);
325 napi_env env = jsRuntime.GetNapiEnv();
326 if (env == nullptr) {
327 TAG_LOGE(AAFwkTag::UIABILITY, "null env");
328 return;
329 }
330 int32_t screenMode = abilityContext->GetScreenMode();
331
332 std::unique_ptr<NativeReference> contextRef;
333 if (screenMode == AAFwk::IDLE_SCREEN_MODE) {
334 napi_value contextObj = CreateJsAbilityContext(env, abilityContext);
335 CHECK_POINTER(contextObj);
336 contextRef = JsRuntime::LoadSystemModuleByEngine(env, "application.AbilityContext", &contextObj, 1);
337 } else {
338 napi_value contextObj =
339 JsEmbeddableUIAbilityContext::CreateJsEmbeddableUIAbilityContext(env, abilityContext, nullptr, screenMode);
340 CHECK_POINTER(contextObj);
341 contextRef = JsRuntime::LoadSystemModuleByEngine(env, "application.EmbeddableUIAbilityContext", &contextObj, 1);
342 }
343
344 BindContext(env, std::move(contextRef), jsRuntime, abilityContext);
345 }
346
SetAbilityContext(std::shared_ptr<AbilityInfo> abilityInfo,std::shared_ptr<AAFwk::Want> want,const std::string & moduleName,const std::string & srcPath)347 void JsUIAbility::SetAbilityContext(std::shared_ptr<AbilityInfo> abilityInfo,
348 std::shared_ptr<AAFwk::Want> want, const std::string &moduleName, const std::string &srcPath)
349 {
350 TAG_LOGI(AAFwkTag::UIABILITY, "called");
351 HandleScope handleScope(jsRuntime_);
352 auto env = jsRuntime_.GetNapiEnv();
353 UpdateAbilityObj(abilityInfo, moduleName, srcPath);
354 if (jsAbilityObj_ == nullptr || abilityContext_ == nullptr || want == nullptr) {
355 TAG_LOGE(AAFwkTag::UIABILITY, "null jsAbilityObj_ or abilityContext_ or want");
356 return;
357 }
358 reusingWindow_ = want->GetBoolParam(REUSING_WINDOW, false);
359 napi_value obj = jsAbilityObj_->GetNapiValue();
360 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
361 TAG_LOGE(AAFwkTag::UIABILITY, "check type failed");
362 return;
363 }
364 napi_value contextObj = nullptr;
365 int32_t screenMode = want->GetIntParam(AAFwk::SCREEN_MODE_KEY, AAFwk::ScreenMode::IDLE_SCREEN_MODE);
366 abilityContext_->SetScreenMode(screenMode);
367 CreateJSContext(env, contextObj, screenMode);
368 CHECK_POINTER(shellContextRef_);
369 contextObj = shellContextRef_->GetNapiValue();
370 if (!CheckTypeForNapiValue(env, contextObj, napi_object)) {
371 TAG_LOGE(AAFwkTag::UIABILITY, "get ability native object failed");
372 return;
373 }
374 auto workContext = new (std::nothrow) std::weak_ptr<AbilityRuntime::AbilityContext>(abilityContext_);
375 CHECK_POINTER(workContext);
376
377 napi_coerce_to_native_binding_object(
378 env, contextObj, DetachCallbackFunc, AttachJsAbilityContext, workContext, nullptr);
379 abilityContext_->Bind(jsRuntime_, shellContextRef_.get());
380 napi_set_named_property(env, obj, "context", contextObj);
381 TAG_LOGD(AAFwkTag::UIABILITY, "set ability context");
382 if (abilityRecovery_ != nullptr) {
383 abilityRecovery_->SetJsAbility(reinterpret_cast<uintptr_t>(workContext));
384 }
385 napi_status status = napi_wrap(env, contextObj, workContext,
386 [](napi_env, void *data, void *hint) {
387 TAG_LOGD(AAFwkTag::UIABILITY, "finalizer for weak_ptr ability context is called");
388 delete static_cast<std::weak_ptr<AbilityRuntime::AbilityContext> *>(data);
389 }, nullptr, nullptr);
390 if (status != napi_ok && workContext != nullptr) {
391 TAG_LOGE(AAFwkTag::UIABILITY, "napi_wrap Failed: %{public}d", status);
392 delete workContext;
393 return;
394 }
395 TAG_LOGI(AAFwkTag::UIABILITY, "End");
396 }
397
CreateJSContext(napi_env env,napi_value & contextObj,int32_t screenMode)398 void JsUIAbility::CreateJSContext(napi_env env, napi_value &contextObj, int32_t screenMode)
399 {
400 if (screenMode == AAFwk::IDLE_SCREEN_MODE) {
401 contextObj = CreateJsAbilityContext(env, abilityContext_);
402 CHECK_POINTER(contextObj);
403 shellContextRef_ = std::shared_ptr<NativeReference>(JsRuntime::LoadSystemModuleByEngine(
404 env, "application.AbilityContext", &contextObj, 1).release());
405 } else {
406 contextObj = JsEmbeddableUIAbilityContext::CreateJsEmbeddableUIAbilityContext(env,
407 abilityContext_, nullptr, screenMode);
408 CHECK_POINTER(contextObj);
409 shellContextRef_ = std::shared_ptr<NativeReference>(JsRuntime::LoadSystemModuleByEngine(
410 env, "application.EmbeddableUIAbilityContext", &contextObj, 1).release());
411 }
412 }
413
OnStart(const Want & want,sptr<AAFwk::SessionInfo> sessionInfo)414 void JsUIAbility::OnStart(const Want &want, sptr<AAFwk::SessionInfo> sessionInfo)
415 {
416 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
417 TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str());
418 UIAbility::OnStart(want, sessionInfo);
419
420 if (!jsAbilityObj_) {
421 TAG_LOGE(AAFwkTag::UIABILITY, "not found Ability.js");
422 return;
423 }
424
425 HandleScope handleScope(jsRuntime_);
426 auto env = jsRuntime_.GetNapiEnv();
427
428 napi_value obj = jsAbilityObj_->GetNapiValue();
429 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
430 TAG_LOGE(AAFwkTag::UIABILITY, "get ability object failed");
431 return;
432 }
433
434 napi_value jsWant = OHOS::AppExecFwk::WrapWant(env, want);
435 if (jsWant == nullptr) {
436 TAG_LOGE(AAFwkTag::UIABILITY, "null jsWant");
437 return;
438 }
439
440 napi_set_named_property(env, obj, "launchWant", jsWant);
441 napi_set_named_property(env, obj, "lastRequestWant", jsWant);
442 auto launchParam = GetLaunchParam();
443 if (InsightIntentExecuteParam::IsInsightIntentExecute(want)) {
444 launchParam.launchReason = AAFwk::LaunchReason::LAUNCHREASON_INSIGHT_INTENT;
445 }
446 napi_value argv[] = {
447 jsWant,
448 CreateJsLaunchParam(env, launchParam),
449 };
450 std::string methodName = "OnStart";
451
452 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
453 if (applicationContext != nullptr) {
454 applicationContext->DispatchOnAbilityWillCreate(jsAbilityObj_);
455 }
456
457 AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
458 CallObjectMethod("onCreate", argv, ArraySize(argv));
459 AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
460 HandleAbilityDelegatorStart();
461 applicationContext = AbilityRuntime::Context::GetApplicationContext();
462 if (applicationContext != nullptr) {
463 applicationContext->DispatchOnAbilityCreate(jsAbilityObj_);
464 }
465 TAG_LOGD(AAFwkTag::UIABILITY, "end");
466 }
467
HandleAbilityDelegatorStart()468 void JsUIAbility::HandleAbilityDelegatorStart()
469 {
470 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
471 auto property = std::make_shared<AppExecFwk::ADelegatorAbilityProperty>();
472 if (delegator && CreateProperty(abilityContext_, property)) {
473 TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformStart");
474 property->object_ = jsAbilityObj_;
475 delegator->PostPerformStart(property);
476 }
477 }
478
AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState state,const std::string & methodName) const479 void JsUIAbility::AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState state, const std::string &methodName) const
480 {
481 auto entry = std::string("JsUIAbility::") + methodName + " begin";
482 FreezeUtil::GetInstance().AddLifecycleEvent(AbilityContext::token_, entry);
483 }
484
AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState state,const std::string & methodName) const485 void JsUIAbility::AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState state, const std::string &methodName) const
486 {
487 auto entry = std::string("JsUIAbility::") + methodName + " end";
488 FreezeUtil::GetInstance().AddLifecycleEvent(AbilityContext::token_, entry);
489 }
490
OnShare(WantParams & wantParam)491 int32_t JsUIAbility::OnShare(WantParams &wantParam)
492 {
493 TAG_LOGD(AAFwkTag::UIABILITY, "called");
494 HandleScope handleScope(jsRuntime_);
495 auto env = jsRuntime_.GetNapiEnv();
496 if (jsAbilityObj_ == nullptr) {
497 TAG_LOGE(AAFwkTag::UIABILITY, "null jsAbilityObj_");
498 return ERR_INVALID_VALUE;
499 }
500 napi_value obj = jsAbilityObj_->GetNapiValue();
501 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
502 TAG_LOGE(AAFwkTag::UIABILITY, "ability napi value failed");
503 return ERR_INVALID_VALUE;
504 }
505
506 napi_value jsWantParams = OHOS::AppExecFwk::WrapWantParams(env, wantParam);
507 napi_value argv[] = {
508 jsWantParams,
509 };
510 CallObjectMethod("onShare", argv, ArraySize(argv));
511 OHOS::AppExecFwk::UnwrapWantParams(env, jsWantParams, wantParam);
512 TAG_LOGD(AAFwkTag::UIABILITY, "end");
513 return ERR_OK;
514 }
515
OnStop()516 void JsUIAbility::OnStop()
517 {
518 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
519 TAG_LOGD(AAFwkTag::UIABILITY, "called");
520 if (abilityContext_) {
521 TAG_LOGD(AAFwkTag::UIABILITY, "set terminating true");
522 abilityContext_->SetTerminating(true);
523 }
524 UIAbility::OnStop();
525 HandleScope handleScope(jsRuntime_);
526 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
527 if (applicationContext != nullptr) {
528 applicationContext->DispatchOnAbilityWillDestroy(jsAbilityObj_);
529 }
530 CallObjectMethod("onDestroy");
531 OnStopCallback();
532 TAG_LOGD(AAFwkTag::UIABILITY, "end");
533 }
534
OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> * callbackInfo,bool & isAsyncCallback)535 void JsUIAbility::OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo, bool &isAsyncCallback)
536 {
537 if (callbackInfo == nullptr) {
538 isAsyncCallback = false;
539 OnStop();
540 return;
541 }
542
543 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
544 TAG_LOGD(AAFwkTag::UIABILITY, "Begin");
545 if (abilityContext_) {
546 TAG_LOGD(AAFwkTag::UIABILITY, "set terminating true");
547 abilityContext_->SetTerminating(true);
548 }
549
550 UIAbility::OnStop();
551
552 HandleScope handleScope(jsRuntime_);
553 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
554 if (applicationContext != nullptr) {
555 applicationContext->DispatchOnAbilityWillDestroy(jsAbilityObj_);
556 }
557 napi_value result = CallObjectMethod("onDestroy", nullptr, 0, true);
558 if (!CheckPromise(result)) {
559 OnStopCallback();
560 isAsyncCallback = false;
561 return;
562 }
563
564 std::weak_ptr<UIAbility> weakPtr = shared_from_this();
565 auto asyncCallback = [abilityWeakPtr = weakPtr]() {
566 auto ability = abilityWeakPtr.lock();
567 if (ability == nullptr) {
568 TAG_LOGE(AAFwkTag::UIABILITY, "null ability");
569 return;
570 }
571 ability->OnStopCallback();
572 };
573 callbackInfo->Push(asyncCallback);
574 isAsyncCallback = CallPromise(result, callbackInfo);
575 if (!isAsyncCallback) {
576 TAG_LOGE(AAFwkTag::UIABILITY, "call promise failed");
577 OnStopCallback();
578 }
579 TAG_LOGD(AAFwkTag::UIABILITY, "end");
580 }
581
OnStopCallback()582 void JsUIAbility::OnStopCallback()
583 {
584 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
585 auto property = std::make_shared<AppExecFwk::ADelegatorAbilityProperty>();
586 if (delegator && CreateProperty(abilityContext_, property)) {
587 TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformStop");
588 property->object_ = jsAbilityObj_;
589 delegator->PostPerformStop(property);
590 }
591
592 bool ret = ConnectionManager::GetInstance().DisconnectCaller(AbilityContext::token_);
593 if (ret) {
594 ConnectionManager::GetInstance().ReportConnectionLeakEvent(getpid(), gettid());
595 TAG_LOGD(AAFwkTag::UIABILITY, "the service connection is not disconnected");
596 }
597
598 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
599 if (applicationContext != nullptr) {
600 applicationContext->DispatchOnAbilityDestroy(jsAbilityObj_);
601 }
602 }
603
604 #ifdef SUPPORT_SCREEN
OnSceneCreated()605 void JsUIAbility::OnSceneCreated()
606 {
607 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
608 TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str());
609 UIAbility::OnSceneCreated();
610 auto jsAppWindowStage = CreateAppWindowStage();
611 if (jsAppWindowStage == nullptr) {
612 TAG_LOGE(AAFwkTag::UIABILITY, "null jsAppWindowStage");
613 return;
614 }
615
616 HandleScope handleScope(jsRuntime_);
617 UpdateJsWindowStage(jsAppWindowStage->GetNapiValue());
618 napi_value argv[] = {jsAppWindowStage->GetNapiValue()};
619 jsWindowStageObj_ = std::shared_ptr<NativeReference>(jsAppWindowStage.release());
620 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
621 if (applicationContext != nullptr) {
622 applicationContext->DispatchOnWindowStageWillCreate(jsAbilityObj_, jsWindowStageObj_);
623 }
624 {
625 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, "onWindowStageCreate");
626 std::string methodName = "OnSceneCreated";
627 AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
628 CallObjectMethod("onWindowStageCreate", argv, ArraySize(argv));
629 AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
630 }
631
632 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
633 auto property = std::make_shared<AppExecFwk::ADelegatorAbilityProperty>();
634 if (delegator && CreateProperty(abilityContext_, property)) {
635 TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformScenceCreated");
636 property->object_ = jsAbilityObj_;
637 delegator->PostPerformScenceCreated(property);
638 }
639
640 applicationContext = AbilityRuntime::Context::GetApplicationContext();
641 if (applicationContext != nullptr) {
642 applicationContext->DispatchOnWindowStageCreate(jsAbilityObj_, jsWindowStageObj_);
643 }
644
645 TAG_LOGD(AAFwkTag::UIABILITY, "end");
646 }
647
OnSceneRestored()648 void JsUIAbility::OnSceneRestored()
649 {
650 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
651 UIAbility::OnSceneRestored();
652 TAG_LOGD(AAFwkTag::UIABILITY, "called");
653 HandleScope handleScope(jsRuntime_);
654 auto jsAppWindowStage = CreateAppWindowStage();
655 if (jsAppWindowStage == nullptr) {
656 TAG_LOGE(AAFwkTag::UIABILITY, "null jsAppWindowStage");
657 return;
658 }
659 UpdateJsWindowStage(jsAppWindowStage->GetNapiValue());
660 napi_value argv[] = {jsAppWindowStage->GetNapiValue()};
661 jsWindowStageObj_ = std::shared_ptr<NativeReference>(jsAppWindowStage.release());
662 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
663 if (applicationContext != nullptr) {
664 applicationContext->DispatchOnWindowStageWillRestore(jsAbilityObj_, jsWindowStageObj_);
665 }
666 CallObjectMethod("onWindowStageRestore", argv, ArraySize(argv));
667 if (applicationContext != nullptr) {
668 applicationContext->DispatchOnWindowStageRestore(jsAbilityObj_, jsWindowStageObj_);
669 }
670
671 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
672 auto property = std::make_shared<AppExecFwk::ADelegatorAbilityProperty>();
673 if (delegator && CreateProperty(abilityContext_, property)) {
674 TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformScenceRestored");
675 property->object_ = jsAbilityObj_;
676 delegator->PostPerformScenceRestored(property);
677 }
678 }
679
OnSceneWillDestroy()680 void JsUIAbility::OnSceneWillDestroy()
681 {
682 TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str());
683 HandleScope handleScope(jsRuntime_);
684 if (jsWindowStageObj_ == nullptr) {
685 TAG_LOGE(AAFwkTag::UIABILITY, "null jsWindowStageObj_");
686 return;
687 }
688 napi_value argv[] = {jsWindowStageObj_->GetNapiValue()};
689 {
690 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, "onWindowStageWillDestroy");
691 std::string methodName = "onWindowStageWillDestroy";
692 CallObjectMethod("onWindowStageWillDestroy", argv, ArraySize(argv));
693 }
694 }
695
onSceneDestroyed()696 void JsUIAbility::onSceneDestroyed()
697 {
698 TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str());
699 UIAbility::onSceneDestroyed();
700
701 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
702 if (applicationContext != nullptr) {
703 applicationContext->DispatchOnWindowStageWillDestroy(jsAbilityObj_, jsWindowStageObj_);
704 }
705 HandleScope handleScope(jsRuntime_);
706 UpdateJsWindowStage(nullptr);
707 CallObjectMethod("onWindowStageDestroy");
708
709 if (scene_ != nullptr) {
710 auto window = scene_->GetMainWindow();
711 if (window != nullptr) {
712 TAG_LOGD(AAFwkTag::UIABILITY, "unRegisterDisplaymovelistener");
713 window->UnregisterDisplayMoveListener(abilityDisplayMoveListener_);
714 }
715 }
716
717 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
718 auto property = std::make_shared<AppExecFwk::ADelegatorAbilityProperty>();
719 if (delegator && CreateProperty(abilityContext_, property)) {
720 TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformScenceDestroyed");
721 property->object_ = jsAbilityObj_;
722 delegator->PostPerformScenceDestroyed(property);
723 }
724
725 applicationContext = AbilityRuntime::Context::GetApplicationContext();
726 if (applicationContext != nullptr) {
727 applicationContext->DispatchOnWindowStageDestroy(jsAbilityObj_, jsWindowStageObj_);
728 }
729 TAG_LOGD(AAFwkTag::UIABILITY, "end");
730 }
731
OnForeground(const Want & want)732 void JsUIAbility::OnForeground(const Want &want)
733 {
734 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
735 TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str());
736 if (abilityInfo_) {
737 jsRuntime_.UpdateModuleNameAndAssetPath(abilityInfo_->moduleName);
738 }
739
740 UIAbility::OnForeground(want);
741 HandleCollaboration(want);
742
743 if (CheckIsSilentForeground()) {
744 TAG_LOGD(AAFwkTag::UIABILITY, "silent foreground, do not call 'onForeground'");
745 return;
746 }
747 CallOnForegroundFunc(want);
748 }
749
CallOnForegroundFunc(const Want & want)750 void JsUIAbility::CallOnForegroundFunc(const Want &want)
751 {
752 HandleScope handleScope(jsRuntime_);
753 auto env = jsRuntime_.GetNapiEnv();
754 if (jsAbilityObj_ == nullptr) {
755 TAG_LOGE(AAFwkTag::UIABILITY, "null jsAbilityObj_");
756 return;
757 }
758 napi_value obj = jsAbilityObj_->GetNapiValue();
759 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
760 TAG_LOGE(AAFwkTag::UIABILITY, "get Ability object failed");
761 return;
762 }
763
764 napi_value jsWant = OHOS::AppExecFwk::WrapWant(env, want);
765 if (jsWant == nullptr) {
766 TAG_LOGE(AAFwkTag::UIABILITY, "null jsWant");
767 return;
768 }
769
770 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
771 if (applicationContext != nullptr) {
772 applicationContext->DispatchOnAbilityWillForeground(jsAbilityObj_);
773 }
774
775 napi_set_named_property(env, obj, "lastRequestWant", jsWant);
776 std::string methodName = "OnForeground";
777 AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
778 CallObjectMethod("onForeground", &jsWant, 1);
779 AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
780
781 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
782 auto property = std::make_shared<AppExecFwk::ADelegatorAbilityProperty>();
783 if (delegator && CreateProperty(abilityContext_, property)) {
784 TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformForeground");
785 property->object_ = jsAbilityObj_;
786 delegator->PostPerformForeground(property);
787 }
788
789 applicationContext = AbilityRuntime::Context::GetApplicationContext();
790 if (applicationContext != nullptr) {
791 applicationContext->DispatchOnAbilityForeground(jsAbilityObj_);
792 }
793 TAG_LOGD(AAFwkTag::UIABILITY, "end");
794 }
795
OnBackground()796 void JsUIAbility::OnBackground()
797 {
798 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
799 TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str());
800 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
801 if (applicationContext != nullptr) {
802 applicationContext->DispatchOnAbilityWillBackground(jsAbilityObj_);
803 }
804 std::string methodName = "OnBackground";
805 HandleScope handleScope(jsRuntime_);
806 AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::BACKGROUND, methodName);
807 CallObjectMethod("onBackground");
808 AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::BACKGROUND, methodName);
809
810 UIAbility::OnBackground();
811
812 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
813 auto property = std::make_shared<AppExecFwk::ADelegatorAbilityProperty>();
814 if (delegator && CreateProperty(abilityContext_, property)) {
815 TAG_LOGD(AAFwkTag::UIABILITY, "call PostPerformBackground");
816 property->object_ = jsAbilityObj_;
817 delegator->PostPerformBackground(property);
818 }
819
820 applicationContext = AbilityRuntime::Context::GetApplicationContext();
821 if (applicationContext != nullptr) {
822 applicationContext->DispatchOnAbilityBackground(jsAbilityObj_);
823 }
824 auto want = GetWant();
825 if (want != nullptr) {
826 HandleCollaboration(*want);
827 }
828 TAG_LOGD(AAFwkTag::UIABILITY, "end");
829 }
830
OnWillForeground()831 void JsUIAbility::OnWillForeground()
832 {
833 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
834 TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str());
835 UIAbility::OnWillForeground();
836
837 std::string methodName = "OnWillForeground";
838 HandleScope handleScope(jsRuntime_);
839 AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
840 CallObjectMethod("onWillForeground");
841 AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
842
843 TAG_LOGD(AAFwkTag::UIABILITY, "end");
844 }
845
OnDidForeground()846 void JsUIAbility::OnDidForeground()
847 {
848 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
849 TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str());
850 UIAbility::OnDidForeground();
851
852 std::string methodName = "OnDidForeground";
853 HandleScope handleScope(jsRuntime_);
854 AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
855 CallObjectMethod("onDidForeground");
856 AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
857
858 if (scene_ != nullptr) {
859 scene_->GoResume();
860 }
861 TAG_LOGD(AAFwkTag::UIABILITY, "end");
862 }
863
OnWillBackground()864 void JsUIAbility::OnWillBackground()
865 {
866 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
867 TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str());
868 if (scene_ != nullptr) {
869 scene_->GoPause();
870 }
871 UIAbility::OnWillBackground();
872
873 std::string methodName = "OnWillBackground";
874 HandleScope handleScope(jsRuntime_);
875 AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::BACKGROUND, methodName);
876 CallObjectMethod("onWillBackground");
877 AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::BACKGROUND, methodName);
878
879 TAG_LOGD(AAFwkTag::UIABILITY, "end");
880 }
881
OnDidBackground()882 void JsUIAbility::OnDidBackground()
883 {
884 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
885 TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str());
886 UIAbility::OnDidBackground();
887
888 std::string methodName = "OnDidBackground";
889 HandleScope handleScope(jsRuntime_);
890 AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::BACKGROUND, methodName);
891 CallObjectMethod("onDidBackground");
892 AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::BACKGROUND, methodName);
893
894 TAG_LOGD(AAFwkTag::UIABILITY, "end");
895 }
896
OnBackPress()897 bool JsUIAbility::OnBackPress()
898 {
899 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
900 TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str());
901 UIAbility::OnBackPress();
902 HandleScope handleScope(jsRuntime_);
903 auto env = jsRuntime_.GetNapiEnv();
904 napi_value jsValue = CallObjectMethod("onBackPressed", nullptr, 0, true, false);
905 bool defaultRet = BackPressDefaultValue();
906 if (jsValue == nullptr) {
907 TAG_LOGD(AAFwkTag::UIABILITY, "null jsValue, return defaultRet %{public}d", defaultRet);
908 return defaultRet;
909 }
910 bool ret = defaultRet;
911 if (!ConvertFromJsValue(env, jsValue, ret)) {
912 TAG_LOGE(AAFwkTag::UIABILITY, "get js value failed");
913 return defaultRet;
914 }
915 TAG_LOGD(AAFwkTag::UIABILITY, "end ret: %{public}d", ret);
916 return ret;
917 }
918
OnPrepareTerminate(AppExecFwk::AbilityTransactionCallbackInfo<bool> * callbackInfo,bool & isAsync)919 void JsUIAbility::OnPrepareTerminate(AppExecFwk::AbilityTransactionCallbackInfo<bool> *callbackInfo,
920 bool &isAsync)
921 {
922 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
923 TAG_LOGD(AAFwkTag::UIABILITY, "ability: %{public}s", GetAbilityName().c_str());
924 UIAbility::OnPrepareTerminate(callbackInfo, isAsync);
925 HandleScope handleScope(jsRuntime_);
926 auto env = jsRuntime_.GetNapiEnv();
927 napi_value onPrepareToTerminateAsyncResult = nullptr;
928 napi_value onPrepareToTerminateResult = nullptr;
929 onPrepareToTerminateAsyncResult = CallObjectMethod("onPrepareToTerminateAsync", nullptr, 0, true);
930 if (onPrepareToTerminateAsyncResult == nullptr) {
931 TAG_LOGI(AAFwkTag::UIABILITY, "onPrepareToTerminateAsync not implemented, call onPrepareToTerminate");
932 onPrepareToTerminateResult = CallObjectMethod("onPrepareToTerminate", nullptr, 0, true);
933 }
934
935 if (onPrepareToTerminateAsyncResult == nullptr && onPrepareToTerminateResult == nullptr) {
936 TAG_LOGW(AAFwkTag::UIABILITY, "neither is implemented");
937 return;
938 }
939 if (onPrepareToTerminateResult != nullptr) {
940 TAG_LOGI(AAFwkTag::UIABILITY, "sync call");
941 bool isTerminate = false;
942 if (!ConvertFromJsValue(env, onPrepareToTerminateResult, isTerminate)) {
943 TAG_LOGE(AAFwkTag::UIABILITY, "get js value failed");
944 }
945 callbackInfo->Call(isTerminate);
946 return;
947 }
948 TAG_LOGI(AAFwkTag::UIABILITY, "async call");
949 if (!CheckPromise(onPrepareToTerminateAsyncResult) ||
950 !CallPromise(onPrepareToTerminateAsyncResult, callbackInfo)) {
951 TAG_LOGE(AAFwkTag::APPKIT, "check or call promise error");
952 return;
953 }
954 isAsync = true;
955 }
956
CreateAppWindowStage()957 std::unique_ptr<NativeReference> JsUIAbility::CreateAppWindowStage()
958 {
959 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
960 HandleScope handleScope(jsRuntime_);
961 auto env = jsRuntime_.GetNapiEnv();
962 napi_value jsWindowStage = Rosen::CreateJsWindowStage(env, GetScene());
963 if (jsWindowStage == nullptr) {
964 TAG_LOGE(AAFwkTag::UIABILITY, "null jsWindowStage");
965 return nullptr;
966 }
967 return JsRuntime::LoadSystemModuleByEngine(env, "application.WindowStage", &jsWindowStage, 1);
968 }
969
GetPageStackFromWant(const Want & want,std::string & pageStack)970 void JsUIAbility::GetPageStackFromWant(const Want &want, std::string &pageStack)
971 {
972 auto stringObj = AAFwk::IString::Query(want.GetParams().GetParam(PAGE_STACK_PROPERTY_NAME));
973 if (stringObj != nullptr) {
974 pageStack = AAFwk::String::Unbox(stringObj);
975 }
976 }
977
IsRestorePageStack(const Want & want)978 bool JsUIAbility::IsRestorePageStack(const Want &want)
979 {
980 return want.GetBoolParam(SUPPORT_CONTINUE_PAGE_STACK_PROPERTY_NAME, true);
981 }
982
RestorePageStack(const Want & want)983 void JsUIAbility::RestorePageStack(const Want &want)
984 {
985 if (IsRestorePageStack(want)) {
986 std::string pageStack;
987 GetPageStackFromWant(want, pageStack);
988 HandleScope handleScope(jsRuntime_);
989 auto env = jsRuntime_.GetNapiEnv();
990 if (abilityContext_->GetContentStorage()) {
991 scene_->GetMainWindow()->NapiSetUIContent(pageStack, env,
992 abilityContext_->GetContentStorage()->GetNapiValue(), Rosen::BackupAndRestoreType::CONTINUATION);
993 } else {
994 TAG_LOGE(AAFwkTag::UIABILITY, "null content storage");
995 }
996 }
997 }
998
AbilityContinuationOrRecover(const Want & want)999 void JsUIAbility::AbilityContinuationOrRecover(const Want &want)
1000 {
1001 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
1002 // multi-instance ability continuation
1003 TAG_LOGD(AAFwkTag::UIABILITY, "launch reason: %{public}d, last exit reasion: %{public}d",
1004 launchParam_.launchReason, launchParam_.lastExitReason);
1005 if (IsRestoredInContinuation()) {
1006 RestorePageStack(want);
1007 OnSceneRestored();
1008 NotifyContinuationResult(want, true);
1009 } else if (ShouldRecoverState(want)) {
1010 std::string pageStack = abilityRecovery_->GetSavedPageStack(AppExecFwk::StateReason::DEVELOPER_REQUEST);
1011 HandleScope handleScope(jsRuntime_);
1012 auto env = jsRuntime_.GetNapiEnv();
1013 auto mainWindow = scene_->GetMainWindow();
1014 if (mainWindow != nullptr) {
1015 mainWindow->NapiSetUIContent(pageStack, env, abilityContext_->GetContentStorage()->GetNapiValue(),
1016 Rosen::BackupAndRestoreType::APP_RECOVERY);
1017 } else {
1018 TAG_LOGE(AAFwkTag::UIABILITY, "null mainWindow");
1019 }
1020 OnSceneRestored();
1021 } else {
1022 if (ShouldDefaultRecoverState(want) && abilityRecovery_ != nullptr && scene_ != nullptr) {
1023 TAG_LOGD(AAFwkTag::UIABILITY, "need restore");
1024 std::string pageStack = abilityRecovery_->GetSavedPageStack(AppExecFwk::StateReason::DEVELOPER_REQUEST);
1025 auto mainWindow = scene_->GetMainWindow();
1026 if (!pageStack.empty() && mainWindow != nullptr) {
1027 mainWindow->SetRestoredRouterStack(pageStack);
1028 }
1029 }
1030 OnSceneCreated();
1031 }
1032 }
1033
DoOnForeground(const Want & want)1034 void JsUIAbility::DoOnForeground(const Want &want)
1035 {
1036 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
1037 if (scene_ == nullptr) {
1038 if ((abilityContext_ == nullptr) || (sceneListener_ == nullptr)) {
1039 TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext or sceneListener_");
1040 return;
1041 }
1042 DoOnForegroundForSceneIsNull(want);
1043 } else {
1044 auto window = scene_->GetMainWindow();
1045 if (window != nullptr && want.HasParameter(Want::PARAM_RESV_WINDOW_MODE)) {
1046 auto windowMode = want.GetIntParam(
1047 Want::PARAM_RESV_WINDOW_MODE, AAFwk::AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_UNDEFINED);
1048 window->SetWindowMode(static_cast<Rosen::WindowMode>(windowMode));
1049 windowMode_ = windowMode;
1050 TAG_LOGD(AAFwkTag::UIABILITY, "set window mode: %{public}d", windowMode);
1051 }
1052 SetInsightIntentParam(want, false);
1053 }
1054
1055 auto window = scene_->GetMainWindow();
1056 if (window != nullptr && securityFlag_) {
1057 window->SetSystemPrivacyMode(true);
1058 }
1059
1060 if (CheckIsSilentForeground()) {
1061 TAG_LOGI(AAFwkTag::UIABILITY, "silent foreground, do not show window");
1062 return;
1063 }
1064
1065 OnWillForeground();
1066
1067 TAG_LOGD(AAFwkTag::UIABILITY, "move scene to foreground, sceneFlag_: %{public}d", UIAbility::sceneFlag_);
1068 AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, METHOD_NAME);
1069 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, "scene_->GoForeground");
1070 scene_->GoForeground(UIAbility::sceneFlag_);
1071 TAG_LOGD(AAFwkTag::UIABILITY, "end");
1072 }
1073
DoOnForegroundForSceneIsNull(const Want & want)1074 void JsUIAbility::DoOnForegroundForSceneIsNull(const Want &want)
1075 {
1076 scene_ = std::make_shared<Rosen::WindowScene>();
1077 int32_t displayId = AAFwk::DisplayUtil::GetDefaultDisplayId();
1078 if (setting_ != nullptr) {
1079 std::string strDisplayId = setting_->GetProperty(OHOS::AppExecFwk::AbilityStartSetting::WINDOW_DISPLAY_ID_KEY);
1080 std::regex formatRegex("[0-9]{0,9}$");
1081 std::smatch sm;
1082 bool flag = std::regex_match(strDisplayId, sm, formatRegex);
1083 if (flag && !strDisplayId.empty()) {
1084 displayId = strtol(strDisplayId.c_str(), nullptr, BASE_DISPLAY_ID_NUM);
1085 TAG_LOGD(AAFwkTag::UIABILITY, "displayId: %{public}d", displayId);
1086 } else {
1087 TAG_LOGW(AAFwkTag::UIABILITY, "formatRegex: [%{public}s]", strDisplayId.c_str());
1088 }
1089 }
1090 auto option = GetWindowOption(want);
1091 Rosen::WMError ret = Rosen::WMError::WM_OK;
1092 auto sessionToken = GetSessionToken();
1093 auto identityToken = GetIdentityToken();
1094 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, "scene_->Init");
1095 if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled() && sessionToken != nullptr) {
1096 abilityContext_->SetWeakSessionToken(sessionToken);
1097 ret = scene_->Init(displayId, abilityContext_, sceneListener_, option, sessionToken, identityToken,
1098 reusingWindow_);
1099 RemoveShareRouterByBundleType(want);
1100 std::string navDestinationInfo = want.GetStringParam(Want::ATOMIC_SERVICE_SHARE_ROUTER);
1101 if (!navDestinationInfo.empty()) {
1102 TAG_LOGD(AAFwkTag::UIABILITY, "SetNavDestinationInfo :%{public}s", navDestinationInfo.c_str());
1103 scene_->SetNavDestinationInfo(navDestinationInfo);
1104 }
1105 if (abilityContext_->IsHook()) {
1106 TAG_LOGI(AAFwkTag::UIABILITY, "to set element");
1107 Rosen::WMError result = scene_->SetHookedWindowElementInfo(want.GetElement());
1108 if (result != Rosen::WMError::WM_OK) {
1109 TAG_LOGW(AAFwkTag::UIABILITY, "scene error:%{public}d", result);
1110 }
1111 }
1112 } else {
1113 ret = scene_->Init(displayId, abilityContext_, sceneListener_, option);
1114 }
1115 if (ret != Rosen::WMError::WM_OK) {
1116 TAG_LOGE(AAFwkTag::UIABILITY, "init window scene failed");
1117 FreezeUtil::GetInstance().AppendLifecycleEvent(AbilityContext::token_,
1118 std::string("JsUIAbility::DoOnForegroundForSceneIsNull; error ") + std::to_string(static_cast<int>(ret)));
1119 return;
1120 }
1121
1122 SetInsightIntentParam(want, true);
1123 AbilityContinuationOrRecover(want);
1124 auto window = scene_->GetMainWindow();
1125 if (window) {
1126 TAG_LOGD(AAFwkTag::UIABILITY, "registerDisplayMoveListener, windowId: %{public}d", window->GetWindowId());
1127 abilityDisplayMoveListener_ = new AbilityDisplayMoveListener(weak_from_this());
1128 if (abilityDisplayMoveListener_ == nullptr) {
1129 TAG_LOGE(AAFwkTag::UIABILITY, "null abilityDisplayMoveListener_");
1130 return;
1131 }
1132 window->RegisterDisplayMoveListener(abilityDisplayMoveListener_);
1133 }
1134 }
1135
RequestFocus(const Want & want)1136 void JsUIAbility::RequestFocus(const Want &want)
1137 {
1138 TAG_LOGI(AAFwkTag::UIABILITY, "called");
1139 if (scene_ == nullptr) {
1140 TAG_LOGE(AAFwkTag::UIABILITY, "null scene_");
1141 return;
1142 }
1143 auto window = scene_->GetMainWindow();
1144 if (window != nullptr && want.HasParameter(Want::PARAM_RESV_WINDOW_MODE)) {
1145 auto windowMode = want.GetIntParam(
1146 Want::PARAM_RESV_WINDOW_MODE, AAFwk::AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_UNDEFINED);
1147 window->SetWindowMode(static_cast<Rosen::WindowMode>(windowMode));
1148 TAG_LOGD(AAFwkTag::UIABILITY, "set window mode: %{public}d", windowMode);
1149 }
1150 SetInsightIntentParam(want, false);
1151 AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, METHOD_NAME);
1152 scene_->GoForeground(UIAbility::sceneFlag_);
1153 TAG_LOGI(AAFwkTag::UIABILITY, "end");
1154 }
1155
ContinuationRestore(const Want & want)1156 void JsUIAbility::ContinuationRestore(const Want &want)
1157 {
1158 TAG_LOGD(AAFwkTag::UIABILITY, "called");
1159 if (!IsRestoredInContinuation()) {
1160 TAG_LOGE(AAFwkTag::UIABILITY, "not in continuation");
1161 return;
1162 }
1163 if (scene_ == nullptr) {
1164 TAG_LOGE(AAFwkTag::UIABILITY, "null scene_");
1165 return;
1166 }
1167 RestorePageStack(want);
1168 OnSceneRestored();
1169 NotifyContinuationResult(want, true);
1170 }
1171
GetJsWindowStage()1172 std::shared_ptr<NativeReference> JsUIAbility::GetJsWindowStage()
1173 {
1174 TAG_LOGD(AAFwkTag::UIABILITY, "called");
1175 if (jsWindowStageObj_ == nullptr) {
1176 TAG_LOGE(AAFwkTag::UIABILITY, "null jsWindowStageObj_");
1177 }
1178 return jsWindowStageObj_;
1179 }
1180
GetJsRuntime()1181 const JsRuntime &JsUIAbility::GetJsRuntime()
1182 {
1183 return jsRuntime_;
1184 }
1185
ExecuteInsightIntentRepeateForeground(const Want & want,const std::shared_ptr<InsightIntentExecuteParam> & executeParam,std::unique_ptr<InsightIntentExecutorAsyncCallback> callback)1186 void JsUIAbility::ExecuteInsightIntentRepeateForeground(const Want &want,
1187 const std::shared_ptr<InsightIntentExecuteParam> &executeParam,
1188 std::unique_ptr<InsightIntentExecutorAsyncCallback> callback)
1189 {
1190 TAG_LOGD(AAFwkTag::UIABILITY, "called");
1191 if (executeParam == nullptr) {
1192 TAG_LOGW(AAFwkTag::UIABILITY, "null executeParam");
1193 RequestFocus(want);
1194 InsightIntentExecutorMgr::TriggerCallbackInner(std::move(callback), ERR_OK);
1195 return;
1196 }
1197
1198 auto asyncCallback = [weak = weak_from_this(), want](InsightIntentExecuteResult result) {
1199 TAG_LOGD(AAFwkTag::UIABILITY, "request focus");
1200 auto ability = weak.lock();
1201 if (ability == nullptr) {
1202 TAG_LOGE(AAFwkTag::UIABILITY, "null ability");
1203 return;
1204 }
1205 ability->RequestFocus(want);
1206 };
1207 callback->Push(asyncCallback);
1208
1209 InsightIntentExecutorInfo executeInfo;
1210 auto ret = GetInsightIntentExecutorInfo(want, executeParam, executeInfo);
1211 if (!ret) {
1212 TAG_LOGE(AAFwkTag::UIABILITY, "get intentExecutor failed");
1213 InsightIntentExecutorMgr::TriggerCallbackInner(std::move(callback),
1214 static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_PARAM));
1215 return;
1216 }
1217
1218 ret = DelayedSingleton<InsightIntentExecutorMgr>::GetInstance()->ExecuteInsightIntent(
1219 jsRuntime_, executeInfo, std::move(callback));
1220 if (!ret) {
1221 // callback has removed, release in insight intent executor.
1222 TAG_LOGE(AAFwkTag::UIABILITY, "execute insightIntent failed");
1223 }
1224 }
1225
ExecuteInsightIntentMoveToForeground(const Want & want,const std::shared_ptr<InsightIntentExecuteParam> & executeParam,std::unique_ptr<InsightIntentExecutorAsyncCallback> callback)1226 void JsUIAbility::ExecuteInsightIntentMoveToForeground(const Want &want,
1227 const std::shared_ptr<InsightIntentExecuteParam> &executeParam,
1228 std::unique_ptr<InsightIntentExecutorAsyncCallback> callback)
1229 {
1230 TAG_LOGD(AAFwkTag::UIABILITY, "called");
1231 if (executeParam == nullptr) {
1232 TAG_LOGW(AAFwkTag::UIABILITY, "null executeParam");
1233 OnForeground(want);
1234 InsightIntentExecutorMgr::TriggerCallbackInner(std::move(callback), ERR_OK);
1235 return;
1236 }
1237
1238 if (abilityInfo_) {
1239 jsRuntime_.UpdateModuleNameAndAssetPath(abilityInfo_->moduleName);
1240 }
1241 UIAbility::OnForeground(want);
1242
1243 auto asyncCallback = [weak = weak_from_this(), want](InsightIntentExecuteResult result) {
1244 TAG_LOGD(AAFwkTag::UIABILITY, "begin call onForeground");
1245 auto ability = weak.lock();
1246 if (ability == nullptr) {
1247 TAG_LOGE(AAFwkTag::UIABILITY, "null ability");
1248 return;
1249 }
1250 ability->CallOnForegroundFunc(want);
1251 };
1252 callback->Push(asyncCallback);
1253
1254 InsightIntentExecutorInfo executeInfo;
1255 auto ret = GetInsightIntentExecutorInfo(want, executeParam, executeInfo);
1256 if (!ret) {
1257 TAG_LOGE(AAFwkTag::UIABILITY, "get intentExecutor failed");
1258 InsightIntentExecutorMgr::TriggerCallbackInner(std::move(callback),
1259 static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_PARAM));
1260 return;
1261 }
1262
1263 ret = DelayedSingleton<InsightIntentExecutorMgr>::GetInstance()->ExecuteInsightIntent(
1264 jsRuntime_, executeInfo, std::move(callback));
1265 if (!ret) {
1266 // callback has removed, release in insight intent executor.
1267 TAG_LOGE(AAFwkTag::UIABILITY, "execute insightIntent failed");
1268 }
1269 }
1270
ExecuteInsightIntentPage(const Want & want,const std::shared_ptr<InsightIntentExecuteParam> & executeParam,std::unique_ptr<InsightIntentExecutorAsyncCallback> callback)1271 void JsUIAbility::ExecuteInsightIntentPage(const Want &want,
1272 const std::shared_ptr<InsightIntentExecuteParam> &executeParam,
1273 std::unique_ptr<InsightIntentExecutorAsyncCallback> callback)
1274 {
1275 TAG_LOGD(AAFwkTag::INTENT, "execute intent page");
1276 if (abilityInfo_ == nullptr) {
1277 TAG_LOGE(AAFwkTag::INTENT, "invalid ability info");
1278 InsightIntentExecutorMgr::TriggerCallbackInner(std::move(callback),
1279 static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_PARAM));
1280 return;
1281 }
1282
1283 InsightIntentExecutorInfo executeInfo;
1284 executeInfo.hapPath = abilityInfo_->hapPath;
1285 executeInfo.executeParam = executeParam;
1286 auto ret = DelayedSingleton<InsightIntentExecutorMgr>::GetInstance()->ExecuteInsightIntent(
1287 jsRuntime_, executeInfo, std::move(callback));
1288 if (!ret) {
1289 // callback has removed, release in insight intent executor.
1290 TAG_LOGE(AAFwkTag::INTENT, "execute insightIntent failed");
1291 }
1292 }
1293
SetInsightIntentParam(const Want & want,bool coldStart)1294 void JsUIAbility::SetInsightIntentParam(const Want &want, bool coldStart)
1295 {
1296 if (scene_ == nullptr) {
1297 TAG_LOGW(AAFwkTag::INTENT, "scene invalid");
1298 return;
1299 }
1300
1301 auto window = scene_->GetMainWindow();
1302 if (window == nullptr) {
1303 TAG_LOGW(AAFwkTag::INTENT, "window invalid");
1304 return;
1305 }
1306
1307 if (abilityInfo_ == nullptr) {
1308 TAG_LOGW(AAFwkTag::INTENT, "abilityInfo invalid");
1309 return;
1310 }
1311
1312 if (AppExecFwk::InsightIntentExecuteParam::IsInsightIntentPage(want)) {
1313 JsInsightIntentPage::SetInsightIntentParam(jsRuntime_, abilityInfo_->hapPath, want, window, coldStart);
1314 }
1315 }
1316
ExecuteInsightIntentBackground(const Want & want,const std::shared_ptr<InsightIntentExecuteParam> & executeParam,std::unique_ptr<InsightIntentExecutorAsyncCallback> callback)1317 void JsUIAbility::ExecuteInsightIntentBackground(const Want &want,
1318 const std::shared_ptr<InsightIntentExecuteParam> &executeParam,
1319 std::unique_ptr<InsightIntentExecutorAsyncCallback> callback)
1320 {
1321 TAG_LOGI(AAFwkTag::UIABILITY, "executeInsightIntentBackground");
1322 if (executeParam == nullptr) {
1323 TAG_LOGW(AAFwkTag::UIABILITY, "null executeParam");
1324 InsightIntentExecutorMgr::TriggerCallbackInner(std::move(callback), ERR_OK);
1325 return;
1326 }
1327
1328 if (abilityInfo_) {
1329 jsRuntime_.UpdateModuleNameAndAssetPath(abilityInfo_->moduleName);
1330 }
1331
1332 InsightIntentExecutorInfo executeInfo;
1333 auto ret = GetInsightIntentExecutorInfo(want, executeParam, executeInfo);
1334 if (!ret) {
1335 TAG_LOGE(AAFwkTag::UIABILITY, "get intentExecutor failed");
1336 InsightIntentExecutorMgr::TriggerCallbackInner(std::move(callback),
1337 static_cast<int32_t>(AbilityErrorCode::ERROR_CODE_INVALID_PARAM));
1338 return;
1339 }
1340
1341 ret = DelayedSingleton<InsightIntentExecutorMgr>::GetInstance()->ExecuteInsightIntent(
1342 jsRuntime_, executeInfo, std::move(callback));
1343 if (!ret) {
1344 // callback has removed, release in insight intent executor.
1345 TAG_LOGE(AAFwkTag::UIABILITY, "execute insightIntent failed");
1346 }
1347 }
1348
GetInsightIntentExecutorInfo(const Want & want,const std::shared_ptr<InsightIntentExecuteParam> & executeParam,InsightIntentExecutorInfo & executeInfo)1349 bool JsUIAbility::GetInsightIntentExecutorInfo(const Want &want,
1350 const std::shared_ptr<InsightIntentExecuteParam> &executeParam,
1351 InsightIntentExecutorInfo& executeInfo)
1352 {
1353 TAG_LOGD(AAFwkTag::UIABILITY, "called");
1354
1355 auto context = GetAbilityContext();
1356 if (executeParam == nullptr || context == nullptr || abilityInfo_ == nullptr) {
1357 TAG_LOGE(AAFwkTag::UIABILITY, "param invalid");
1358 return false;
1359 }
1360
1361 if (executeParam->executeMode_ == AppExecFwk::ExecuteMode::UI_ABILITY_FOREGROUND
1362 && jsWindowStageObj_ == nullptr) {
1363 TAG_LOGE(AAFwkTag::UIABILITY, "param invalid");
1364 return false;
1365 }
1366
1367 const WantParams &wantParams = want.GetParams();
1368 executeInfo.srcEntry = wantParams.GetStringParam("ohos.insightIntent.srcEntry");
1369 executeInfo.hapPath = abilityInfo_->hapPath;
1370 executeInfo.esmodule = abilityInfo_->compileMode == AppExecFwk::CompileMode::ES_MODULE;
1371 executeInfo.windowMode = windowMode_;
1372 executeInfo.token = context->GetToken();
1373 if (jsWindowStageObj_ != nullptr) {
1374 executeInfo.pageLoader = jsWindowStageObj_;
1375 }
1376 executeInfo.executeParam = executeParam;
1377 return true;
1378 }
1379
OnCollaborate(WantParams & wantParam)1380 int32_t JsUIAbility::OnCollaborate(WantParams &wantParam)
1381 {
1382 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
1383 TAG_LOGD(AAFwkTag::UIABILITY, "OnCollaborate: %{public}s", GetAbilityName().c_str());
1384 int32_t ret = CollaborateResult::ON_COLLABORATE_ERR;
1385 HandleScope handleScope(jsRuntime_);
1386 auto env = jsRuntime_.GetNapiEnv();
1387
1388 if (jsAbilityObj_ == nullptr) {
1389 TAG_LOGE(AAFwkTag::UIABILITY, "null jsAbilityObj_");
1390 return ret;
1391 }
1392 napi_value obj = jsAbilityObj_->GetNapiValue();
1393 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
1394 TAG_LOGE(AAFwkTag::UIABILITY, "get ability object fail");
1395 return ret;
1396 }
1397
1398 napi_value jsWantParams = OHOS::AppExecFwk::WrapWantParams(env, wantParam);
1399 napi_value argv[] = {
1400 jsWantParams,
1401 };
1402 auto result = CallObjectMethod("onCollaborate", argv, ArraySize(argv), true);
1403 if (result == nullptr) {
1404 TAG_LOGE(AAFwkTag::UIABILITY, "onCollaborate not implemented");
1405 return CollaborateResult::ON_COLLABORATE_NOT_IMPLEMENTED;
1406 }
1407 OHOS::AppExecFwk::UnwrapWantParams(env, jsWantParams, wantParam);
1408
1409 if (!ConvertFromJsValue(env, result, ret)) {
1410 TAG_LOGE(AAFwkTag::UIABILITY, "get js value failed");
1411 return ret;
1412 }
1413 ret = (ret == CollaborateResult::ACCEPT) ? CollaborateResult::ACCEPT : CollaborateResult::REJECT;
1414 return ret;
1415 }
1416
HandleCollaboration(const Want & want)1417 void JsUIAbility::HandleCollaboration(const Want &want)
1418 {
1419 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
1420 if (abilityInfo_ == nullptr) {
1421 TAG_LOGE(AAFwkTag::UIABILITY, "null abilityInfo_");
1422 return;
1423 }
1424 if (want.GetBoolParam(IS_CALLING_FROM_DMS, false) &&
1425 (abilityInfo_->launchMode != AppExecFwk::LaunchMode::SPECIFIED)) {
1426 (const_cast<Want &>(want)).RemoveParam(IS_CALLING_FROM_DMS);
1427 SetWant(want);
1428 OHOS::AAFwk::WantParams wantParams = want.GetParams();
1429 int32_t resultCode = OnCollaborate(wantParams);
1430 auto abilityContext = GetAbilityContext();
1431 if (abilityContext == nullptr) {
1432 TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext");
1433 return;
1434 }
1435 OHOS::AAFwk::WantParams param = want.GetParams().GetWantParams(SUPPORT_COLLABORATE_INDEX);
1436 auto collabToken = param.GetStringParam(COLLABORATE_KEY);
1437 auto uid = abilityInfo_->uid;
1438 auto callerPid = getpid();
1439 auto accessTokenId = abilityInfo_->applicationInfo.accessTokenId;
1440 AAFwk::DistributedClient dmsClient;
1441 dmsClient.OnCollaborateDone(collabToken, resultCode, callerPid, uid, accessTokenId);
1442 }
1443 }
1444 #endif
1445
OnAbilityRequestFailure(const std::string & requestId,const AppExecFwk::ElementName & element,const std::string & message,int32_t resultCode)1446 void JsUIAbility::OnAbilityRequestFailure(const std::string &requestId, const AppExecFwk::ElementName &element,
1447 const std::string &message, int32_t resultCode)
1448 {
1449 TAG_LOGD(AAFwkTag::UIABILITY, "OnAbilityRequestFailure called");
1450 UIAbility::OnAbilityRequestFailure(requestId, element, message, resultCode);
1451 auto abilityContext = GetAbilityContext();
1452 if (abilityContext == nullptr) {
1453 TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext");
1454 return;
1455 }
1456 abilityContext->OnRequestFailure(requestId, element, message, resultCode);
1457 }
1458
OnAbilityRequestSuccess(const std::string & requestId,const AppExecFwk::ElementName & element,const std::string & message)1459 void JsUIAbility::OnAbilityRequestSuccess(const std::string &requestId, const AppExecFwk::ElementName &element,
1460 const std::string &message)
1461 {
1462 TAG_LOGD(AAFwkTag::UIABILITY, "OnAbilityRequestSuccess called");
1463 UIAbility::OnAbilityRequestSuccess(requestId, element, message);
1464 auto abilityContext = GetAbilityContext();
1465 if (abilityContext == nullptr) {
1466 TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext");
1467 return;
1468 }
1469 abilityContext->OnRequestSuccess(requestId, element, message);
1470 }
1471
OnContinue(WantParams & wantParams,bool & isAsyncOnContinue,const AppExecFwk::AbilityInfo & abilityInfo)1472 int32_t JsUIAbility::OnContinue(WantParams &wantParams, bool &isAsyncOnContinue,
1473 const AppExecFwk::AbilityInfo &abilityInfo)
1474 {
1475 TAG_LOGI(AAFwkTag::UIABILITY, "called");
1476 HandleScope handleScope(jsRuntime_);
1477 auto env = jsRuntime_.GetNapiEnv();
1478 if (jsAbilityObj_ == nullptr) {
1479 TAG_LOGE(AAFwkTag::UIABILITY, "null jsAbilityObj_");
1480 return AppExecFwk::ContinuationManagerStage::OnContinueResult::ON_CONTINUE_ERR;
1481 }
1482 napi_value obj = jsAbilityObj_->GetNapiValue();
1483 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
1484 TAG_LOGE(AAFwkTag::UIABILITY, "failed get ability");
1485 return AppExecFwk::ContinuationManagerStage::OnContinueResult::ON_CONTINUE_ERR;
1486 }
1487 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
1488 if (applicationContext != nullptr) {
1489 applicationContext->DispatchOnAbilityWillContinue(jsAbilityObj_);
1490 }
1491 napi_value jsWantParams = OHOS::AppExecFwk::WrapWantParams(env, wantParams);
1492 napi_value result = CallObjectMethod("onContinue", &jsWantParams, 1, true);
1493 int32_t onContinueRes = 0;
1494 if (!CheckPromise(result)) {
1495 return OnContinueSyncCB(result, wantParams, jsWantParams);
1496 }
1497 auto *callbackInfo = AppExecFwk::AbilityTransactionCallbackInfo<int32_t>::Create();
1498 if (callbackInfo == nullptr) {
1499 TAG_LOGE(AAFwkTag::UIABILITY, "null callbackInfo");
1500 return OnContinueSyncCB(result, wantParams, jsWantParams);
1501 }
1502 std::weak_ptr<UIAbility> weakPtr = shared_from_this();
1503 napi_ref jsWantParamsRef;
1504 napi_create_reference(env, jsWantParams, 1, &jsWantParamsRef);
1505 ReleaseOnContinueAsset(env, result, jsWantParamsRef, callbackInfo);
1506 auto asyncCallback = [jsWantParamsRef, abilityWeakPtr = weakPtr, abilityInfo](int32_t status) {
1507 auto ability = abilityWeakPtr.lock();
1508 if (ability == nullptr) {
1509 TAG_LOGE(AAFwkTag::UIABILITY, "null ability");
1510 return;
1511 }
1512 ability->OnContinueAsyncCB(jsWantParamsRef, status, abilityInfo);
1513 };
1514 callbackInfo->Push(asyncCallback);
1515 if (!CallPromise(result, callbackInfo)) {
1516 TAG_LOGE(AAFwkTag::UIABILITY, "call promise failed");
1517 return OnContinueSyncCB(result, wantParams, jsWantParams);
1518 }
1519 isAsyncOnContinue = true;
1520 TAG_LOGI(AAFwkTag::UIABILITY, "end");
1521 return onContinueRes;
1522 }
1523
ReleaseOnContinueAsset(const napi_env env,napi_value & promise,napi_ref & jsWantParamsRef,AppExecFwk::AbilityTransactionCallbackInfo<int32_t> * callbackInfo)1524 void JsUIAbility::ReleaseOnContinueAsset(const napi_env env, napi_value &promise,
1525 napi_ref &jsWantParamsRef, AppExecFwk::AbilityTransactionCallbackInfo<int32_t> *callbackInfo)
1526 {
1527 napi_add_finalizer(env, promise, jsWantParamsRef, [](napi_env env, void *context, void *) {
1528 TAG_LOGI(AAFwkTag::UIABILITY, "Release jsWantParamsRef");
1529 auto contextRef = reinterpret_cast<napi_ref>(context);
1530 if (contextRef != nullptr) {
1531 napi_delete_reference(env, contextRef);
1532 contextRef = nullptr;
1533 }
1534 }, nullptr, nullptr);
1535 napi_add_finalizer(env, promise, callbackInfo, [](napi_env env, void *context, void *) {
1536 TAG_LOGI(AAFwkTag::UIABILITY, "Release callbackInfo");
1537 auto contextRef = reinterpret_cast<AppExecFwk::AbilityTransactionCallbackInfo<int32_t> *>(context);
1538 if (contextRef != nullptr) {
1539 AppExecFwk::AbilityTransactionCallbackInfo<int32_t>::Destroy(contextRef);
1540 contextRef = nullptr;
1541 }
1542 }, nullptr, nullptr);
1543 }
1544
OnContinueAsyncCB(napi_ref jsWantParamsRef,int32_t status,const AppExecFwk::AbilityInfo & abilityInfo)1545 int32_t JsUIAbility::OnContinueAsyncCB(napi_ref jsWantParamsRef, int32_t status,
1546 const AppExecFwk::AbilityInfo &abilityInfo)
1547 {
1548 TAG_LOGI(AAFwkTag::UIABILITY, "call");
1549 HandleScope handleScope(jsRuntime_);
1550 auto env = jsRuntime_.GetNapiEnv();
1551 WantParams wantParams;
1552 napi_value jsWantParams;
1553 napi_get_reference_value(env, jsWantParamsRef, &jsWantParams);
1554 OHOS::AppExecFwk::UnwrapWantParams(env, jsWantParams, wantParams);
1555 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
1556 if (applicationContext != nullptr) {
1557 applicationContext->DispatchOnAbilityContinue(jsAbilityObj_);
1558 }
1559
1560 Want want;
1561 want.SetParams(wantParams);
1562 want.AddFlags(want.FLAG_ABILITY_CONTINUATION);
1563 want.SetElementName(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name,
1564 abilityInfo.moduleName);
1565 int result = AAFwk::AbilityManagerClient::GetInstance()->StartContinuation(want, token_, status);
1566 if (result != ERR_OK) {
1567 TAG_LOGE(AAFwkTag::CONTINUATION, "StartContinuation failed: %{public}d", result);
1568 }
1569 TAG_LOGI(AAFwkTag::UIABILITY, "end");
1570 return result;
1571 }
1572
OnContinueSyncCB(napi_value result,WantParams & wantParams,napi_value jsWantParams)1573 int32_t JsUIAbility::OnContinueSyncCB(napi_value result, WantParams &wantParams, napi_value jsWantParams)
1574 {
1575 TAG_LOGI(AAFwkTag::UIABILITY, "call");
1576 HandleScope handleScope(jsRuntime_);
1577 auto env = jsRuntime_.GetNapiEnv();
1578 int32_t onContinueRes = 0;
1579 if (!ConvertFromJsValue(env, result, onContinueRes)) {
1580 TAG_LOGE(AAFwkTag::UIABILITY, "'onContinue' is not implemented");
1581 return AppExecFwk::ContinuationManagerStage::OnContinueResult::ON_CONTINUE_ERR;
1582 }
1583 OHOS::AppExecFwk::UnwrapWantParams(env, jsWantParams, wantParams);
1584 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
1585 if (applicationContext != nullptr) {
1586 applicationContext->DispatchOnAbilityContinue(jsAbilityObj_);
1587 }
1588 TAG_LOGI(AAFwkTag::UIABILITY, "end");
1589 return onContinueRes;
1590 }
1591
OnSaveState(int32_t reason,WantParams & wantParams,AppExecFwk::AbilityTransactionCallbackInfo<AppExecFwk::OnSaveStateResult> * callbackInfo,bool & isAsync,AppExecFwk::StateReason stateReason)1592 int32_t JsUIAbility::OnSaveState(int32_t reason, WantParams &wantParams,
1593 AppExecFwk::AbilityTransactionCallbackInfo<AppExecFwk::OnSaveStateResult> *callbackInfo,
1594 bool &isAsync, AppExecFwk::StateReason stateReason)
1595 {
1596 HandleScope handleScope(jsRuntime_);
1597 auto env = jsRuntime_.GetNapiEnv();
1598 CHECK_POINTER_AND_RETURN(jsAbilityObj_, CALL_BACK_ERROR);
1599 napi_value obj = jsAbilityObj_->GetNapiValue();
1600 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
1601 TAG_LOGE(AAFwkTag::UIABILITY, "get ability object failed");
1602 return CALL_BACK_ERROR;
1603 }
1604 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
1605 if (applicationContext != nullptr) {
1606 applicationContext->DispatchOnAbilityWillSaveState(jsAbilityObj_);
1607 }
1608
1609 napi_value jsWantParams = OHOS::AppExecFwk::WrapWantParams(env, wantParams);
1610 napi_value jsReason = CreateJsValue(env, reason);
1611 napi_value args[] = {jsReason, jsWantParams};
1612 bool hasCaughtException = false;
1613 CallObjectMethodParams callObjectMethodParams;
1614 callObjectMethodParams.withResult = true;
1615 napi_value onSaveStateAsyncResult = CallObjectMethod(
1616 "onSaveStateAsync", hasCaughtException, callObjectMethodParams, args, PROMISE_CALLBACK_PARAM_NUM);
1617 if (hasCaughtException) {
1618 return CALL_BACK_ERROR;
1619 }
1620 if (onSaveStateAsyncResult != nullptr) {
1621 OHOS::AppExecFwk::UnwrapWantParams(env, jsWantParams, wantParams);
1622 CallOnSaveStateInfo info = { callbackInfo, wantParams, stateReason };
1623 int32_t status = CallSaveStatePromise(onSaveStateAsyncResult, info);
1624 if (status == ERR_OK && applicationContext != nullptr) {
1625 applicationContext->DispatchOnAbilitySaveState(jsAbilityObj_);
1626 }
1627 isAsync = true;
1628 return status;
1629 }
1630 napi_value methodOnSaveState = nullptr;
1631 napi_get_named_property(env, obj, "onSaveState", &methodOnSaveState);
1632 CHECK_POINTER_AND_RETURN(methodOnSaveState, CALL_BACK_ERROR);
1633
1634 napi_value result = nullptr;
1635 napi_call_function(env, obj, methodOnSaveState, PROMISE_CALLBACK_PARAM_NUM, args, &result);
1636 OHOS::AppExecFwk::UnwrapWantParams(env, jsWantParams, wantParams);
1637
1638 int32_t numberResult = 0;
1639 if (!ConvertFromJsValue(env, result, numberResult)) {
1640 TAG_LOGE(AAFwkTag::UIABILITY, "no result return from onSaveState");
1641 return CALL_BACK_ERROR;
1642 }
1643
1644 if (applicationContext != nullptr) {
1645 applicationContext->DispatchOnAbilitySaveState(jsAbilityObj_);
1646 }
1647 AppExecFwk::OnSaveStateResult saveStateResult = {numberResult, wantParams, stateReason};
1648 callbackInfo->Call(saveStateResult);
1649 AppExecFwk::AbilityTransactionCallbackInfo<AppExecFwk::OnSaveStateResult>::Destroy(callbackInfo);
1650 return numberResult;
1651 }
1652
OnConfigurationUpdated(const Configuration & configuration)1653 void JsUIAbility::OnConfigurationUpdated(const Configuration &configuration)
1654 {
1655 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
1656 UIAbility::OnConfigurationUpdated(configuration);
1657 TAG_LOGD(AAFwkTag::UIABILITY, "called");
1658 if (abilityContext_ == nullptr) {
1659 TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext");
1660 return;
1661 }
1662
1663 HandleScope handleScope(jsRuntime_);
1664 auto env = jsRuntime_.GetNapiEnv();
1665 auto abilityConfig = abilityContext_->GetAbilityConfiguration();
1666 auto fullConfig = abilityContext_->GetConfiguration();
1667 if (fullConfig == nullptr) {
1668 TAG_LOGE(AAFwkTag::UIABILITY, "null fullConfig");
1669 return;
1670 }
1671
1672 auto realConfig = AppExecFwk::Configuration(*fullConfig);
1673
1674 if (abilityConfig != nullptr) {
1675 std::vector<std::string> changeKeyV;
1676 realConfig.CompareDifferent(changeKeyV, *abilityConfig);
1677 if (!changeKeyV.empty()) {
1678 realConfig.Merge(changeKeyV, *abilityConfig);
1679 }
1680 }
1681
1682 TAG_LOGD(AAFwkTag::UIABILITY, "realConfig: %{public}s", realConfig.GetName().c_str());
1683 napi_value napiConfiguration = OHOS::AppExecFwk::WrapConfiguration(env, realConfig);
1684
1685 CallObjectMethod("onConfigurationUpdated", &napiConfiguration, 1);
1686 CallObjectMethod("onConfigurationUpdate", &napiConfiguration, 1);
1687 auto realConfigPtr = std::make_shared<Configuration>(realConfig);
1688 JsAbilityContext::ConfigurationUpdated(env, shellContextRef_, realConfigPtr);
1689 }
1690
OnMemoryLevel(int level)1691 void JsUIAbility::OnMemoryLevel(int level)
1692 {
1693 UIAbility::OnMemoryLevel(level);
1694 TAG_LOGD(AAFwkTag::UIABILITY, "called");
1695
1696 HandleScope handleScope(jsRuntime_);
1697 auto env = jsRuntime_.GetNapiEnv();
1698 if (jsAbilityObj_ == nullptr) {
1699 TAG_LOGE(AAFwkTag::UIABILITY, "null jsAbilityObj_");
1700 return;
1701 }
1702 napi_value obj = jsAbilityObj_->GetNapiValue();
1703 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
1704 TAG_LOGE(AAFwkTag::UIABILITY, "get ability object failed");
1705 return;
1706 }
1707
1708 napi_value jslevel = CreateJsValue(env, level);
1709 napi_value argv[] = { jslevel };
1710 CallObjectMethod("onMemoryLevel", argv, ArraySize(argv));
1711 }
1712
UpdateContextConfiguration()1713 void JsUIAbility::UpdateContextConfiguration()
1714 {
1715 TAG_LOGD(AAFwkTag::UIABILITY, "called");
1716 if (abilityContext_ == nullptr) {
1717 TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext_");
1718 return;
1719 }
1720 HandleScope handleScope(jsRuntime_);
1721 auto env = jsRuntime_.GetNapiEnv();
1722 JsAbilityContext::ConfigurationUpdated(env, shellContextRef_, abilityContext_->GetConfiguration());
1723 }
1724
RemoveShareRouterByBundleType(const Want & want)1725 void JsUIAbility::RemoveShareRouterByBundleType(const Want &want)
1726 {
1727 auto abilityInfo = abilityContext_ ? abilityContext_->GetAbilityInfo() : nullptr;
1728 if (abilityInfo == nullptr ||
1729 abilityInfo->applicationInfo.bundleType != OHOS::AppExecFwk::BundleType::ATOMIC_SERVICE) {
1730 TAG_LOGD(AAFwkTag::UIABILITY, "not atomicService");
1731 const_cast<Want &>(want).RemoveParam(Want::ATOMIC_SERVICE_SHARE_ROUTER);
1732 }
1733 return;
1734 }
1735
OnNewWant(const Want & want)1736 void JsUIAbility::OnNewWant(const Want &want)
1737 {
1738 TAG_LOGD(AAFwkTag::UIABILITY, "called");
1739 UIAbility::OnNewWant(want);
1740
1741 #ifdef SUPPORT_SCREEN
1742 if (scene_) {
1743 RemoveShareRouterByBundleType(want);
1744 scene_->OnNewWant(want);
1745 }
1746 HandleCollaboration(want);
1747 #endif
1748
1749 HandleScope handleScope(jsRuntime_);
1750 auto env = jsRuntime_.GetNapiEnv();
1751 if (jsAbilityObj_ == nullptr) {
1752 TAG_LOGE(AAFwkTag::UIABILITY, "null jsAbilityObj_");
1753 return;
1754 }
1755 napi_value obj = jsAbilityObj_->GetNapiValue();
1756 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
1757 TAG_LOGE(AAFwkTag::UIABILITY, "ability object failed");
1758 return;
1759 }
1760
1761 napi_value jsWant = OHOS::AppExecFwk::WrapWant(env, want);
1762 if (jsWant == nullptr) {
1763 TAG_LOGE(AAFwkTag::UIABILITY, "null want");
1764 return;
1765 }
1766
1767 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
1768 if (applicationContext != nullptr) {
1769 applicationContext->DispatchOnWillNewWant(jsAbilityObj_);
1770 }
1771
1772 napi_set_named_property(env, obj, "lastRequestWant", jsWant);
1773 auto launchParam = GetLaunchParam();
1774 if (InsightIntentExecuteParam::IsInsightIntentExecute(want)) {
1775 launchParam.launchReason = AAFwk::LaunchReason::LAUNCHREASON_INSIGHT_INTENT;
1776 }
1777 napi_value argv[] = {
1778 jsWant,
1779 CreateJsLaunchParam(env, launchParam),
1780 };
1781 std::string methodName = "OnNewWant";
1782 AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
1783 CallObjectMethod("onNewWant", argv, ArraySize(argv));
1784 AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
1785
1786 applicationContext = AbilityRuntime::Context::GetApplicationContext();
1787 if (applicationContext != nullptr) {
1788 applicationContext->DispatchOnNewWant(jsAbilityObj_);
1789 }
1790 TAG_LOGD(AAFwkTag::UIABILITY, "end");
1791 }
1792
OnAbilityResult(int requestCode,int resultCode,const Want & resultData)1793 void JsUIAbility::OnAbilityResult(int requestCode, int resultCode, const Want &resultData)
1794 {
1795 TAG_LOGD(AAFwkTag::UIABILITY, "called");
1796 UIAbility::OnAbilityResult(requestCode, resultCode, resultData);
1797 if (abilityContext_ == nullptr) {
1798 TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext_");
1799 return;
1800 }
1801 abilityContext_->OnAbilityResult(requestCode, resultCode, resultData);
1802 TAG_LOGD(AAFwkTag::UIABILITY, "end");
1803 }
1804
CallRequest()1805 sptr<IRemoteObject> JsUIAbility::CallRequest()
1806 {
1807 TAG_LOGD(AAFwkTag::UIABILITY, "called");
1808 if (jsAbilityObj_ == nullptr) {
1809 TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext_");
1810 return nullptr;
1811 }
1812
1813 if (remoteCallee_ != nullptr) {
1814 TAG_LOGE(AAFwkTag::UIABILITY, "remoteCallee_ is exist");
1815 return remoteCallee_;
1816 }
1817
1818 HandleScope handleScope(jsRuntime_);
1819 auto env = jsRuntime_.GetNapiEnv();
1820 auto obj = jsAbilityObj_->GetNapiValue();
1821 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
1822 TAG_LOGE(AAFwkTag::UIABILITY, "null value");
1823 return nullptr;
1824 }
1825
1826 napi_value method = nullptr;
1827 napi_get_named_property(env, obj, "onCallRequest", &method);
1828 bool isCallable = false;
1829 napi_is_callable(env, method, &isCallable);
1830 if (!isCallable) {
1831 TAG_LOGE(AAFwkTag::UIABILITY, "method: %{public}s", method == nullptr ? "nullptr" : "not func");
1832 return nullptr;
1833 }
1834
1835 napi_value remoteJsObj = nullptr;
1836 napi_call_function(env, obj, method, 0, nullptr, &remoteJsObj);
1837 if (remoteJsObj == nullptr) {
1838 TAG_LOGE(AAFwkTag::UIABILITY, "null remoteJsObj");
1839 return nullptr;
1840 }
1841
1842 remoteCallee_ = SetNewRuleFlagToCallee(env, remoteJsObj);
1843 TAG_LOGD(AAFwkTag::UIABILITY, "end");
1844 return remoteCallee_;
1845 }
1846
CallObjectMethod(const char * name,napi_value const * argv,size_t argc,bool withResult,bool showMethodNotFoundLog)1847 napi_value JsUIAbility::CallObjectMethod(const char *name, napi_value const *argv, size_t argc, bool withResult,
1848 bool showMethodNotFoundLog)
1849 {
1850 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, std::string("CallObjectMethod:") + name);
1851 TAG_LOGI(AAFwkTag::UIABILITY, "JsUIAbility call js, name: %{public}s", name);
1852 if (jsAbilityObj_ == nullptr) {
1853 TAG_LOGE(AAFwkTag::UIABILITY, "null jsAbilityObj");
1854 return nullptr;
1855 }
1856
1857 HandleEscape handleEscape(jsRuntime_);
1858 auto env = jsRuntime_.GetNapiEnv();
1859
1860 napi_value obj = jsAbilityObj_->GetNapiValue();
1861 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
1862 TAG_LOGE(AAFwkTag::UIABILITY, "get ability object failed");
1863 return nullptr;
1864 }
1865
1866 napi_value methodOnCreate = nullptr;
1867 napi_get_named_property(env, obj, name, &methodOnCreate);
1868 if (methodOnCreate == nullptr) {
1869 if (showMethodNotFoundLog) {
1870 TAG_LOGE(AAFwkTag::UIABILITY, "get '%{public}s' from ability object failed", name);
1871 }
1872 return nullptr;
1873 }
1874 TryCatch tryCatch(env);
1875 if (withResult) {
1876 napi_value result = nullptr;
1877 napi_status withResultStatus = napi_call_function(env, obj, methodOnCreate, argc, argv, &result);
1878 if (withResultStatus != napi_ok) {
1879 TAG_LOGE(AAFwkTag::UIABILITY, "JsUIAbility call js, withResult failed: %{public}d", withResultStatus);
1880 }
1881 if (tryCatch.HasCaught()) {
1882 reinterpret_cast<NativeEngine*>(env)->HandleUncaughtException();
1883 }
1884 return handleEscape.Escape(result);
1885 }
1886 int64_t timeStart = AbilityRuntime::TimeUtil::SystemTimeMillisecond();
1887 napi_status status = napi_call_function(env, obj, methodOnCreate, argc, argv, nullptr);
1888 if (status != napi_ok && status != napi_function_expected) {
1889 TAG_LOGE(AAFwkTag::UIABILITY, "napi err: %{public}d", status);
1890 }
1891 int64_t timeEnd = AbilityRuntime::TimeUtil::SystemTimeMillisecond();
1892 if (tryCatch.HasCaught()) {
1893 reinterpret_cast<NativeEngine*>(env)->HandleUncaughtException();
1894 }
1895 TAG_LOGI(AAFwkTag::UIABILITY, "end, name: %{public}s, time: %{public}s",
1896 name, std::to_string(timeEnd - timeStart).c_str());
1897 return nullptr;
1898 }
1899
CallObjectMethod(const char * name,bool & hasCaughtException,const CallObjectMethodParams & callObjectMethodParams,napi_value const * argv,size_t argc)1900 napi_value JsUIAbility::CallObjectMethod(const char *name, bool &hasCaughtException,
1901 const CallObjectMethodParams &callObjectMethodParams, napi_value const *argv, size_t argc)
1902 {
1903 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, std::string("CallObjectMethod:") + name);
1904 TAG_LOGI(AAFwkTag::UIABILITY, "JsUIAbility call js, name: %{public}s", name);
1905 if (jsAbilityObj_ == nullptr) {
1906 TAG_LOGE(AAFwkTag::UIABILITY, "null jsAbilityObj");
1907 return nullptr;
1908 }
1909
1910 HandleEscape handleEscape(jsRuntime_);
1911 auto env = jsRuntime_.GetNapiEnv();
1912
1913 napi_value obj = jsAbilityObj_->GetNapiValue();
1914 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
1915 TAG_LOGE(AAFwkTag::UIABILITY, "get ability object failed");
1916 return nullptr;
1917 }
1918
1919 napi_value methodOnCreate = nullptr;
1920 napi_get_named_property(env, obj, name, &methodOnCreate);
1921 if (methodOnCreate == nullptr) {
1922 if (callObjectMethodParams.showMethodNotFoundLog) {
1923 TAG_LOGE(AAFwkTag::UIABILITY, "get '%{public}s' from ability object failed", name);
1924 }
1925 return nullptr;
1926 }
1927 TryCatch tryCatch(env);
1928 if (callObjectMethodParams.withResult) {
1929 napi_value result = nullptr;
1930 napi_status withResultStatus = napi_call_function(env, obj, methodOnCreate, argc, argv, &result);
1931 if (withResultStatus != napi_ok) {
1932 TAG_LOGE(AAFwkTag::UIABILITY, "JsUIAbility call js, withResult failed: %{public}d", withResultStatus);
1933 }
1934 if (tryCatch.HasCaught()) {
1935 TAG_LOGE(AAFwkTag::APPKIT, "%{public}s exception occurred", name);
1936 reinterpret_cast<NativeEngine*>(env)->HandleUncaughtException();
1937 hasCaughtException = true;
1938 }
1939 return handleEscape.Escape(result);
1940 }
1941 int64_t timeStart = AbilityRuntime::TimeUtil::SystemTimeMillisecond();
1942 napi_status status = napi_call_function(env, obj, methodOnCreate, argc, argv, nullptr);
1943 if (status != napi_ok) {
1944 TAG_LOGE(AAFwkTag::UIABILITY, "JsUIAbility call js, failed: %{public}d", status);
1945 }
1946 int64_t timeEnd = AbilityRuntime::TimeUtil::SystemTimeMillisecond();
1947 if (tryCatch.HasCaught()) {
1948 reinterpret_cast<NativeEngine*>(env)->HandleUncaughtException();
1949 hasCaughtException = true;
1950 }
1951 TAG_LOGI(AAFwkTag::UIABILITY, "end, name: %{public}s, time: %{public}s",
1952 name, std::to_string(timeEnd - timeStart).c_str());
1953 return nullptr;
1954 }
1955
CheckPromise(napi_value result)1956 bool JsUIAbility::CheckPromise(napi_value result)
1957 {
1958 if (result == nullptr) {
1959 TAG_LOGE(AAFwkTag::UIABILITY, "null result");
1960 return false;
1961 }
1962 auto env = jsRuntime_.GetNapiEnv();
1963 bool isPromise = false;
1964 napi_is_promise(env, result, &isPromise);
1965 if (!isPromise) {
1966 TAG_LOGD(AAFwkTag::UIABILITY, "result is not promise");
1967 return false;
1968 }
1969 return true;
1970 }
1971
CallPromise(napi_value result,AppExecFwk::AbilityTransactionCallbackInfo<> * callbackInfo)1972 bool JsUIAbility::CallPromise(napi_value result, AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo)
1973 {
1974 auto env = jsRuntime_.GetNapiEnv();
1975 if (!CheckTypeForNapiValue(env, result, napi_object)) {
1976 TAG_LOGE(AAFwkTag::UIABILITY, "convert failed");
1977 return false;
1978 }
1979 napi_value then = nullptr;
1980 napi_get_named_property(env, result, "then", &then);
1981 if (then == nullptr) {
1982 TAG_LOGE(AAFwkTag::UIABILITY, "null then");
1983 return false;
1984 }
1985 bool isCallable = false;
1986 napi_is_callable(env, then, &isCallable);
1987 if (!isCallable) {
1988 TAG_LOGE(AAFwkTag::UIABILITY, "not callable");
1989 return false;
1990 }
1991 HandleScope handleScope(jsRuntime_);
1992 napi_value promiseCallback = nullptr;
1993 napi_create_function(env, "promiseCallback", strlen("promiseCallback"), PromiseCallback,
1994 callbackInfo, &promiseCallback);
1995 napi_value argv[1] = { promiseCallback };
1996 napi_call_function(env, result, then, 1, argv, nullptr);
1997 TAG_LOGD(AAFwkTag::UIABILITY, "end");
1998 return true;
1999 }
2000
CallPromise(napi_value result,AppExecFwk::AbilityTransactionCallbackInfo<int32_t> * callbackInfo)2001 bool JsUIAbility::CallPromise(napi_value result, AppExecFwk::AbilityTransactionCallbackInfo<int32_t> *callbackInfo)
2002 {
2003 TAG_LOGI(AAFwkTag::UIABILITY, "called");
2004 auto env = jsRuntime_.GetNapiEnv();
2005 if (!CheckTypeForNapiValue(env, result, napi_object)) {
2006 TAG_LOGE(AAFwkTag::UIABILITY, "convert error");
2007 return false;
2008 }
2009 napi_value then = nullptr;
2010 napi_get_named_property(env, result, "then", &then);
2011 if (then == nullptr) {
2012 TAG_LOGE(AAFwkTag::UIABILITY, "null then");
2013 return false;
2014 }
2015 bool isCallable = false;
2016 napi_is_callable(env, then, &isCallable);
2017 if (!isCallable) {
2018 TAG_LOGE(AAFwkTag::UIABILITY, "not callable");
2019 return false;
2020 }
2021 HandleScope handleScope(jsRuntime_);
2022 napi_value promiseCallback = nullptr;
2023 napi_create_function(env, nullptr, NAPI_AUTO_LENGTH, OnContinuePromiseCallback,
2024 callbackInfo, &promiseCallback);
2025 napi_value argv[2] = { promiseCallback, promiseCallback };
2026 napi_call_function(env, result, then, PROMISE_CALLBACK_PARAM_NUM, argv, nullptr);
2027 TAG_LOGI(AAFwkTag::UIABILITY, "end");
2028 return true;
2029 }
2030
CallPromise(napi_value result,AppExecFwk::AbilityTransactionCallbackInfo<bool> * callbackInfo)2031 bool JsUIAbility::CallPromise(napi_value result, AppExecFwk::AbilityTransactionCallbackInfo<bool> *callbackInfo)
2032 {
2033 TAG_LOGI(AAFwkTag::UIABILITY, "called");
2034 auto env = jsRuntime_.GetNapiEnv();
2035 if (!CheckTypeForNapiValue(env, result, napi_object)) {
2036 TAG_LOGE(AAFwkTag::UIABILITY, "convert error");
2037 return false;
2038 }
2039 napi_value then = nullptr;
2040 napi_get_named_property(env, result, "then", &then);
2041 if (then == nullptr) {
2042 TAG_LOGE(AAFwkTag::UIABILITY, "null then");
2043 return false;
2044 }
2045 bool isCallable = false;
2046 napi_is_callable(env, then, &isCallable);
2047 if (!isCallable) {
2048 TAG_LOGE(AAFwkTag::UIABILITY, "not callable");
2049 return false;
2050 }
2051 HandleScope handleScope(jsRuntime_);
2052 napi_value promiseCallback = nullptr;
2053 napi_create_function(env, "promiseCallback", strlen("promiseCallback"),
2054 OnPrepareTerminatePromiseCallback, callbackInfo, &promiseCallback);
2055 napi_value argv[1] = { promiseCallback };
2056 napi_call_function(env, result, then, 1, argv, nullptr);
2057 TAG_LOGI(AAFwkTag::UIABILITY, "end");
2058 return true;
2059 }
2060
CallSaveStatePromise(napi_value result,CallOnSaveStateInfo info)2061 int32_t JsUIAbility::CallSaveStatePromise(napi_value result, CallOnSaveStateInfo info)
2062 {
2063 auto env = jsRuntime_.GetNapiEnv();
2064 if (!CheckPromise(result)) {
2065 TAG_LOGE(AAFwkTag::UIABILITY, "check orpromise error");
2066 return CALL_BACK_ERROR;
2067 }
2068 if (!CheckTypeForNapiValue(env, result, napi_object)) {
2069 TAG_LOGE(AAFwkTag::UIABILITY, "check type error");
2070 return CALL_BACK_ERROR;
2071 }
2072 napi_value then = nullptr;
2073 napi_get_named_property(env, result, "then", &then);
2074 if (then == nullptr) {
2075 TAG_LOGE(AAFwkTag::UIABILITY, "null then");
2076 return CALL_BACK_ERROR;
2077 }
2078 bool isCallable = false;
2079 napi_is_callable(env, then, &isCallable);
2080 if (!isCallable) {
2081 TAG_LOGE(AAFwkTag::UIABILITY, "not callable");
2082 return CALL_BACK_ERROR;
2083 }
2084 napi_value promiseCallback = nullptr;
2085 napi_create_function(env, "promiseCallback", strlen("promiseCallback"),
2086 OnSaveStateCallback, &info, &promiseCallback);
2087 napi_value argv[1] = { promiseCallback };
2088 napi_call_function(env, result, then, 1, argv, nullptr);
2089 return ERR_OK;
2090 }
2091
Dump(const std::vector<std::string> & params,std::vector<std::string> & info)2092 void JsUIAbility::Dump(const std::vector<std::string> ¶ms, std::vector<std::string> &info)
2093 {
2094 UIAbility::Dump(params, info);
2095 TAG_LOGD(AAFwkTag::UIABILITY, "called");
2096 HandleScope handleScope(jsRuntime_);
2097 auto env = jsRuntime_.GetNapiEnv();
2098 // create js array object of params
2099 napi_value argv[] = { CreateNativeArray(env, params) };
2100 napi_value dumpInfo = CallObjectMethod("dump", argv, ArraySize(argv), true);
2101 napi_value onDumpInfo = CallObjectMethod("onDump", argv, ArraySize(argv), true);
2102
2103 GetDumpInfo(env, dumpInfo, onDumpInfo, info);
2104 TAG_LOGD(AAFwkTag::UIABILITY, "dump info size: %{public}zu", info.size());
2105 }
2106
GetDumpInfo(napi_env env,napi_value dumpInfo,napi_value onDumpInfo,std::vector<std::string> & info)2107 void JsUIAbility::GetDumpInfo(
2108 napi_env env, napi_value dumpInfo, napi_value onDumpInfo, std::vector<std::string> &info)
2109 {
2110 if (dumpInfo != nullptr) {
2111 uint32_t len = 0;
2112 napi_get_array_length(env, dumpInfo, &len);
2113 for (uint32_t i = 0; i < len; i++) {
2114 std::string dumpInfoStr;
2115 napi_value element = nullptr;
2116 napi_get_element(env, dumpInfo, i, &element);
2117 if (!ConvertFromJsValue(env, element, dumpInfoStr)) {
2118 TAG_LOGE(AAFwkTag::UIABILITY, "parse dumpInfoStr failed");
2119 return;
2120 }
2121 info.push_back(dumpInfoStr);
2122 }
2123 }
2124
2125 if (onDumpInfo != nullptr) {
2126 uint32_t len = 0;
2127 napi_get_array_length(env, onDumpInfo, &len);
2128 for (uint32_t i = 0; i < len; i++) {
2129 std::string dumpInfoStr;
2130 napi_value element = nullptr;
2131 napi_get_element(env, onDumpInfo, i, &element);
2132 if (!ConvertFromJsValue(env, element, dumpInfoStr)) {
2133 TAG_LOGE(AAFwkTag::UIABILITY, "invalid dumpInfoStr from onDumpInfoNative");
2134 return;
2135 }
2136 info.push_back(dumpInfoStr);
2137 }
2138 }
2139 }
2140
GetJsAbility()2141 std::shared_ptr<NativeReference> JsUIAbility::GetJsAbility()
2142 {
2143 TAG_LOGD(AAFwkTag::UIABILITY, "called");
2144 if (jsAbilityObj_ == nullptr) {
2145 TAG_LOGE(AAFwkTag::UIABILITY, "null jsAbilityObj_");
2146 }
2147 return jsAbilityObj_;
2148 }
2149
SetNewRuleFlagToCallee(napi_env env,napi_value remoteJsObj)2150 sptr<IRemoteObject> JsUIAbility::SetNewRuleFlagToCallee(napi_env env, napi_value remoteJsObj)
2151 {
2152 if (!CheckTypeForNapiValue(env, remoteJsObj, napi_object)) {
2153 TAG_LOGE(AAFwkTag::UIABILITY, "null callee");
2154 return nullptr;
2155 }
2156 napi_value setFlagMethod = nullptr;
2157 napi_get_named_property(env, remoteJsObj, "setNewRuleFlag", &setFlagMethod);
2158 bool isCallable = false;
2159 napi_is_callable(env, setFlagMethod, &isCallable);
2160 if (!isCallable) {
2161 TAG_LOGE(AAFwkTag::UIABILITY, "setFlagMethod: %{public}s", setFlagMethod == nullptr ? "nullptr" : "not func");
2162 return nullptr;
2163 }
2164 auto flag = CreateJsValue(env, IsUseNewStartUpRule());
2165 napi_value argv[1] = { flag };
2166 napi_call_function(env, remoteJsObj, setFlagMethod, 1, argv, nullptr);
2167
2168 auto remoteObj = NAPI_ohos_rpc_getNativeRemoteObject(env, remoteJsObj);
2169 if (remoteObj == nullptr) {
2170 TAG_LOGE(AAFwkTag::UIABILITY, "null remoteObj");
2171 return nullptr;
2172 }
2173 return remoteObj;
2174 }
2175 #ifdef SUPPORT_SCREEN
UpdateJsWindowStage(napi_value windowStage)2176 void JsUIAbility::UpdateJsWindowStage(napi_value windowStage)
2177 {
2178 TAG_LOGD(AAFwkTag::UIABILITY, "called");
2179 if (shellContextRef_ == nullptr) {
2180 TAG_LOGE(AAFwkTag::UIABILITY, "null shellContextRef_");
2181 return;
2182 }
2183 napi_value contextObj = shellContextRef_->GetNapiValue();
2184 napi_env env = jsRuntime_.GetNapiEnv();
2185 if (!CheckTypeForNapiValue(env, contextObj, napi_object)) {
2186 TAG_LOGE(AAFwkTag::UIABILITY, "get native context obj failed");
2187 return;
2188 }
2189 if (windowStage == nullptr) {
2190 TAG_LOGE(AAFwkTag::UIABILITY, "null windowStage");
2191 napi_set_named_property(env, contextObj, "windowStage", CreateJsUndefined(env));
2192 return;
2193 }
2194 TAG_LOGD(AAFwkTag::UIABILITY, "set context windowStage");
2195 napi_set_named_property(env, contextObj, "windowStage", windowStage);
2196 }
2197 #endif
CheckSatisfyTargetAPIVersion(int32_t version)2198 bool JsUIAbility::CheckSatisfyTargetAPIVersion(int32_t version)
2199 {
2200 auto applicationInfo = GetApplicationInfo();
2201 if (!applicationInfo) {
2202 TAG_LOGE(AAFwkTag::UIABILITY, "null targetAPIVersion");
2203 return false;
2204 }
2205 TAG_LOGD(AAFwkTag::UIABILITY, "targetAPIVersion: %{public}d", applicationInfo->apiTargetVersion);
2206 return applicationInfo->apiTargetVersion % API_VERSION_MOD >= version;
2207 }
2208
BackPressDefaultValue()2209 bool JsUIAbility::BackPressDefaultValue()
2210 {
2211 return CheckSatisfyTargetAPIVersion(API12) ? true : false;
2212 }
2213
OnAfterFocusedCommon(bool isFocused)2214 void JsUIAbility::OnAfterFocusedCommon(bool isFocused)
2215 {
2216 auto abilityContext = GetAbilityContext();
2217 if (abilityContext == nullptr) {
2218 TAG_LOGE(AAFwkTag::UIABILITY, "null abilityContext");
2219 return;
2220 }
2221 auto applicationContext = abilityContext->GetApplicationContext();
2222 if (applicationContext == nullptr || applicationContext->IsAbilityLifecycleCallbackEmpty()) {
2223 TAG_LOGD(AAFwkTag::UIABILITY, "null applicationContext or lifecycleCallback");
2224 return;
2225 }
2226 if (isFocused) {
2227 applicationContext->DispatchWindowStageFocus(GetJsAbility(), GetJsWindowStage());
2228 } else {
2229 applicationContext->DispatchWindowStageUnfocus(GetJsAbility(), GetJsWindowStage());
2230 }
2231 }
2232
SetContinueState(int32_t state)2233 void JsUIAbility::SetContinueState(int32_t state)
2234 {
2235 if (scene_ == nullptr) {
2236 TAG_LOGW(AAFwkTag::UIABILITY, "windowScene is nullptr.");
2237 return;
2238 }
2239 auto window = scene_->GetMainWindow();
2240 if (window == nullptr) {
2241 TAG_LOGE(AAFwkTag::UIABILITY, "window is nullptr.");
2242 return;
2243 }
2244 window->SetContinueState(state);
2245 TAG_LOGI(AAFwkTag::UIABILITY, "window SetContinueState, state: %{public}d.", state);
2246 }
2247
NotifyWindowDestroy()2248 void JsUIAbility::NotifyWindowDestroy()
2249 {
2250 if (scene_ == nullptr) {
2251 TAG_LOGE(AAFwkTag::UIABILITY, "windowScene is nullptr.");
2252 return;
2253 }
2254 TAG_LOGI(AAFwkTag::UIABILITY, "Notify scene to destroy Window.");
2255 Rosen::WMError ret = scene_->GoDestroyHookWindow();
2256 if (ret != Rosen::WMError::WM_OK) {
2257 TAG_LOGW(AAFwkTag::UIABILITY, "scene return error.");
2258 }
2259 }
2260 } // namespace AbilityRuntime
2261 } // namespace OHOS
2262