• 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 {}
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> &params, 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