1 /*
2 * Copyright (c) 2021-2022 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_recovery.h"
26 #include "ability_start_setting.h"
27 #include "connection_manager.h"
28 #include "hilog_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_GRAPHICS
34 #include "js_window_stage.h"
35 #endif
36 #include "napi_common_want.h"
37 #include "napi_remote_object.h"
38 #include "string_wrapper.h"
39 #include "context/context.h"
40 #include "context/application_context.h"
41 #include "hitrace_meter.h"
42
43 namespace OHOS {
44 namespace AbilityRuntime {
45 namespace {
PromiseCallback(NativeEngine * engine,NativeCallbackInfo * info)46 NativeValue *PromiseCallback(NativeEngine *engine, NativeCallbackInfo *info)
47 {
48 if (info == nullptr || info->functionInfo == nullptr || info->functionInfo->data == nullptr) {
49 HILOG_ERROR("Invalid input info.");
50 return nullptr;
51 }
52 void *data = info->functionInfo->data;
53 auto *callbackInfo = static_cast<AppExecFwk::AbilityTransactionCallbackInfo<> *>(data);
54 callbackInfo->Call();
55 AppExecFwk::AbilityTransactionCallbackInfo<>::Destroy(callbackInfo);
56 info->functionInfo->data = nullptr;
57 return nullptr;
58 }
59 }
60
AttachJsAbilityContext(NativeEngine * engine,void * value,void *)61 NativeValue *AttachJsAbilityContext(NativeEngine *engine, void *value, void *)
62 {
63 HILOG_DEBUG("AttachJsAbilityContext");
64 if (value == nullptr) {
65 HILOG_WARN("invalid parameter.");
66 return nullptr;
67 }
68 auto ptr = reinterpret_cast<std::weak_ptr<AbilityRuntime::AbilityContext>*>(value)->lock();
69 if (ptr == nullptr) {
70 HILOG_WARN("invalid context.");
71 return nullptr;
72 }
73 NativeValue *object = CreateJsAbilityContext(*engine, ptr, nullptr, nullptr);
74 auto systemModule = JsRuntime::LoadSystemModuleByEngine(engine, "application.AbilityContext", &object, 1);
75 if (systemModule == nullptr) {
76 HILOG_WARN("invalid systemModule.");
77 return nullptr;
78 }
79 auto contextObj = systemModule->Get();
80 NativeObject *nObject = ConvertNativeValueTo<NativeObject>(contextObj);
81 nObject->ConvertToNativeBindingObject(engine, DetachCallbackFunc, AttachJsAbilityContext, value, nullptr);
82 auto workContext = new (std::nothrow) std::weak_ptr<AbilityRuntime::AbilityContext>(ptr);
83 nObject->SetNativePointer(workContext,
84 [](NativeEngine *, void * data, void *) {
85 HILOG_DEBUG("Finalizer for weak_ptr ability context is called");
86 delete static_cast<std::weak_ptr<AbilityRuntime::AbilityContext> *>(data);
87 }, nullptr);
88 return contextObj;
89 }
90
Create(const std::unique_ptr<Runtime> & runtime)91 Ability *JsAbility::Create(const std::unique_ptr<Runtime> &runtime)
92 {
93 return new JsAbility(static_cast<JsRuntime &>(*runtime));
94 }
95
JsAbility(JsRuntime & jsRuntime)96 JsAbility::JsAbility(JsRuntime &jsRuntime) : jsRuntime_(jsRuntime)
97 {}
98 JsAbility::~JsAbility() = default;
99
Init(const std::shared_ptr<AbilityInfo> & abilityInfo,const std::shared_ptr<OHOSApplication> application,std::shared_ptr<AbilityHandler> & handler,const sptr<IRemoteObject> & token)100 void JsAbility::Init(const std::shared_ptr<AbilityInfo> &abilityInfo,
101 const std::shared_ptr<OHOSApplication> application, std::shared_ptr<AbilityHandler> &handler,
102 const sptr<IRemoteObject> &token)
103 {
104 Ability::Init(abilityInfo, application, handler, token);
105
106 if (!abilityInfo) {
107 HILOG_ERROR("abilityInfo is nullptr");
108 return;
109 }
110
111 std::string srcPath(abilityInfo->package);
112 if (!abilityInfo->isModuleJson) {
113 /* temporary compatibility api8 + config.json */
114 srcPath.append("/assets/js/");
115 if (!abilityInfo->srcPath.empty()) {
116 srcPath.append(abilityInfo->srcPath);
117 }
118 srcPath.append("/").append(abilityInfo->name).append(".abc");
119 } else {
120 if (abilityInfo->srcEntrance.empty()) {
121 HILOG_ERROR("abilityInfo srcEntrance is empty");
122 return;
123 }
124 srcPath.append("/");
125 srcPath.append(abilityInfo->srcEntrance);
126 srcPath.erase(srcPath.rfind("."));
127 srcPath.append(".abc");
128 HILOG_INFO("JsAbility srcPath is %{public}s", srcPath.c_str());
129 }
130
131 std::string moduleName(abilityInfo->moduleName);
132 moduleName.append("::").append(abilityInfo->name);
133
134 HandleScope handleScope(jsRuntime_);
135 auto &engine = jsRuntime_.GetNativeEngine();
136
137 jsAbilityObj_ = jsRuntime_.LoadModule(
138 moduleName, srcPath, abilityInfo->hapPath, abilityInfo->compileMode == AppExecFwk::CompileMode::ES_MODULE);
139 if (jsAbilityObj_ == nullptr) {
140 HILOG_ERROR("Failed to get AbilityStage object");
141 return;
142 }
143
144 NativeObject *obj = ConvertNativeValueTo<NativeObject>(jsAbilityObj_->Get());
145 if (obj == nullptr) {
146 HILOG_ERROR("Failed to convert AbilityStage object");
147 return;
148 }
149
150 auto context = GetAbilityContext();
151 NativeValue *contextObj = CreateJsAbilityContext(engine, context, nullptr, nullptr);
152 shellContextRef_ = std::shared_ptr<NativeReference>(
153 JsRuntime::LoadSystemModuleByEngine(&engine, "application.AbilityContext", &contextObj, 1).release());
154 contextObj = shellContextRef_->Get();
155 auto nativeObj = ConvertNativeValueTo<NativeObject>(contextObj);
156 if (nativeObj == nullptr) {
157 HILOG_ERROR("Failed to get ability native object");
158 return;
159 }
160 auto workContext = new (std::nothrow) std::weak_ptr<AbilityRuntime::AbilityContext>(context);
161 nativeObj->ConvertToNativeBindingObject(&engine, DetachCallbackFunc, AttachJsAbilityContext,
162 workContext, nullptr);
163 context->Bind(jsRuntime_, shellContextRef_.get());
164 obj->SetProperty("context", contextObj);
165 HILOG_DEBUG("Set ability context");
166
167 nativeObj->SetNativePointer(
168 workContext,
169 [](NativeEngine *, void *data, void *) {
170 HILOG_DEBUG("Finalizer for weak_ptr ability context is called");
171 delete static_cast<std::weak_ptr<AbilityRuntime::AbilityContext> *>(data);
172 },
173 nullptr);
174 }
175
OnStart(const Want & want)176 void JsAbility::OnStart(const Want &want)
177 {
178 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
179 HILOG_DEBUG("OnStart begin, ability is %{public}s.", GetAbilityName().c_str());
180 Ability::OnStart(want);
181
182 if (!jsAbilityObj_) {
183 HILOG_WARN("Not found Ability.js");
184 return;
185 }
186 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
187 if (applicationContext != nullptr) {
188 applicationContext->DispatchOnAbilityCreate(jsAbilityObj_);
189 }
190
191 HandleScope handleScope(jsRuntime_);
192 auto &nativeEngine = jsRuntime_.GetNativeEngine();
193
194 NativeValue *value = jsAbilityObj_->Get();
195 NativeObject *obj = ConvertNativeValueTo<NativeObject>(value);
196 if (obj == nullptr) {
197 HILOG_ERROR("Failed to get Ability object");
198 return;
199 }
200
201 napi_value napiWant = OHOS::AppExecFwk::WrapWant(reinterpret_cast<napi_env>(&nativeEngine), want);
202 NativeValue *jsWant = reinterpret_cast<NativeValue *>(napiWant);
203
204 obj->SetProperty("launchWant", jsWant);
205 obj->SetProperty("lastRequestWant", jsWant);
206
207 NativeValue *argv[] = {
208 jsWant,
209 CreateJsLaunchParam(nativeEngine, GetLaunchParam()),
210 };
211 CallObjectMethod("onCreate", argv, ArraySize(argv));
212
213 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
214 if (delegator) {
215 HILOG_DEBUG("Call AbilityDelegator::PostPerformStart");
216 delegator->PostPerformStart(CreateADelegatorAbilityProperty());
217 }
218 HILOG_DEBUG("OnStart end, ability is %{public}s.", GetAbilityName().c_str());
219 }
220
OnStop()221 void JsAbility::OnStop()
222 {
223 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
224 HILOG_DEBUG("OnStop begin.");
225 if (abilityContext_) {
226 HILOG_DEBUG("OnStop, set terminating true.");
227 abilityContext_->SetTerminating(true);
228 }
229 Ability::OnStop();
230 CallObjectMethod("onDestroy");
231 OnStopCallback();
232 HILOG_DEBUG("OnStop end.");
233 }
234
OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> * callbackInfo,bool & isAsyncCallback)235 void JsAbility::OnStop(AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo, bool &isAsyncCallback)
236 {
237 if (callbackInfo == nullptr) {
238 isAsyncCallback = false;
239 OnStop();
240 return;
241 }
242
243 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
244 HILOG_DEBUG("OnStop begin.");
245 if (abilityContext_) {
246 HILOG_DEBUG("OnStop, set terminating true.");
247 abilityContext_->SetTerminating(true);
248 }
249
250 Ability::OnStop();
251
252 HandleScope handleScope(jsRuntime_);
253 NativeValue *result = CallObjectMethod("onDestroy", nullptr, 0, true);
254 if (!CheckPromise(result)) {
255 OnStopCallback();
256 isAsyncCallback = false;
257 return;
258 }
259
260 std::weak_ptr<Ability> weakPtr = shared_from_this();
261 auto asyncCallback = [abilityWeakPtr = weakPtr]() {
262 auto ability = abilityWeakPtr.lock();
263 if (ability == nullptr) {
264 HILOG_ERROR("ability is nullptr.");
265 return;
266 }
267 ability->OnStopCallback();
268 };
269 callbackInfo->Push(asyncCallback);
270 isAsyncCallback = CallPromise(result, callbackInfo);
271 if (!isAsyncCallback) {
272 HILOG_ERROR("Failed to call promise.");
273 OnStopCallback();
274 }
275 HILOG_DEBUG("OnStop end.");
276 }
277
OnStopCallback()278 void JsAbility::OnStopCallback()
279 {
280 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
281 if (delegator) {
282 HILOG_DEBUG("Call AbilityDelegator::PostPerformStop");
283 delegator->PostPerformStop(CreateADelegatorAbilityProperty());
284 }
285
286 bool ret = ConnectionManager::GetInstance().DisconnectCaller(AbilityContext::token_);
287 if (ret) {
288 ConnectionManager::GetInstance().ReportConnectionLeakEvent(getpid(), gettid());
289 HILOG_DEBUG("The service connection is not disconnected.");
290 }
291
292 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
293 if (applicationContext != nullptr) {
294 applicationContext->DispatchOnAbilityDestroy(jsAbilityObj_);
295 }
296 }
297
298 #ifdef SUPPORT_GRAPHICS
299 const std::string PAGE_STACK_PROPERTY_NAME = "pageStack";
300 const std::string SUPPORT_CONTINUE_PAGE_STACK_PROPERTY_NAME = "ohos.extra.param.key.supportContinuePageStack";
301
OnSceneCreated()302 void JsAbility::OnSceneCreated()
303 {
304 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
305 HILOG_DEBUG("OnSceneCreated begin, ability is %{public}s.", GetAbilityName().c_str());
306 Ability::OnSceneCreated();
307 auto jsAppWindowStage = CreateAppWindowStage();
308 if (jsAppWindowStage == nullptr) {
309 HILOG_ERROR("Failed to create jsAppWindowStage object by LoadSystemModule");
310 return;
311 }
312 NativeValue *argv[] = {jsAppWindowStage->Get()};
313 CallObjectMethod("onWindowStageCreate", argv, ArraySize(argv));
314
315 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
316 if (delegator) {
317 HILOG_DEBUG("Call AbilityDelegator::PostPerformScenceCreated");
318 delegator->PostPerformScenceCreated(CreateADelegatorAbilityProperty());
319 }
320
321 jsWindowStageObj_ = std::shared_ptr<NativeReference>(jsAppWindowStage.release());
322 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
323 if (applicationContext != nullptr) {
324 applicationContext->DispatchOnWindowStageCreate(jsAbilityObj_, jsWindowStageObj_);
325 }
326
327 HILOG_DEBUG("OnSceneCreated end, ability is %{public}s.", GetAbilityName().c_str());
328 }
329
OnSceneRestored()330 void JsAbility::OnSceneRestored()
331 {
332 Ability::OnSceneRestored();
333 HILOG_DEBUG("OnSceneRestored");
334 auto jsAppWindowStage = CreateAppWindowStage();
335 if (jsAppWindowStage == nullptr) {
336 HILOG_ERROR("Failed to create jsAppWindowStage object by LoadSystemModule");
337 return;
338 }
339 NativeValue *argv[] = {jsAppWindowStage->Get()};
340 CallObjectMethod("onWindowStageRestore", argv, ArraySize(argv));
341
342 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
343 if (delegator) {
344 HILOG_DEBUG("Call AbilityDelegator::PostPerformScenceRestored");
345 delegator->PostPerformScenceRestored(CreateADelegatorAbilityProperty());
346 }
347
348 jsWindowStageObj_ = std::shared_ptr<NativeReference>(jsAppWindowStage.release());
349 }
350
onSceneDestroyed()351 void JsAbility::onSceneDestroyed()
352 {
353 HILOG_DEBUG("onSceneDestroyed begin, ability is %{public}s.", GetAbilityName().c_str());
354 Ability::onSceneDestroyed();
355
356 CallObjectMethod("onWindowStageDestroy");
357
358 if (scene_ != nullptr) {
359 auto window = scene_->GetMainWindow();
360 if (window != nullptr) {
361 HILOG_DEBUG("Call UnregisterDisplayMoveListener");
362 window->UnregisterDisplayMoveListener(abilityDisplayMoveListener_);
363 }
364 }
365
366 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
367 if (delegator) {
368 HILOG_DEBUG("Call AbilityDelegator::PostPerformScenceDestroyed");
369 delegator->PostPerformScenceDestroyed(CreateADelegatorAbilityProperty());
370 }
371
372 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
373 if (applicationContext != nullptr) {
374 applicationContext->DispatchOnWindowStageDestroy(jsAbilityObj_, jsWindowStageObj_);
375 }
376 HILOG_DEBUG("onSceneDestroyed end, ability is %{public}s.", GetAbilityName().c_str());
377 }
378
OnForeground(const Want & want)379 void JsAbility::OnForeground(const Want &want)
380 {
381 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
382 HILOG_DEBUG("OnForeground begin, ability is %{public}s.", GetAbilityName().c_str());
383 if (abilityInfo_) {
384 jsRuntime_.UpdateModuleNameAndAssetPath(abilityInfo_->moduleName);
385 }
386
387 Ability::OnForeground(want);
388
389 HandleScope handleScope(jsRuntime_);
390 auto &nativeEngine = jsRuntime_.GetNativeEngine();
391 if (jsAbilityObj_ == nullptr) {
392 HILOG_ERROR("Failed to get AbilityStage object");
393 return;
394 }
395 NativeValue *value = jsAbilityObj_->Get();
396 NativeObject *obj = ConvertNativeValueTo<NativeObject>(value);
397 if (obj == nullptr) {
398 HILOG_ERROR("Failed to get Ability object");
399 return;
400 }
401
402 napi_value napiWant = OHOS::AppExecFwk::WrapWant(reinterpret_cast<napi_env>(&nativeEngine), want);
403 NativeValue *jsWant = reinterpret_cast<NativeValue *>(napiWant);
404
405 obj->SetProperty("lastRequestWant", jsWant);
406
407 CallObjectMethod("onForeground", &jsWant, 1);
408
409 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
410 if (delegator) {
411 HILOG_DEBUG("Call AbilityDelegator::PostPerformForeground");
412 delegator->PostPerformForeground(CreateADelegatorAbilityProperty());
413 }
414
415 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
416 if (applicationContext != nullptr) {
417 applicationContext->DispatchOnAbilityForeground(jsAbilityObj_);
418 }
419 HILOG_DEBUG("OnForeground end, ability is %{public}s.", GetAbilityName().c_str());
420 }
421
OnBackground()422 void JsAbility::OnBackground()
423 {
424 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
425 HILOG_DEBUG("OnBackground begin, ability is %{public}s.", GetAbilityName().c_str());
426 CallObjectMethod("onBackground");
427 Ability::OnBackground();
428
429 auto delegator = AppExecFwk::AbilityDelegatorRegistry::GetAbilityDelegator();
430 if (delegator) {
431 HILOG_DEBUG("Call AbilityDelegator::PostPerformBackground");
432 delegator->PostPerformBackground(CreateADelegatorAbilityProperty());
433 }
434
435 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
436 if (applicationContext != nullptr) {
437 applicationContext->DispatchOnAbilityBackground(jsAbilityObj_);
438 }
439 HILOG_DEBUG("OnBackground end, ability is %{public}s.", GetAbilityName().c_str());
440 }
441
CreateAppWindowStage()442 std::unique_ptr<NativeReference> JsAbility::CreateAppWindowStage()
443 {
444 HandleScope handleScope(jsRuntime_);
445 auto &engine = jsRuntime_.GetNativeEngine();
446 NativeValue *jsWindowStage = Rosen::CreateJsWindowStage(engine, GetScene());
447 if (jsWindowStage == nullptr) {
448 HILOG_ERROR("Failed to create jsWindowSatge object");
449 return nullptr;
450 }
451 return JsRuntime::LoadSystemModuleByEngine(&engine, "application.WindowStage", &jsWindowStage, 1);
452 }
453
GetPageStackFromWant(const Want & want,std::string & pageStack)454 void JsAbility::GetPageStackFromWant(const Want &want, std::string &pageStack)
455 {
456 auto stringObj = AAFwk::IString::Query(want.GetParams().GetParam(PAGE_STACK_PROPERTY_NAME));
457 if (stringObj != nullptr) {
458 pageStack = AAFwk::String::Unbox(stringObj);
459 }
460 }
461
IsRestorePageStack(const Want & want)462 bool JsAbility::IsRestorePageStack(const Want &want)
463 {
464 return want.GetBoolParam(SUPPORT_CONTINUE_PAGE_STACK_PROPERTY_NAME, true);
465 }
466
RestorePageStack(const Want & want)467 void JsAbility::RestorePageStack(const Want &want)
468 {
469 if (IsRestorePageStack(want)) {
470 std::string pageStack;
471 GetPageStackFromWant(want, pageStack);
472 HandleScope handleScope(jsRuntime_);
473 auto &engine = jsRuntime_.GetNativeEngine();
474 if (abilityContext_->GetContentStorage()) {
475 scene_->GetMainWindow()->SetUIContent(pageStack, &engine,
476 abilityContext_->GetContentStorage()->Get(), true);
477 } else {
478 HILOG_ERROR("restore: content storage is nullptr");
479 }
480 }
481 }
482
AbilityContinuationOrRecover(const Want & want)483 void JsAbility::AbilityContinuationOrRecover(const Want &want)
484 {
485 // multi-instance ability continuation
486 HILOG_DEBUG("launch reason = %{public}d", launchParam_.launchReason);
487 if (IsRestoredInContinuation()) {
488 RestorePageStack(want);
489 OnSceneRestored();
490 NotifyContinuationResult(want, true);
491 } else if (ShouldRecoverState(want)) {
492 std::string pageStack = abilityRecovery_->GetSavedPageStack(AppExecFwk::StateReason::DEVELOPER_REQUEST);
493 HandleScope handleScope(jsRuntime_);
494 auto &engine = jsRuntime_.GetNativeEngine();
495 auto mainWindow = scene_->GetMainWindow();
496 if (mainWindow != nullptr) {
497 mainWindow->SetUIContent(pageStack, &engine, abilityContext_->GetContentStorage()->Get(), true);
498 } else {
499 HILOG_ERROR("AppRecovery:AbilityContinuationOrRecover mainWindow nullptr");
500 }
501 OnSceneRestored();
502 } else {
503 OnSceneCreated();
504 }
505 }
506
DoOnForeground(const Want & want)507 void JsAbility::DoOnForeground(const Want &want)
508 {
509 if (scene_ == nullptr) {
510 if ((abilityContext_ == nullptr) || (sceneListener_ == nullptr)) {
511 HILOG_ERROR("Ability::OnForeground error. abilityContext_ or sceneListener_ is nullptr!");
512 return;
513 }
514 scene_ = std::make_shared<Rosen::WindowScene>();
515 int32_t displayId = Rosen::WindowScene::DEFAULT_DISPLAY_ID;
516 if (setting_ != nullptr) {
517 std::string strDisplayId =
518 setting_->GetProperty(OHOS::AppExecFwk::AbilityStartSetting::WINDOW_DISPLAY_ID_KEY);
519 std::regex formatRegex("[0-9]{0,9}$");
520 std::smatch sm;
521 bool flag = std::regex_match(strDisplayId, sm, formatRegex);
522 if (flag && !strDisplayId.empty()) {
523 int base = 10; // Numerical base (radix) that determines the valid characters and their interpretation.
524 displayId = strtol(strDisplayId.c_str(), nullptr, base);
525 HILOG_DEBUG("%{public}s success. displayId is %{public}d", __func__, displayId);
526 } else {
527 HILOG_WARN("%{public}s failed to formatRegex:[%{public}s]", __func__, strDisplayId.c_str());
528 }
529 }
530 auto option = GetWindowOption(want);
531 Rosen::WMError ret = scene_->Init(displayId, abilityContext_, sceneListener_, option);
532 if (ret != Rosen::WMError::WM_OK) {
533 HILOG_ERROR("%{public}s error. failed to init window scene!", __func__);
534 return;
535 }
536
537 AbilityContinuationOrRecover(want);
538 auto window = scene_->GetMainWindow();
539 if (window) {
540 HILOG_DEBUG("Call RegisterDisplayMoveListener, windowId: %{public}d", window->GetWindowId());
541 abilityDisplayMoveListener_ = new AbilityDisplayMoveListener(weak_from_this());
542 window->RegisterDisplayMoveListener(abilityDisplayMoveListener_);
543 }
544 } else {
545 auto window = scene_->GetMainWindow();
546 if (window != nullptr && want.HasParameter(Want::PARAM_RESV_WINDOW_MODE)) {
547 auto windowMode = want.GetIntParam(Want::PARAM_RESV_WINDOW_MODE,
548 AAFwk::AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_UNDEFINED);
549 window->SetWindowMode(static_cast<Rosen::WindowMode>(windowMode));
550 HILOG_DEBUG("set window mode = %{public}d.", windowMode);
551 }
552 }
553
554 auto window = scene_->GetMainWindow();
555 if (window != nullptr && securityFlag_) {
556 window->SetSystemPrivacyMode(true);
557 }
558
559 HILOG_DEBUG("%{public}s begin scene_->GoForeground, sceneFlag_:%{public}d.", __func__, Ability::sceneFlag_);
560 scene_->GoForeground(Ability::sceneFlag_);
561 HILOG_DEBUG("%{public}s end scene_->GoForeground.", __func__);
562 }
563
RequestFocus(const Want & want)564 void JsAbility::RequestFocus(const Want &want)
565 {
566 HILOG_DEBUG("%{public}s called.", __func__);
567 if (scene_ == nullptr) {
568 return;
569 }
570 auto window = scene_->GetMainWindow();
571 if (window != nullptr && want.HasParameter(Want::PARAM_RESV_WINDOW_MODE)) {
572 auto windowMode = want.GetIntParam(Want::PARAM_RESV_WINDOW_MODE,
573 AAFwk::AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_UNDEFINED);
574 window->SetWindowMode(static_cast<Rosen::WindowMode>(windowMode));
575 HILOG_DEBUG("set window mode = %{public}d.", windowMode);
576 }
577 scene_->GoForeground(Ability::sceneFlag_);
578 }
579
ContinuationRestore(const Want & want)580 void JsAbility::ContinuationRestore(const Want &want)
581 {
582 HILOG_DEBUG("%{public}s called.", __func__);
583 if (!IsRestoredInContinuation() || scene_ == nullptr) {
584 return;
585 }
586 RestorePageStack(want);
587 OnSceneRestored();
588 NotifyContinuationResult(want, true);
589 }
590
GetJsWindowStage()591 std::shared_ptr<NativeReference> JsAbility::GetJsWindowStage()
592 {
593 HILOG_DEBUG("%{public}s called.", __func__);
594 if (jsWindowStageObj_ == nullptr) {
595 HILOG_ERROR("jsWindowSatge is nullptr");
596 }
597 return jsWindowStageObj_;
598 }
599 #endif
600
OnContinue(WantParams & wantParams)601 int32_t JsAbility::OnContinue(WantParams &wantParams)
602 {
603 HandleScope handleScope(jsRuntime_);
604 auto &nativeEngine = jsRuntime_.GetNativeEngine();
605 if (jsAbilityObj_ == nullptr) {
606 HILOG_ERROR("Failed to get AbilityStage object");
607 return AppExecFwk::ContinuationManager::OnContinueResult::Reject;
608 }
609 NativeValue *value = jsAbilityObj_->Get();
610 NativeObject *obj = ConvertNativeValueTo<NativeObject>(value);
611 if (obj == nullptr) {
612 HILOG_ERROR("Failed to get Ability object");
613 return AppExecFwk::ContinuationManager::OnContinueResult::Reject;
614 }
615
616 NativeValue *methodOnCreate = obj->GetProperty("onContinue");
617 if (methodOnCreate == nullptr) {
618 HILOG_ERROR("Failed to get 'onContinue' from Ability object");
619 return AppExecFwk::ContinuationManager::OnContinueResult::Reject;
620 }
621
622 napi_value napiWantParams = OHOS::AppExecFwk::WrapWantParams(reinterpret_cast<napi_env>(&nativeEngine), wantParams);
623 NativeValue *jsWantParams = reinterpret_cast<NativeValue *>(napiWantParams);
624
625 NativeValue *result = nativeEngine.CallFunction(value, methodOnCreate, &jsWantParams, 1);
626
627 napi_value new_napiWantParams = reinterpret_cast<napi_value>(jsWantParams);
628 OHOS::AppExecFwk::UnwrapWantParams(reinterpret_cast<napi_env>(&nativeEngine), new_napiWantParams, wantParams);
629
630 NativeNumber *numberResult = ConvertNativeValueTo<NativeNumber>(result);
631 if (numberResult == nullptr) {
632 HILOG_ERROR("'onContinue' is not implemented");
633 return AppExecFwk::ContinuationManager::OnContinueResult::Reject;
634 }
635
636 auto applicationContext = AbilityRuntime::Context::GetApplicationContext();
637 if (applicationContext != nullptr) {
638 applicationContext->DispatchOnAbilityContinue(jsAbilityObj_);
639 }
640
641 return *numberResult;
642 }
643
OnSaveState(int32_t reason,WantParams & wantParams)644 int32_t JsAbility::OnSaveState(int32_t reason, WantParams &wantParams)
645 {
646 HandleScope handleScope(jsRuntime_);
647 auto &nativeEngine = jsRuntime_.GetNativeEngine();
648 if (jsAbilityObj_ == nullptr) {
649 HILOG_ERROR("AppRecoveryFailed to get AbilityStage object");
650 return -1;
651 }
652 NativeValue *value = jsAbilityObj_->Get();
653 NativeObject *obj = ConvertNativeValueTo<NativeObject>(value);
654 if (obj == nullptr) {
655 HILOG_ERROR("AppRecovery Failed to get Ability object");
656 return -1;
657 }
658
659 NativeValue *methodOnSaveState = obj->GetProperty("onSaveState");
660 if (methodOnSaveState == nullptr) {
661 HILOG_ERROR("AppRecovery Failed to get 'onSaveState' from Ability object");
662 return -1;
663 }
664
665 napi_value napiWantParams = OHOS::AppExecFwk::WrapWantParams(reinterpret_cast<napi_env>(&nativeEngine), wantParams);
666 NativeValue* jsReason = CreateJsValue(nativeEngine, reason);
667 NativeValue* jsWantParams = reinterpret_cast<NativeValue *>(napiWantParams);
668 NativeValue* args[] = { jsReason, jsWantParams };
669 NativeValue* result = nativeEngine.CallFunction(value, methodOnSaveState, args, 2); // 2:args size
670 napi_value newNapiWantParams = reinterpret_cast<napi_value>(jsWantParams);
671 OHOS::AppExecFwk::UnwrapWantParams(reinterpret_cast<napi_env>(&nativeEngine), newNapiWantParams, wantParams);
672
673 NativeNumber *numberResult = ConvertNativeValueTo<NativeNumber>(result);
674 if (numberResult == nullptr) {
675 HILOG_ERROR("AppRecovery no result return from onSaveState");
676 return -1;
677 }
678 return *numberResult;
679 }
680
OnConfigurationUpdated(const Configuration & configuration)681 void JsAbility::OnConfigurationUpdated(const Configuration &configuration)
682 {
683 Ability::OnConfigurationUpdated(configuration);
684 HILOG_DEBUG("%{public}s called.", __func__);
685
686 HandleScope handleScope(jsRuntime_);
687 auto& nativeEngine = jsRuntime_.GetNativeEngine();
688 auto fullConfig = GetAbilityContext()->GetConfiguration();
689 if (!fullConfig) {
690 HILOG_ERROR("configuration is nullptr.");
691 return;
692 }
693
694 napi_value napiConfiguration = OHOS::AppExecFwk::WrapConfiguration(
695 reinterpret_cast<napi_env>(&nativeEngine), configuration);
696 NativeValue* jsConfiguration = reinterpret_cast<NativeValue*>(napiConfiguration);
697 CallObjectMethod("onConfigurationUpdated", &jsConfiguration, 1);
698 CallObjectMethod("onConfigurationUpdate", &jsConfiguration, 1);
699 JsAbilityContext::ConfigurationUpdated(&nativeEngine, shellContextRef_, fullConfig);
700 }
701
OnMemoryLevel(int level)702 void JsAbility::OnMemoryLevel(int level)
703 {
704 Ability::OnMemoryLevel(level);
705 HILOG_DEBUG("%{public}s called.", __func__);
706
707 HandleScope handleScope(jsRuntime_);
708 auto &nativeEngine = jsRuntime_.GetNativeEngine();
709 if (jsAbilityObj_ == nullptr) {
710 HILOG_ERROR("Failed to get AbilityStage object");
711 return;
712 }
713 NativeValue *value = jsAbilityObj_->Get();
714 NativeObject *obj = ConvertNativeValueTo<NativeObject>(value);
715 if (obj == nullptr) {
716 HILOG_ERROR("Failed to get Ability object");
717 return;
718 }
719
720 NativeValue *jslevel = CreateJsValue(nativeEngine, level);
721 NativeValue *argv[] = {
722 jslevel,
723 };
724 CallObjectMethod("onMemoryLevel", argv, ArraySize(argv));
725 }
726
UpdateContextConfiguration()727 void JsAbility::UpdateContextConfiguration()
728 {
729 HILOG_DEBUG("%{public}s called.", __func__);
730 HandleScope handleScope(jsRuntime_);
731 auto& nativeEngine = jsRuntime_.GetNativeEngine();
732 JsAbilityContext::ConfigurationUpdated(&nativeEngine, shellContextRef_, GetAbilityContext()->GetConfiguration());
733 }
734
OnNewWant(const Want & want)735 void JsAbility::OnNewWant(const Want &want)
736 {
737 HILOG_DEBUG("%{public}s begin.", __func__);
738 Ability::OnNewWant(want);
739
740 #ifdef SUPPORT_GRAPHICS
741 if (scene_) {
742 scene_->OnNewWant(want);
743 }
744 #endif
745
746 HandleScope handleScope(jsRuntime_);
747 auto &nativeEngine = jsRuntime_.GetNativeEngine();
748 if (jsAbilityObj_ == nullptr) {
749 HILOG_ERROR("Failed to get AbilityStage object");
750 return;
751 }
752 NativeValue *value = jsAbilityObj_->Get();
753 NativeObject *obj = ConvertNativeValueTo<NativeObject>(value);
754 if (obj == nullptr) {
755 HILOG_ERROR("Failed to get Ability object");
756 return;
757 }
758
759 napi_value napiWant = OHOS::AppExecFwk::WrapWant(reinterpret_cast<napi_env>(&nativeEngine), want);
760 NativeValue *jsWant = reinterpret_cast<NativeValue *>(napiWant);
761
762 obj->SetProperty("lastRequestWant", jsWant);
763
764 NativeValue *argv[] = {
765 jsWant,
766 CreateJsLaunchParam(nativeEngine, GetLaunchParam()),
767 };
768 CallObjectMethod("onNewWant", argv, ArraySize(argv));
769
770 HILOG_DEBUG("%{public}s end.", __func__);
771 }
772
OnAbilityResult(int requestCode,int resultCode,const Want & resultData)773 void JsAbility::OnAbilityResult(int requestCode, int resultCode, const Want &resultData)
774 {
775 HILOG_DEBUG("%{public}s begin.", __func__);
776 Ability::OnAbilityResult(requestCode, resultCode, resultData);
777 std::shared_ptr<AbilityRuntime::AbilityContext> context = GetAbilityContext();
778 if (context == nullptr) {
779 HILOG_WARN("JsAbility not attached to any runtime context!");
780 return;
781 }
782 context->OnAbilityResult(requestCode, resultCode, resultData);
783 HILOG_DEBUG("%{public}s end.", __func__);
784 }
785
CallRequest()786 sptr<IRemoteObject> JsAbility::CallRequest()
787 {
788 HILOG_DEBUG("JsAbility::CallRequest begin.");
789 if (jsAbilityObj_ == nullptr) {
790 HILOG_WARN("JsAbility::CallRequest Obj is nullptr");
791 return nullptr;
792 }
793
794 if (remoteCallee_ != nullptr) {
795 HILOG_DEBUG("JsAbility::CallRequest get Callee remoteObj.");
796 return remoteCallee_;
797 }
798
799 HandleScope handleScope(jsRuntime_);
800 HILOG_DEBUG("JsAbility::CallRequest set runtime scope.");
801 auto &nativeEngine = jsRuntime_.GetNativeEngine();
802 auto value = jsAbilityObj_->Get();
803 if (value == nullptr) {
804 HILOG_ERROR("JsAbility::CallRequest value is nullptr");
805 return nullptr;
806 }
807
808 NativeObject *obj = ConvertNativeValueTo<NativeObject>(value);
809 if (obj == nullptr) {
810 HILOG_ERROR("JsAbility::CallRequest obj is nullptr");
811 return nullptr;
812 }
813
814 auto method = obj->GetProperty("onCallRequest");
815 if (method == nullptr || !method->IsCallable()) {
816 HILOG_ERROR("JsAbility::CallRequest method is %{public}s", method == nullptr ? "nullptr" : "not func");
817 return nullptr;
818 }
819
820 auto remoteJsObj = nativeEngine.CallFunction(value, method, nullptr, 0);
821 if (remoteJsObj == nullptr) {
822 HILOG_ERROR("JsAbility::CallRequest JsObj is nullptr");
823 return nullptr;
824 }
825
826 remoteCallee_ = SetNewRuleFlagToCallee(nativeEngine, remoteJsObj);
827 HILOG_DEBUG("JsAbility::CallRequest end.");
828 return remoteCallee_;
829 }
830
CallObjectMethod(const char * name,NativeValue * const * argv,size_t argc,bool withResult)831 NativeValue *JsAbility::CallObjectMethod(const char *name, NativeValue *const *argv, size_t argc, bool withResult)
832 {
833 HILOG_DEBUG("JsAbility::CallObjectMethod(%{public}s", name);
834
835 if (!jsAbilityObj_) {
836 HILOG_WARN("Not found Ability.js");
837 return nullptr;
838 }
839
840 HandleEscape handleEscape(jsRuntime_);
841 auto &nativeEngine = jsRuntime_.GetNativeEngine();
842
843 NativeValue *value = jsAbilityObj_->Get();
844 NativeObject *obj = ConvertNativeValueTo<NativeObject>(value);
845 if (obj == nullptr) {
846 HILOG_ERROR("Failed to get Ability object");
847 return nullptr;
848 }
849
850 NativeValue *methodOnCreate = obj->GetProperty(name);
851 if (methodOnCreate == nullptr) {
852 HILOG_ERROR("Failed to get '%{public}s' from Ability object", name);
853 return nullptr;
854 }
855 if (withResult) {
856 return handleEscape.Escape(nativeEngine.CallFunction(value, methodOnCreate, argv, argc));
857 }
858 nativeEngine.CallFunction(value, methodOnCreate, argv, argc);
859 return nullptr;
860 }
861
CheckPromise(NativeValue * result)862 bool JsAbility::CheckPromise(NativeValue *result)
863 {
864 if (result == nullptr) {
865 HILOG_DEBUG("result is null, no need to call promise.");
866 return false;
867 }
868 if (!result->IsPromise()) {
869 HILOG_DEBUG("result is not promise, no need to call promise.");
870 return false;
871 }
872 return true;
873 }
874
CallPromise(NativeValue * result,AppExecFwk::AbilityTransactionCallbackInfo<> * callbackInfo)875 bool JsAbility::CallPromise(NativeValue *result, AppExecFwk::AbilityTransactionCallbackInfo<> *callbackInfo)
876 {
877 auto *retObj = ConvertNativeValueTo<NativeObject>(result);
878 if (retObj == nullptr) {
879 HILOG_ERROR("Failed to convert native value to NativeObject.");
880 return false;
881 }
882 NativeValue *then = retObj->GetProperty("then");
883 if (then == nullptr) {
884 HILOG_ERROR("Failed to get property: then.");
885 return false;
886 }
887 if (!then->IsCallable()) {
888 HILOG_ERROR("property then is not callable.");
889 return false;
890 }
891 HandleScope handleScope(jsRuntime_);
892 auto &nativeEngine = jsRuntime_.GetNativeEngine();
893 auto promiseCallback = nativeEngine.CreateFunction("promiseCallback", strlen("promiseCallback"), PromiseCallback,
894 callbackInfo);
895 NativeValue *argv[1] = { promiseCallback };
896 nativeEngine.CallFunction(result, then, argv, 1);
897 return true;
898 }
899
CreateADelegatorAbilityProperty()900 std::shared_ptr<AppExecFwk::ADelegatorAbilityProperty> JsAbility::CreateADelegatorAbilityProperty()
901 {
902 auto property = std::make_shared<AppExecFwk::ADelegatorAbilityProperty>();
903 property->token_ = GetAbilityContext()->GetToken();
904 property->name_ = GetAbilityName();
905 if (GetApplicationInfo() == nullptr || GetApplicationInfo()->bundleName.empty()) {
906 property->fullName_ = GetAbilityName();
907 } else {
908 std::string::size_type pos = GetAbilityName().find(GetApplicationInfo()->bundleName);
909 if (pos == std::string::npos || pos != 0) {
910 property->fullName_ = GetApplicationInfo()->bundleName + "." + GetAbilityName();
911 } else {
912 property->fullName_ = GetAbilityName();
913 }
914 }
915 property->lifecycleState_ = GetState();
916 property->object_ = jsAbilityObj_;
917
918 return property;
919 }
920
Dump(const std::vector<std::string> & params,std::vector<std::string> & info)921 void JsAbility::Dump(const std::vector<std::string> ¶ms, std::vector<std::string> &info)
922 {
923 Ability::Dump(params, info);
924 HILOG_DEBUG("%{public}s called.", __func__);
925 HandleScope handleScope(jsRuntime_);
926 auto& nativeEngine = jsRuntime_.GetNativeEngine();
927 // create js array object of params
928 NativeValue* argv[] = { CreateNativeArray(nativeEngine, params) };
929
930 if (!jsAbilityObj_) {
931 HILOG_WARN("Not found .js");
932 return;
933 }
934
935 NativeValue* value = jsAbilityObj_->Get();
936 NativeObject* obj = ConvertNativeValueTo<NativeObject>(value);
937 if (obj == nullptr) {
938 HILOG_ERROR("Failed to get object");
939 return;
940 }
941
942 NativeValue* method = obj->GetProperty("dump");
943 NativeValue* onDumpMethod = obj->GetProperty("onDump");
944
945 NativeValue* dumpInfo = nullptr;
946 if (method != nullptr) {
947 dumpInfo = nativeEngine.CallFunction(value, method, argv, 1);
948 }
949
950 NativeValue* onDumpInfo = nullptr;
951 if (onDumpMethod != nullptr) {
952 onDumpInfo = nativeEngine.CallFunction(value, onDumpMethod, argv, 1);
953 }
954
955 NativeArray* dumpInfoNative = nullptr;
956 if (dumpInfo != nullptr) {
957 dumpInfoNative = ConvertNativeValueTo<NativeArray>(dumpInfo);
958 }
959
960 NativeArray* onDumpInfoNative = nullptr;
961 if (onDumpInfo != nullptr) {
962 onDumpInfoNative = ConvertNativeValueTo<NativeArray>(onDumpInfo);
963 }
964
965 if (dumpInfoNative != nullptr) {
966 for (uint32_t i = 0; i < dumpInfoNative->GetLength(); i++) {
967 std::string dumpInfoStr;
968 if (!ConvertFromJsValue(nativeEngine, dumpInfoNative->GetElement(i), dumpInfoStr)) {
969 HILOG_ERROR("Parse dumpInfoStr failed");
970 return;
971 }
972 info.push_back(dumpInfoStr);
973 }
974 }
975
976 if (onDumpInfoNative != nullptr) {
977 for (uint32_t i = 0; i < onDumpInfoNative->GetLength(); i++) {
978 std::string dumpInfoStr;
979 if (!ConvertFromJsValue(nativeEngine, onDumpInfoNative->GetElement(i), dumpInfoStr)) {
980 HILOG_ERROR("Parse dumpInfoStr from onDumpInfoNative failed");
981 return;
982 }
983 info.push_back(dumpInfoStr);
984 }
985 }
986
987 HILOG_DEBUG("Dump info size: %{public}zu", info.size());
988 }
989
GetJsAbility()990 std::shared_ptr<NativeReference> JsAbility::GetJsAbility()
991 {
992 HILOG_DEBUG("%{public}s called.", __func__);
993 if (jsAbilityObj_ == nullptr) {
994 HILOG_ERROR("jsAbility object is nullptr");
995 }
996 return jsAbilityObj_;
997 }
998
SetNewRuleFlagToCallee(NativeEngine & nativeEngine,NativeValue * remoteJsObj)999 sptr<IRemoteObject> JsAbility::SetNewRuleFlagToCallee(NativeEngine &nativeEngine, NativeValue* remoteJsObj)
1000 {
1001 NativeObject* calleeObj = ConvertNativeValueTo<NativeObject>(remoteJsObj);
1002 if (calleeObj == nullptr) {
1003 HILOG_ERROR("JsAbility::SetNewRuleFlagToCallee calleeObj is nullptr");
1004 return nullptr;
1005 }
1006 auto setFlagMethod = calleeObj->GetProperty("setNewRuleFlag");
1007 if (setFlagMethod == nullptr || !setFlagMethod->IsCallable()) {
1008 HILOG_ERROR("JsAbility::SetNewRuleFlagToCallee setFlagMethod is %{public}s",
1009 setFlagMethod == nullptr ? "nullptr" : "not func");
1010 return nullptr;
1011 }
1012 auto flag = nativeEngine.CreateBoolean(IsUseNewStartUpRule());
1013 NativeValue *argv[1] = { flag };
1014 nativeEngine.CallFunction(remoteJsObj, setFlagMethod, argv, 1);
1015
1016 auto remoteObj = NAPI_ohos_rpc_getNativeRemoteObject(
1017 reinterpret_cast<napi_env>(&nativeEngine), reinterpret_cast<napi_value>(remoteJsObj));
1018 if (remoteObj == nullptr) {
1019 HILOG_ERROR("JsAbility::CallRequest obj is nullptr");
1020 return nullptr;
1021 }
1022 return remoteObj;
1023 }
1024 } // namespace AbilityRuntime
1025 } // namespace OHOS
1026