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