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