1 /*
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <cstdlib>
17 #include <regex>
18
19 #include "system_ability_definition.h"
20 #include "if_system_ability_manager.h"
21 #include "ability_delegator_registry.h"
22 #include "ability_runtime/js_ability.h"
23
24 #include "ability_runtime/js_ability_context.h"
25 #include "ability_start_setting.h"
26 #include "connection_manager.h"
27 #include "hilog_tag_wrapper.h"
28 #include "js_data_struct_converter.h"
29 #include "js_runtime.h"
30 #include "js_runtime_utils.h"
31 #include "napi_common_configuration.h"
32 #ifdef SUPPORT_GRAPHICS
33 #include "js_window_stage.h"
34 #endif
35 #include "napi_common_want.h"
36 #include "napi_remote_object.h"
37 #include "scene_board_judgement.h"
38 #include "string_wrapper.h"
39 #include "time_util.h"
40 #include "context/context.h"
41 #include "context/application_context.h"
42 #include "hitrace_meter.h"
43
44 namespace OHOS {
45 namespace AbilityRuntime {
46 namespace {
47 #ifdef SUPPORT_GRAPHICS
48 const std::string METHOD_NAME = "WindowScene::GoForeground";
49 #endif
PromiseCallback(napi_env env,napi_callback_info info)50 napi_value PromiseCallback(napi_env env, napi_callback_info info)
51 {
52 void *data = nullptr;
53 NAPI_CALL_NO_THROW(napi_get_cb_info(env, info, nullptr, nullptr, nullptr, &data), nullptr);
54 auto *callbackInfo = static_cast<AppExecFwk::AbilityTransactionCallbackInfo<> *>(data);
55 callbackInfo->Call();
56 AppExecFwk::AbilityTransactionCallbackInfo<>::Destroy(callbackInfo);
57 data = nullptr;
58 return nullptr;
59 }
60 }
61
AttachJsAbilityContext(napi_env env,void * value,void *)62 napi_value AttachJsAbilityContext(napi_env env, void *value, void *)
63 {
64 TAG_LOGD(AAFwkTag::ABILITY, "called");
65 if (value == nullptr) {
66 TAG_LOGW(AAFwkTag::ABILITY, "invalid parameter");
67 return nullptr;
68 }
69 auto ptr = reinterpret_cast<std::weak_ptr<AbilityRuntime::AbilityContext>*>(value)->lock();
70 if (ptr == nullptr) {
71 TAG_LOGW(AAFwkTag::ABILITY, "invalid context");
72 return nullptr;
73 }
74 napi_value object = CreateJsAbilityContext(env, ptr);
75 auto systemModule = JsRuntime::LoadSystemModuleByEngine(env, "application.AbilityContext", &object, 1);
76 if (systemModule == nullptr) {
77 TAG_LOGW(AAFwkTag::ABILITY, "invalid systemModule");
78 return nullptr;
79 }
80 auto contextObj = systemModule->GetNapiValue();
81 napi_coerce_to_native_binding_object(env, contextObj, DetachCallbackFunc, AttachJsAbilityContext, value, nullptr);
82 auto workContext = new (std::nothrow) std::weak_ptr<AbilityRuntime::AbilityContext>(ptr);
83 napi_status status = napi_wrap(env, contextObj, workContext,
84 [](napi_env, void* data, void*) {
85 TAG_LOGD(AAFwkTag::ABILITY, "finalizer for weak_ptr ability context is called");
86 delete static_cast<std::weak_ptr<AbilityRuntime::AbilityContext> *>(data);
87 },
88 nullptr, nullptr);
89 if (status != napi_ok && workContext != nullptr) {
90 TAG_LOGE(AAFwkTag::ABILITY, "napi_wrap Failed: %{public}d", status);
91 delete workContext;
92 return nullptr;
93 }
94
95 return contextObj;
96 }
97
Create(const std::unique_ptr<Runtime> & runtime)98 Ability *JsAbility::Create(const std::unique_ptr<Runtime> &runtime)
99 {
100 return new JsAbility(static_cast<JsRuntime &>(*runtime));
101 }
102
JsAbility(JsRuntime & jsRuntime)103 JsAbility::JsAbility(JsRuntime &jsRuntime) : jsRuntime_(jsRuntime)
104 {}
~JsAbility()105 JsAbility::~JsAbility()
106 {
107 TAG_LOGD(AAFwkTag::ABILITY, "destructor");
108 auto context = GetAbilityContext();
109 if (context) {
110 context->Unbind();
111 }
112
113 jsRuntime_.FreeNativeReference(std::move(jsAbilityObj_));
114 jsRuntime_.FreeNativeReference(std::move(shellContextRef_));
115 #ifdef SUPPORT_GRAPHICS
116 jsRuntime_.FreeNativeReference(std::move(jsWindowStageObj_));
117 #endif
118 }
119
Init(const std::shared_ptr<AbilityInfo> & abilityInfo,const std::shared_ptr<OHOSApplication> application,std::shared_ptr<AbilityHandler> & handler,const sptr<IRemoteObject> & token)120 void JsAbility::Init(const std::shared_ptr<AbilityInfo> &abilityInfo,
121 const std::shared_ptr<OHOSApplication> application, std::shared_ptr<AbilityHandler> &handler,
122 const sptr<IRemoteObject> &token)
123 {
124 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
125 Ability::Init(abilityInfo, application, handler, token);
126
127 if (!abilityInfo) {
128 TAG_LOGE(AAFwkTag::ABILITY, "null abilityInfo");
129 return;
130 }
131 auto srcPath = GenerateSrcPath(abilityInfo);
132 if (srcPath.empty()) {
133 return;
134 }
135
136 std::string moduleName(abilityInfo->moduleName);
137 moduleName.append("::").append(abilityInfo->name);
138
139 HandleScope handleScope(jsRuntime_);
140
141 jsAbilityObj_ = jsRuntime_.LoadModule(
142 moduleName, srcPath, abilityInfo->hapPath, abilityInfo->compileMode == AppExecFwk::CompileMode::ES_MODULE);
143 if (jsAbilityObj_ == nullptr) {
144 TAG_LOGE(AAFwkTag::ABILITY, "AbilityStage object failed");
145 return;
146 }
147
148 BindContext();
149 }
150
GenerateSrcPath(std::shared_ptr<AbilityInfo> abilityInfo) const151 std::string JsAbility::GenerateSrcPath(std::shared_ptr<AbilityInfo> abilityInfo) const
152 {
153 if (abilityInfo == nullptr) {
154 TAG_LOGE(AAFwkTag::ABILITY, "null abilityInfo");
155 return "";
156 }
157
158 std::string srcPath(abilityInfo->package);
159 if (!abilityInfo->isModuleJson) {
160 /* temporary compatibility api8 + config.json */
161 srcPath.append("/assets/js/");
162 if (!abilityInfo->srcPath.empty()) {
163 srcPath.append(abilityInfo->srcPath);
164 }
165 srcPath.append("/").append(abilityInfo->name).append(".abc");
166 } else {
167 if (abilityInfo->srcEntrance.empty()) {
168 TAG_LOGE(AAFwkTag::ABILITY, "abilityInfo srcEntrance empty");
169 return "";
170 }
171 srcPath.append("/");
172 srcPath.append(abilityInfo->srcEntrance);
173 srcPath.erase(srcPath.rfind("."));
174 srcPath.append(".abc");
175 TAG_LOGI(AAFwkTag::ABILITY, "%{public}s", srcPath.c_str());
176 }
177 return srcPath;
178 }
179
BindContext()180 void JsAbility::BindContext()
181 {
182 auto env = jsRuntime_.GetNapiEnv();
183 napi_value obj = jsAbilityObj_->GetNapiValue();
184 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
185 TAG_LOGE(AAFwkTag::ABILITY, "check type failed");
186 return;
187 }
188
189 auto context = GetAbilityContext();
190 napi_value contextObj = CreateJsAbilityContext(env, context);
191 shellContextRef_ = std::shared_ptr<NativeReference>(JsRuntime::LoadSystemModuleByEngine(
192 env, "application.AbilityContext", &contextObj, 1).release());
193 if (shellContextRef_ == nullptr) {
194 TAG_LOGE(AAFwkTag::ABILITY, "load module failed");
195 return;
196 }
197 contextObj = shellContextRef_->GetNapiValue();
198 if (!CheckTypeForNapiValue(env, contextObj, napi_object)) {
199 TAG_LOGE(AAFwkTag::ABILITY, "ability native object failed");
200 return;
201 }
202 auto workContext = new (std::nothrow) std::weak_ptr<AbilityRuntime::AbilityContext>(context);
203 napi_coerce_to_native_binding_object(
204 env, contextObj, DetachCallbackFunc, AttachJsAbilityContext, workContext, nullptr);
205 context->Bind(jsRuntime_, shellContextRef_.get());
206 napi_set_named_property(env, obj, "context", contextObj);
207 TAG_LOGD(AAFwkTag::ABILITY, "set ability context");
208
209 napi_status status = napi_wrap(env, contextObj, workContext,
210 [](napi_env, void *data, void *) {
211 TAG_LOGD(AAFwkTag::ABILITY, "finalizer for weak_ptr ability context is called");
212 delete static_cast<std::weak_ptr<AbilityRuntime::AbilityContext> *>(data);
213 },
214 nullptr, nullptr);
215 if (status != napi_ok && workContext != nullptr) {
216 TAG_LOGE(AAFwkTag::ABILITY, "napi_wrap Failed: %{public}d", status);
217 delete workContext;
218 return;
219 }
220 }
221
OnStart(const Want & want,sptr<AAFwk::SessionInfo> sessionInfo)222 void JsAbility::OnStart(const Want &want, sptr<AAFwk::SessionInfo> sessionInfo)
223 {
224 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
225 TAG_LOGD(AAFwkTag::ABILITY, "begin, ability: %{public}s", GetAbilityName().c_str());
226 Ability::OnStart(want, sessionInfo);
227
228 if (!jsAbilityObj_) {
229 TAG_LOGW(AAFwkTag::ABILITY, "not found Ability.js");
230 return;
231 }
232
233 HandleScope handleScope(jsRuntime_);
234 auto env = jsRuntime_.GetNapiEnv();
235
236 napi_value obj = jsAbilityObj_->GetNapiValue();
237 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
238 TAG_LOGE(AAFwkTag::ABILITY, "Ability object failed");
239 return;
240 }
241
242 napi_value jsWant = OHOS::AppExecFwk::WrapWant(env, want);
243 if (jsWant == nullptr) {
244 TAG_LOGE(AAFwkTag::ABILITY, "null jsWant");
245 return;
246 }
247
248 napi_set_named_property(env, obj, "launchWant", jsWant);
249 napi_set_named_property(env, obj, "lastRequestWant", jsWant);
250
251 napi_value argv[] = {
252 jsWant,
253 CreateJsLaunchParam(env, GetLaunchParam()),
254 };
255 std::string methodName = "OnStart";
256 AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
257 CallObjectMethod("onCreate", argv, ArraySize(argv));
258 AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
259
260 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
261 if (delegator) {
262 TAG_LOGD(AAFwkTag::ABILITY, "call PostPerformStart");
263 delegator->PostPerformStart(CreateADelegatorAbilityProperty());
264 }
265 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
266 if (applicationContext != nullptr) {
267 applicationContext->DispatchOnAbilityCreate(jsAbilityObj_);
268 }
269 TAG_LOGD(AAFwkTag::ABILITY, "end, ability:%{public}s", GetAbilityName().c_str());
270 }
271
AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState state,const std::string & methodName) const272 void JsAbility::AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState state, const std::string &methodName) const
273 {
274 FreezeUtil::LifecycleFlow flow = { AbilityContext::token_, state };
275 auto entry = std::string("JsAbility::") + methodName + "; the " + methodName + " begin";
276 FreezeUtil::GetInstance().AddLifecycleEvent(flow, entry);
277 }
278
AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState state,const std::string & methodName) const279 void JsAbility::AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState state, const std::string &methodName) const
280 {
281 FreezeUtil::LifecycleFlow flow = { AbilityContext::token_, state };
282 auto entry = std::string("JsAbility::") + methodName + "; the " + methodName + " end";
283 FreezeUtil::GetInstance().AddLifecycleEvent(flow, entry);
284 }
285
OnShare(WantParams & wantParam)286 int32_t JsAbility::OnShare(WantParams &wantParam)
287 {
288 TAG_LOGD(AAFwkTag::ABILITY, "called");
289 HandleScope handleScope(jsRuntime_);
290 auto env = jsRuntime_.GetNapiEnv();
291 if (jsAbilityObj_ == nullptr) {
292 TAG_LOGE(AAFwkTag::ABILITY, "AbilityStage object failed");
293 return ERR_INVALID_VALUE;
294 }
295 napi_value obj = jsAbilityObj_->GetNapiValue();
296 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
297 TAG_LOGE(AAFwkTag::ABILITY, "Ability object failed");
298 return ERR_INVALID_VALUE;
299 }
300
301 napi_value jsWantParams = OHOS::AppExecFwk::WrapWantParams(env, wantParam);
302 napi_value argv[] = {
303 jsWantParams,
304 };
305 CallObjectMethod("onShare", argv, ArraySize(argv));
306 OHOS::AppExecFwk::UnwrapWantParams(env, jsWantParams, wantParam);
307 return ERR_OK;
308 }
309
OnStop()310 void JsAbility::OnStop()
311 {
312 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
313 TAG_LOGD(AAFwkTag::ABILITY, "called");
314 if (abilityContext_) {
315 TAG_LOGD(AAFwkTag::ABILITY, "set terminating true");
316 abilityContext_->SetTerminating(true);
317 }
318 Ability::OnStop();
319 HandleScope handleScope(jsRuntime_);
320 CallObjectMethod("onDestroy");
321 OnStopCallback();
322 }
323
OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> * callbackInfo,bool & isAsyncCallback)324 void JsAbility::OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo, bool &isAsyncCallback)
325 {
326 if (callbackInfo == nullptr) {
327 isAsyncCallback = false;
328 OnStop();
329 return;
330 }
331
332 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
333 TAG_LOGD(AAFwkTag::ABILITY, "called");
334 if (abilityContext_) {
335 TAG_LOGD(AAFwkTag::ABILITY, "set terminating true");
336 abilityContext_->SetTerminating(true);
337 }
338
339 Ability::OnStop();
340
341 HandleScope handleScope(jsRuntime_);
342 napi_value result = CallObjectMethod("onDestroy", nullptr, 0, true);
343 if (!CheckPromise(result)) {
344 OnStopCallback();
345 isAsyncCallback = false;
346 return;
347 }
348
349 std::weak_ptr<Ability> weakPtr = shared_from_this();
350 auto asyncCallback = [abilityWeakPtr = weakPtr]() {
351 auto ability = abilityWeakPtr.lock();
352 if (ability == nullptr) {
353 TAG_LOGE(AAFwkTag::ABILITY, "null ability");
354 return;
355 }
356 ability->OnStopCallback();
357 };
358 callbackInfo->Push(asyncCallback);
359 isAsyncCallback = CallPromise(result, callbackInfo);
360 if (!isAsyncCallback) {
361 TAG_LOGE(AAFwkTag::ABILITY, "call promise");
362 OnStopCallback();
363 }
364 }
365
OnStopCallback()366 void JsAbility::OnStopCallback()
367 {
368 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
369 if (delegator) {
370 TAG_LOGD(AAFwkTag::ABILITY, "call PostPerformStop");
371 delegator->PostPerformStop(CreateADelegatorAbilityProperty());
372 }
373
374 bool ret = ConnectionManager::GetInstance().DisconnectCaller(AbilityContext::token_);
375 if (ret) {
376 ConnectionManager::GetInstance().ReportConnectionLeakEvent(getpid(), gettid());
377 TAG_LOGD(AAFwkTag::ABILITY, "service connection not disconnected");
378 }
379
380 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
381 if (applicationContext != nullptr) {
382 applicationContext->DispatchOnAbilityDestroy(jsAbilityObj_);
383 }
384 }
385
386 #ifdef SUPPORT_GRAPHICS
387 const std::string PAGE_STACK_PROPERTY_NAME = "pageStack";
388 const std::string SUPPORT_CONTINUE_PAGE_STACK_PROPERTY_NAME = "ohos.extra.param.key.supportContinuePageStack";
389
OnSceneCreated()390 void JsAbility::OnSceneCreated()
391 {
392 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
393 TAG_LOGD(AAFwkTag::ABILITY, "ability: %{public}s", GetAbilityName().c_str());
394 Ability::OnSceneCreated();
395 auto jsAppWindowStage = CreateAppWindowStage();
396 if (jsAppWindowStage == nullptr) {
397 TAG_LOGE(AAFwkTag::ABILITY, "create jsAppWindowStage object");
398 return;
399 }
400
401 HandleScope handleScope(jsRuntime_);
402 napi_value argv[] = {jsAppWindowStage->GetNapiValue()};
403 {
404 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, "onWindowStageCreate");
405 std::string methodName = "OnSceneCreated";
406 AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
407 CallObjectMethod("onWindowStageCreate", argv, ArraySize(argv));
408 AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
409 }
410
411 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
412 if (delegator) {
413 TAG_LOGD(AAFwkTag::ABILITY, "call PostPerformScenceCreated");
414 delegator->PostPerformScenceCreated(CreateADelegatorAbilityProperty());
415 }
416
417 jsWindowStageObj_ = std::shared_ptr<NativeReference>(jsAppWindowStage.release());
418 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
419 if (applicationContext != nullptr) {
420 applicationContext->DispatchOnWindowStageCreate(jsAbilityObj_, jsWindowStageObj_);
421 }
422
423 TAG_LOGD(AAFwkTag::ABILITY, "end, ability:%{public}s", GetAbilityName().c_str());
424 }
425
OnSceneRestored()426 void JsAbility::OnSceneRestored()
427 {
428 Ability::OnSceneRestored();
429 TAG_LOGD(AAFwkTag::ABILITY, "called");
430 HandleScope handleScope(jsRuntime_);
431 auto jsAppWindowStage = CreateAppWindowStage();
432 if (jsAppWindowStage == nullptr) {
433 TAG_LOGE(AAFwkTag::ABILITY, "create jsAppWindowStage object");
434 return;
435 }
436 napi_value argv[] = {jsAppWindowStage->GetNapiValue()};
437 CallObjectMethod("onWindowStageRestore", argv, ArraySize(argv));
438
439 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
440 if (delegator) {
441 TAG_LOGD(AAFwkTag::ABILITY, "call PostPerformScenceRestored");
442 delegator->PostPerformScenceRestored(CreateADelegatorAbilityProperty());
443 }
444
445 jsWindowStageObj_ = std::shared_ptr<NativeReference>(jsAppWindowStage.release());
446 }
447
onSceneDestroyed()448 void JsAbility::onSceneDestroyed()
449 {
450 TAG_LOGD(AAFwkTag::ABILITY, "begin, ability:%{public}s", GetAbilityName().c_str());
451 Ability::onSceneDestroyed();
452 HandleScope handleScope(jsRuntime_);
453 CallObjectMethod("onWindowStageDestroy");
454
455 if (scene_ != nullptr) {
456 auto window = scene_->GetMainWindow();
457 if (window != nullptr) {
458 TAG_LOGD(AAFwkTag::ABILITY, "call UnregisterDisplayMoveListener");
459 window->UnregisterDisplayMoveListener(abilityDisplayMoveListener_);
460 }
461 }
462
463 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
464 if (delegator) {
465 TAG_LOGD(AAFwkTag::ABILITY, "call PostPerformScenceDestroyed");
466 delegator->PostPerformScenceDestroyed(CreateADelegatorAbilityProperty());
467 }
468
469 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
470 if (applicationContext != nullptr) {
471 applicationContext->DispatchOnWindowStageDestroy(jsAbilityObj_, jsWindowStageObj_);
472 }
473 TAG_LOGD(AAFwkTag::ABILITY, "end, ability:%{public}s", GetAbilityName().c_str());
474 }
475
OnForeground(const Want & want)476 void JsAbility::OnForeground(const Want &want)
477 {
478 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
479 TAG_LOGD(AAFwkTag::ABILITY, "begin, ability:%{public}s", GetAbilityName().c_str());
480 if (abilityInfo_) {
481 jsRuntime_.UpdateModuleNameAndAssetPath(abilityInfo_->moduleName);
482 }
483
484 Ability::OnForeground(want);
485
486 HandleScope handleScope(jsRuntime_);
487 auto env = jsRuntime_.GetNapiEnv();
488 if (jsAbilityObj_ == nullptr) {
489 TAG_LOGE(AAFwkTag::ABILITY, "AbilityStage object failed");
490 return;
491 }
492 napi_value obj = jsAbilityObj_->GetNapiValue();
493 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
494 TAG_LOGE(AAFwkTag::ABILITY, "Ability object failed");
495 return;
496 }
497
498 napi_value jsWant = OHOS::AppExecFwk::WrapWant(env, want);
499 if (jsWant == nullptr) {
500 TAG_LOGE(AAFwkTag::ABILITY, "null jsWant");
501 return;
502 }
503
504 napi_set_named_property(env, obj, "lastRequestWant", jsWant);
505 std::string methodName = "OnForeground";
506 AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
507 CallObjectMethod("onForeground", &jsWant, 1);
508 AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
509
510 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
511 if (delegator) {
512 TAG_LOGD(AAFwkTag::ABILITY, "call PostPerformForeground");
513 delegator->PostPerformForeground(CreateADelegatorAbilityProperty());
514 }
515
516 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
517 if (applicationContext != nullptr) {
518 applicationContext->DispatchOnAbilityForeground(jsAbilityObj_);
519 }
520 TAG_LOGD(AAFwkTag::ABILITY, "end, ability:%{public}s", GetAbilityName().c_str());
521 }
522
OnBackground()523 void JsAbility::OnBackground()
524 {
525 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
526 TAG_LOGD(AAFwkTag::ABILITY, "begin, ability:%{public}s", GetAbilityName().c_str());
527 std::string methodName = "OnBackground";
528 HandleScope handleScope(jsRuntime_);
529 AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::BACKGROUND, methodName);
530 CallObjectMethod("onBackground");
531 AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::BACKGROUND, methodName);
532
533 Ability::OnBackground();
534
535 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
536 if (delegator) {
537 TAG_LOGD(AAFwkTag::ABILITY, "call PostPerformBackground");
538 delegator->PostPerformBackground(CreateADelegatorAbilityProperty());
539 }
540
541 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
542 if (applicationContext != nullptr) {
543 applicationContext->DispatchOnAbilityBackground(jsAbilityObj_);
544 }
545 TAG_LOGD(AAFwkTag::ABILITY, "end, ability:%{public}s", GetAbilityName().c_str());
546 }
547
OnBackPress()548 bool JsAbility::OnBackPress()
549 {
550 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
551 TAG_LOGD(AAFwkTag::ABILITY, "call, ability:%{public}s", GetAbilityName().c_str());
552 Ability::OnBackPress();
553 HandleScope handleScope(jsRuntime_);
554 auto env = jsRuntime_.GetNapiEnv();
555 napi_value jsValue = CallObjectMethod("onBackPressed", nullptr, 0, true);
556 bool ret = false;
557 if (!ConvertFromJsValue(env, jsValue, ret)) {
558 TAG_LOGW(AAFwkTag::ABILITY, "get js value failed");
559 return false;
560 }
561 TAG_LOGD(AAFwkTag::ABILITY, "end, ret:%{public}d", ret);
562 return ret;
563 }
564
OnPrepareTerminate()565 bool JsAbility::OnPrepareTerminate()
566 {
567 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
568 TAG_LOGD(AAFwkTag::ABILITY, "call, ability: %{public}s", GetAbilityName().c_str());
569 Ability::OnPrepareTerminate();
570 HandleScope handleScope(jsRuntime_);
571 auto env = jsRuntime_.GetNapiEnv();
572 napi_value jsValue = CallObjectMethod("onPrepareToTerminate", nullptr, 0, true);
573 bool ret = false;
574 if (!ConvertFromJsValue(env, jsValue, ret)) {
575 TAG_LOGW(AAFwkTag::ABILITY, "get js value failed");
576 return false;
577 }
578 TAG_LOGD(AAFwkTag::ABILITY, "end, ret:%{public}d", ret);
579 return ret;
580 }
581
CreateAppWindowStage()582 std::unique_ptr<NativeReference> JsAbility::CreateAppWindowStage()
583 {
584 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
585 HandleScope handleScope(jsRuntime_);
586 auto env = jsRuntime_.GetNapiEnv();
587 napi_value jsWindowStage = Rosen::CreateJsWindowStage(env, GetScene());
588 if (jsWindowStage == nullptr) {
589 TAG_LOGE(AAFwkTag::ABILITY, "create jsWindowSatge object");
590 return nullptr;
591 }
592 return JsRuntime::LoadSystemModuleByEngine(env, "application.WindowStage", &jsWindowStage, 1);
593 }
594
GetPageStackFromWant(const Want & want,std::string & pageStack)595 void JsAbility::GetPageStackFromWant(const Want &want, std::string &pageStack)
596 {
597 auto stringObj = AAFwk::IString::Query(want.GetParams().GetParam(PAGE_STACK_PROPERTY_NAME));
598 if (stringObj != nullptr) {
599 pageStack = AAFwk::String::Unbox(stringObj);
600 }
601 }
602
IsRestorePageStack(const Want & want)603 bool JsAbility::IsRestorePageStack(const Want &want)
604 {
605 return want.GetBoolParam(SUPPORT_CONTINUE_PAGE_STACK_PROPERTY_NAME, true);
606 }
607
RestorePageStack(const Want & want)608 void JsAbility::RestorePageStack(const Want &want)
609 {
610 if (IsRestorePageStack(want)) {
611 std::string pageStack;
612 GetPageStackFromWant(want, pageStack);
613 HandleScope handleScope(jsRuntime_);
614 auto env = jsRuntime_.GetNapiEnv();
615 if (abilityContext_->GetContentStorage()) {
616 scene_->GetMainWindow()->NapiSetUIContent(pageStack, env,
617 abilityContext_->GetContentStorage()->GetNapiValue(), Rosen::BackupAndRestoreType::CONTINUATION);
618 } else {
619 TAG_LOGE(AAFwkTag::ABILITY, "restore: contnull ent storage");
620 }
621 }
622 }
623
AbilityContinuationOrRecover(const Want & want)624 void JsAbility::AbilityContinuationOrRecover(const Want &want)
625 {
626 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
627 // multi-instance ability continuation
628 TAG_LOGD(AAFwkTag::ABILITY, "launch reason = %{public}d", launchParam_.launchReason);
629 if (IsRestoredInContinuation()) {
630 RestorePageStack(want);
631 OnSceneRestored();
632 NotifyContinuationResult(want, true);
633 } else if (ShouldRecoverState(want)) {
634 OnSceneRestored();
635 } else {
636 OnSceneCreated();
637 }
638 }
639
DoOnForeground(const Want & want)640 void JsAbility::DoOnForeground(const Want &want)
641 {
642 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
643 if (scene_ == nullptr) {
644 if (!InitWindowScene(want)) {
645 return;
646 }
647 AbilityContinuationOrRecover(want);
648 auto window = scene_->GetMainWindow();
649 if (window) {
650 TAG_LOGD(AAFwkTag::ABILITY, "call RegisterDisplayMoveListener, windowId: %{public}d",
651 window->GetWindowId());
652 abilityDisplayMoveListener_ = new AbilityDisplayMoveListener(weak_from_this());
653 window->RegisterDisplayMoveListener(abilityDisplayMoveListener_);
654 }
655 } else {
656 auto window = scene_->GetMainWindow();
657 if (window != nullptr && want.HasParameter(Want::PARAM_RESV_WINDOW_MODE)) {
658 auto windowMode = want.GetIntParam(Want::PARAM_RESV_WINDOW_MODE,
659 AAFwk::AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_UNDEFINED);
660 window->SetWindowMode(static_cast<Rosen::WindowMode>(windowMode));
661 TAG_LOGD(AAFwkTag::ABILITY, "set window mode:%{public}d", windowMode);
662 }
663 }
664
665 auto window = scene_->GetMainWindow();
666 if (window != nullptr && securityFlag_) {
667 window->SetSystemPrivacyMode(true);
668 }
669
670 TAG_LOGI(AAFwkTag::ABILITY, "move scene to foreground, sceneFlag_:%{public}d", Ability::sceneFlag_);
671 AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, METHOD_NAME);
672 scene_->GoForeground(Ability::sceneFlag_);
673 TAG_LOGD(AAFwkTag::ABILITY, "end");
674 }
675
InitWindowScene(const Want & want)676 bool JsAbility::InitWindowScene(const Want &want)
677 {
678 if ((abilityContext_ == nullptr) || (sceneListener_ == nullptr)) {
679 TAG_LOGE(AAFwkTag::ABILITY, "null abilityContext_/scenull neListener_");
680 return false;
681 }
682 scene_ = std::make_shared<Rosen::WindowScene>();
683 int32_t displayId = static_cast<int32_t>(Rosen::DisplayManager::GetInstance().GetDefaultDisplayId());
684 if (setting_ != nullptr) {
685 std::string strDisplayId =
686 setting_->GetProperty(OHOS::AppExecFwk::AbilityStartSetting::WINDOW_DISPLAY_ID_KEY);
687 std::regex formatRegex("[0-9]{0,9}$");
688 std::smatch sm;
689 bool flag = std::regex_match(strDisplayId, sm, formatRegex);
690 if (flag && !strDisplayId.empty()) {
691 int base = 10; // Numerical base (radix) that determines the valid characters and their interpretation.
692 displayId = strtol(strDisplayId.c_str(), nullptr, base);
693 TAG_LOGD(AAFwkTag::ABILITY, "displayId:%{public}d", displayId);
694 } else {
695 TAG_LOGW(AAFwkTag::ABILITY, "formatRegex:[%{public}s]", strDisplayId.c_str());
696 }
697 }
698 auto option = GetWindowOption(want);
699 Rosen::WMError ret = Rosen::WMError::WM_OK;
700 if (Rosen::SceneBoardJudgement::IsSceneBoardEnabled()) {
701 auto sessionToken = GetSessionToken();
702 if (sessionToken == nullptr) {
703 TAG_LOGE(AAFwkTag::ABILITY, "null essionToken");
704 return false;
705 }
706 abilityContext_->SetWeakSessionToken(sessionToken);
707 ret = scene_->Init(displayId, abilityContext_, sceneListener_, option, sessionToken);
708 } else {
709 ret = scene_->Init(displayId, abilityContext_, sceneListener_, option);
710 }
711 if (ret != Rosen::WMError::WM_OK) {
712 TAG_LOGE(AAFwkTag::ABILITY, "init window scene");
713 return false;
714 }
715 return true;
716 }
717
RequestFocus(const Want & want)718 void JsAbility::RequestFocus(const Want &want)
719 {
720 TAG_LOGI(AAFwkTag::ABILITY, "begin");
721 if (scene_ == nullptr) {
722 TAG_LOGE(AAFwkTag::ABILITY, "null scene_");
723 return;
724 }
725 auto window = scene_->GetMainWindow();
726 if (window != nullptr && want.HasParameter(Want::PARAM_RESV_WINDOW_MODE)) {
727 auto windowMode = want.GetIntParam(Want::PARAM_RESV_WINDOW_MODE,
728 AAFwk::AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_UNDEFINED);
729 window->SetWindowMode(static_cast<Rosen::WindowMode>(windowMode));
730 TAG_LOGD(AAFwkTag::ABILITY, "set window mode = %{public}d", windowMode);
731 }
732 AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, METHOD_NAME);
733 scene_->GoForeground(Ability::sceneFlag_);
734 }
735
ContinuationRestore(const Want & want)736 void JsAbility::ContinuationRestore(const Want &want)
737 {
738 TAG_LOGD(AAFwkTag::ABILITY, "called");
739 if (!IsRestoredInContinuation() || scene_ == nullptr) {
740 return;
741 }
742 RestorePageStack(want);
743 OnSceneRestored();
744 NotifyContinuationResult(want, true);
745 }
746
GetJsWindowStage()747 std::shared_ptr<NativeReference> JsAbility::GetJsWindowStage()
748 {
749 TAG_LOGD(AAFwkTag::ABILITY, "called");
750 if (jsWindowStageObj_ == nullptr) {
751 TAG_LOGE(AAFwkTag::ABILITY, "jsnull WindowSatge");
752 }
753 return jsWindowStageObj_;
754 }
755
GetJsRuntime()756 const JsRuntime& JsAbility::GetJsRuntime()
757 {
758 return jsRuntime_;
759 }
760
761 #endif
762
OnContinue(WantParams & wantParams)763 int32_t JsAbility::OnContinue(WantParams &wantParams)
764 {
765 HandleScope handleScope(jsRuntime_);
766 auto env = jsRuntime_.GetNapiEnv();
767 if (jsAbilityObj_ == nullptr) {
768 TAG_LOGE(AAFwkTag::ABILITY, "AbilityStage object");
769 return AppExecFwk::ContinuationManager::OnContinueResult::REJECT;
770 }
771 napi_value obj = jsAbilityObj_->GetNapiValue();
772 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
773 TAG_LOGE(AAFwkTag::ABILITY, "Ability object");
774 return AppExecFwk::ContinuationManager::OnContinueResult::REJECT;
775 }
776
777 napi_value methodOnCreate = nullptr;
778 napi_get_named_property(env, obj, "onContinue", &methodOnCreate);
779 if (methodOnCreate == nullptr) {
780 TAG_LOGE(AAFwkTag::ABILITY, "get 'onContinue'");
781 return AppExecFwk::ContinuationManager::OnContinueResult::REJECT;
782 }
783
784 napi_value jsWantParams = OHOS::AppExecFwk::WrapWantParams(env, wantParams);
785 napi_value result = nullptr;
786 napi_call_function(env, obj, methodOnCreate, 1, &jsWantParams, &result);
787
788 OHOS::AppExecFwk::UnwrapWantParams(env, jsWantParams, wantParams);
789
790 int32_t numberResult = 0;
791 if (!ConvertFromJsValue(env, result, numberResult)) {
792 TAG_LOGE(AAFwkTag::ABILITY, "'onContinue' not implemented");
793 return AppExecFwk::ContinuationManager::OnContinueResult::REJECT;
794 }
795
796 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
797 if (applicationContext != nullptr) {
798 applicationContext->DispatchOnAbilityContinue(jsAbilityObj_);
799 }
800
801 return numberResult;
802 }
803
OnSaveState(int32_t reason,WantParams & wantParams)804 int32_t JsAbility::OnSaveState(int32_t reason, WantParams &wantParams)
805 {
806 HandleScope handleScope(jsRuntime_);
807 auto env = jsRuntime_.GetNapiEnv();
808 if (jsAbilityObj_ == nullptr) {
809 TAG_LOGE(AAFwkTag::ABILITY, "null jsAbilityObj_");
810 return -1;
811 }
812 napi_value obj = jsAbilityObj_->GetNapiValue();
813 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
814 TAG_LOGE(AAFwkTag::ABILITY, "appRecovery get Ability object");
815 return -1;
816 }
817
818 napi_value methodOnSaveState = nullptr;
819 napi_get_named_property(env, obj, "onSaveState", &methodOnSaveState);
820 if (methodOnSaveState == nullptr) {
821 TAG_LOGE(AAFwkTag::ABILITY, "null methodOnSaveState");
822 return -1;
823 }
824
825 napi_value jsWantParams = OHOS::AppExecFwk::WrapWantParams(env, wantParams);
826 napi_value jsReason = CreateJsValue(env, reason);
827 napi_value args[] = { jsReason, jsWantParams };
828 napi_value result = nullptr;
829 napi_call_function(env, obj, methodOnSaveState, 2, args, &result); // 2:args size
830 OHOS::AppExecFwk::UnwrapWantParams(env, jsWantParams, wantParams);
831
832 int32_t numberResult = 0;
833 if (!ConvertFromJsValue(env, result, numberResult)) {
834 TAG_LOGE(AAFwkTag::ABILITY, "appRecovery no result");
835 return -1;
836 }
837 return numberResult;
838 }
839
OnConfigurationUpdated(const Configuration & configuration)840 void JsAbility::OnConfigurationUpdated(const Configuration &configuration)
841 {
842 Ability::OnConfigurationUpdated(configuration);
843 TAG_LOGD(AAFwkTag::ABILITY, "called");
844
845 HandleScope handleScope(jsRuntime_);
846 auto env = jsRuntime_.GetNapiEnv();
847 auto fullConfig = GetAbilityContext()->GetConfiguration();
848 if (!fullConfig) {
849 TAG_LOGE(AAFwkTag::ABILITY, "configuration");
850 return;
851 }
852
853 napi_value napiConfiguration = OHOS::AppExecFwk::WrapConfiguration(env, configuration);
854 CallObjectMethod("onConfigurationUpdated", &napiConfiguration, 1);
855 CallObjectMethod("onConfigurationUpdate", &napiConfiguration, 1);
856 JsAbilityContext::ConfigurationUpdated(env, shellContextRef_, fullConfig);
857 }
858
OnMemoryLevel(int level)859 void JsAbility::OnMemoryLevel(int level)
860 {
861 Ability::OnMemoryLevel(level);
862 TAG_LOGD(AAFwkTag::ABILITY, "called");
863
864 HandleScope handleScope(jsRuntime_);
865 auto env = jsRuntime_.GetNapiEnv();
866 if (jsAbilityObj_ == nullptr) {
867 TAG_LOGE(AAFwkTag::ABILITY, "AbilityStage object failed");
868 return;
869 }
870 napi_value obj = jsAbilityObj_->GetNapiValue();
871 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
872 TAG_LOGE(AAFwkTag::ABILITY, "Ability object failed");
873 return;
874 }
875
876 napi_value jslevel = CreateJsValue(env, level);
877 napi_value argv[] = {
878 jslevel,
879 };
880 CallObjectMethod("onMemoryLevel", argv, ArraySize(argv));
881 }
882
UpdateContextConfiguration()883 void JsAbility::UpdateContextConfiguration()
884 {
885 TAG_LOGD(AAFwkTag::ABILITY, "called");
886 HandleScope handleScope(jsRuntime_);
887 auto env = jsRuntime_.GetNapiEnv();
888 JsAbilityContext::ConfigurationUpdated(env, shellContextRef_, GetAbilityContext()->GetConfiguration());
889 }
890
OnNewWant(const Want & want)891 void JsAbility::OnNewWant(const Want &want)
892 {
893 TAG_LOGD(AAFwkTag::ABILITY, "called");
894 Ability::OnNewWant(want);
895
896 #ifdef SUPPORT_GRAPHICS
897 if (scene_) {
898 scene_->OnNewWant(want);
899 }
900 #endif
901
902 HandleScope handleScope(jsRuntime_);
903 auto env = jsRuntime_.GetNapiEnv();
904 if (jsAbilityObj_ == nullptr) {
905 TAG_LOGE(AAFwkTag::ABILITY, "AbilityStage object failed");
906 return;
907 }
908 napi_value obj = jsAbilityObj_->GetNapiValue();
909 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
910 TAG_LOGE(AAFwkTag::ABILITY, "Ability object failed");
911 return;
912 }
913
914 napi_value jsWant = OHOS::AppExecFwk::WrapWant(env, want);
915 if (jsWant == nullptr) {
916 TAG_LOGE(AAFwkTag::ABILITY, "want failed");
917 return;
918 }
919
920 napi_set_named_property(env, obj, "lastRequestWant", jsWant);
921
922 napi_value argv[] = {
923 jsWant,
924 CreateJsLaunchParam(env, GetLaunchParam()),
925 };
926 std::string methodName = "OnNewWant";
927 AddLifecycleEventBeforeJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
928 CallObjectMethod("onNewWant", argv, ArraySize(argv));
929 AddLifecycleEventAfterJSCall(FreezeUtil::TimeoutState::FOREGROUND, methodName);
930
931 TAG_LOGD(AAFwkTag::ABILITY, "end");
932 }
933
OnAbilityResult(int requestCode,int resultCode,const Want & resultData)934 void JsAbility::OnAbilityResult(int requestCode, int resultCode, const Want &resultData)
935 {
936 TAG_LOGD(AAFwkTag::ABILITY, "called");
937 Ability::OnAbilityResult(requestCode, resultCode, resultData);
938 std::shared_ptr<AbilityRuntime::AbilityContext> context = GetAbilityContext();
939 if (context == nullptr) {
940 TAG_LOGW(AAFwkTag::ABILITY, "null context");
941 return;
942 }
943 context->OnAbilityResult(requestCode, resultCode, resultData);
944 TAG_LOGD(AAFwkTag::ABILITY, "end");
945 }
946
CallRequest()947 sptr<IRemoteObject> JsAbility::CallRequest()
948 {
949 TAG_LOGD(AAFwkTag::ABILITY, "called");
950 if (jsAbilityObj_ == nullptr) {
951 TAG_LOGW(AAFwkTag::ABILITY, "null Obj");
952 return nullptr;
953 }
954
955 if (remoteCallee_ != nullptr) {
956 TAG_LOGD(AAFwkTag::ABILITY, "get Callee remoteObj");
957 return remoteCallee_;
958 }
959
960 HandleScope handleScope(jsRuntime_);
961 TAG_LOGD(AAFwkTag::ABILITY, "set runtime scope");
962 auto env = jsRuntime_.GetNapiEnv();
963 auto obj = jsAbilityObj_->GetNapiValue();
964 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
965 TAG_LOGE(AAFwkTag::ABILITY, "object failed");
966 return nullptr;
967 }
968
969 napi_value method = nullptr;
970 napi_get_named_property(env, obj, "onCallRequest", &method);
971 bool isCallable = false;
972 napi_is_callable(env, method, &isCallable);
973 if (!isCallable) {
974 TAG_LOGE(AAFwkTag::ABILITY, "method:%{public}s",
975 method == nullptr ? "nullptr" : "not func");
976 return nullptr;
977 }
978
979 napi_value remoteJsObj = nullptr;
980 napi_call_function(env, obj, method, 0, nullptr, &remoteJsObj);
981 if (remoteJsObj == nullptr) {
982 TAG_LOGE(AAFwkTag::ABILITY, "null JsAbility::CallRenull quest JsObj");
983 return nullptr;
984 }
985
986 remoteCallee_ = SetNewRuleFlagToCallee(env, remoteJsObj);
987 TAG_LOGD(AAFwkTag::ABILITY, "end");
988 return remoteCallee_;
989 }
990
CallObjectMethod(const char * name,napi_value const * argv,size_t argc,bool withResult)991 napi_value JsAbility::CallObjectMethod(const char *name, napi_value const *argv, size_t argc, bool withResult)
992 {
993 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
994 TAG_LOGI(AAFwkTag::ABILITY, "begin:%{public}s", name);
995
996 if (!jsAbilityObj_) {
997 TAG_LOGW(AAFwkTag::ABILITY, "not found Ability.js");
998 return nullptr;
999 }
1000
1001 HandleEscape handleEscape(jsRuntime_);
1002 auto env = jsRuntime_.GetNapiEnv();
1003
1004 napi_value obj = jsAbilityObj_->GetNapiValue();
1005 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
1006 TAG_LOGE(AAFwkTag::ABILITY, "Ability object failed");
1007 return nullptr;
1008 }
1009
1010 napi_value methodOnCreate = nullptr;
1011 napi_get_named_property(env, obj, name, &methodOnCreate);
1012 if (methodOnCreate == nullptr) {
1013 TAG_LOGE(AAFwkTag::ABILITY, "'%{public}s' failed", name);
1014 return nullptr;
1015 }
1016 if (withResult) {
1017 napi_value result = nullptr;
1018 napi_call_function(env, obj, methodOnCreate, argc, argv, &result);
1019 return handleEscape.Escape(result);
1020 }
1021 napi_call_function(env, obj, methodOnCreate, argc, argv, nullptr);
1022 TAG_LOGI(AAFwkTag::ABILITY, "end:%{public}s", name);
1023 return nullptr;
1024 }
1025
CheckPromise(napi_value result)1026 bool JsAbility::CheckPromise(napi_value result)
1027 {
1028 if (result == nullptr) {
1029 TAG_LOGD(AAFwkTag::ABILITY, "null result");
1030 return false;
1031 }
1032 auto env = jsRuntime_.GetNapiEnv();
1033 bool isPromise = false;
1034 napi_is_promise(env, result, &isPromise);
1035 if (!isPromise) {
1036 TAG_LOGD(AAFwkTag::ABILITY, "result not promise");
1037 return false;
1038 }
1039 return true;
1040 }
1041
CallPromise(napi_value result,AppExecFwk::AbilityTransactionCallbackInfo<> * callbackInfo)1042 bool JsAbility::CallPromise(napi_value result, AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo)
1043 {
1044 auto env = jsRuntime_.GetNapiEnv();
1045 if (!CheckTypeForNapiValue(env, result, napi_object)) {
1046 TAG_LOGE(AAFwkTag::ABILITY, "convert native value to NativeObject failed");
1047 return false;
1048 }
1049 napi_value then = nullptr;
1050 napi_get_named_property(env, result, "then", &then);
1051 if (then == nullptr) {
1052 TAG_LOGE(AAFwkTag::ABILITY, "failed get property:then");
1053 return false;
1054 }
1055 bool isCallable = false;
1056 napi_is_callable(env, then, &isCallable);
1057 if (!isCallable) {
1058 TAG_LOGE(AAFwkTag::ABILITY, "property not callable");
1059 return false;
1060 }
1061 HandleScope handleScope(jsRuntime_);
1062 napi_value promiseCallback = nullptr;
1063 napi_create_function(env, "promiseCallback", strlen("promiseCallback"), PromiseCallback,
1064 callbackInfo, &promiseCallback);
1065 napi_value argv[1] = { promiseCallback };
1066 napi_call_function(env, result, then, 1, argv, nullptr);
1067 TAG_LOGD(AAFwkTag::ABILITY, "callPromise complete");
1068 return true;
1069 }
1070
CreateADelegatorAbilityProperty()1071 std::shared_ptr<AppExecFwk::ADelegatorAbilityProperty> JsAbility::CreateADelegatorAbilityProperty()
1072 {
1073 auto property = std::make_shared<AppExecFwk::ADelegatorAbilityProperty>();
1074 property->token_ = GetAbilityContext()->GetToken();
1075 property->name_ = GetAbilityName();
1076 property->moduleName_ = GetModuleName();
1077 if (GetApplicationInfo() == nullptr || GetApplicationInfo()->bundleName.empty()) {
1078 property->fullName_ = GetAbilityName();
1079 } else {
1080 std::string::size_type pos = GetAbilityName().find(GetApplicationInfo()->bundleName);
1081 if (pos == std::string::npos || pos != 0) {
1082 property->fullName_ = GetApplicationInfo()->bundleName + "." + GetAbilityName();
1083 } else {
1084 property->fullName_ = GetAbilityName();
1085 }
1086 }
1087 property->lifecycleState_ = GetState();
1088 property->object_ = jsAbilityObj_;
1089
1090 return property;
1091 }
1092
Dump(const std::vector<std::string> & params,std::vector<std::string> & info)1093 void JsAbility::Dump(const std::vector<std::string> ¶ms, std::vector<std::string> &info)
1094 {
1095 Ability::Dump(params, info);
1096 TAG_LOGD(AAFwkTag::ABILITY, "called");
1097 HandleScope handleScope(jsRuntime_);
1098
1099 if (!jsAbilityObj_) {
1100 TAG_LOGW(AAFwkTag::ABILITY, "not found .js");
1101 return;
1102 }
1103
1104 auto env = jsRuntime_.GetNapiEnv();
1105 napi_value obj = jsAbilityObj_->GetNapiValue();
1106 if (!CheckTypeForNapiValue(env, obj, napi_object)) {
1107 TAG_LOGE(AAFwkTag::ABILITY, "get object failed");
1108 return;
1109 }
1110
1111 if (!AddDumpInfo(env, obj, params, info, "dump")) {
1112 return;
1113 }
1114 if (!AddDumpInfo(env, obj, params, info, "onDump")) {
1115 return;
1116 }
1117
1118 TAG_LOGD(AAFwkTag::ABILITY, "dump info size:%{public}zu", info.size());
1119 }
1120
AddDumpInfo(napi_env env,napi_value obj,const std::vector<std::string> & params,std::vector<std::string> & info,const std::string & methodName) const1121 bool JsAbility::AddDumpInfo(napi_env env, napi_value obj, const std::vector<std::string> ¶ms,
1122 std::vector<std::string> &info, const std::string &methodName) const
1123 {
1124 // create js array object of params
1125 napi_value argv[] = { CreateNativeArray(env, params) };
1126
1127 napi_value method = nullptr;
1128 napi_get_named_property(env, obj, methodName.c_str(), &method);
1129
1130 napi_value dumpInfo = nullptr;
1131 if (method != nullptr) {
1132 napi_call_function(env, obj, method, 1, argv, &dumpInfo);
1133 }
1134
1135 if (dumpInfo == nullptr) {
1136 uint32_t len = 0;
1137 napi_get_array_length(env, dumpInfo, &len);
1138 for (uint32_t i = 0; i < len; i++) {
1139 std::string dumpInfoStr;
1140 napi_value element = nullptr;
1141 napi_get_element(env, dumpInfo, i, &element);
1142 if (!ConvertFromJsValue(env, element, dumpInfoStr)) {
1143 TAG_LOGE(AAFwkTag::ABILITY, "parse dumpInfoStr failed");
1144 return false;
1145 }
1146 info.push_back(dumpInfoStr);
1147 }
1148 }
1149 return true;
1150 }
1151
GetJsAbility()1152 std::shared_ptr<NativeReference> JsAbility::GetJsAbility()
1153 {
1154 TAG_LOGD(AAFwkTag::ABILITY, "called");
1155 if (jsAbilityObj_ == nullptr) {
1156 TAG_LOGE(AAFwkTag::ABILITY, "null jsAbility object");
1157 }
1158 return jsAbilityObj_;
1159 }
1160
SetNewRuleFlagToCallee(napi_env env,napi_value remoteJsObj)1161 sptr<IRemoteObject> JsAbility::SetNewRuleFlagToCallee(napi_env env, napi_value remoteJsObj)
1162 {
1163 if (!CheckTypeForNapiValue(env, remoteJsObj, napi_object)) {
1164 TAG_LOGE(AAFwkTag::ABILITY, "null calleeObj");
1165 return nullptr;
1166 }
1167 napi_value setFlagMethod = nullptr;
1168 napi_get_named_property(env, remoteJsObj, "setNewRuleFlag", &setFlagMethod);
1169 bool isCallable = false;
1170 napi_is_callable(env, setFlagMethod, &isCallable);
1171 if (!isCallable) {
1172 TAG_LOGE(AAFwkTag::ABILITY, "setFlagMethod:%{public}s",
1173 setFlagMethod == nullptr ? "nullptr" : "not func");
1174 return nullptr;
1175 }
1176 auto flag = CreateJsValue(env, IsUseNewStartUpRule());
1177 napi_value argv[1] = { flag };
1178 napi_call_function(env, remoteJsObj, setFlagMethod, 1, argv, nullptr);
1179
1180 auto remoteObj = NAPI_ohos_rpc_getNativeRemoteObject(env, remoteJsObj);
1181 if (remoteObj == nullptr) {
1182 TAG_LOGE(AAFwkTag::ABILITY, "Callnull Request obj");
1183 return nullptr;
1184 }
1185 return remoteObj;
1186 }
1187 } // namespace AbilityRuntime
1188 } // namespace OHOS
1189