1 /*
2  * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "js_ability_manager.h"
17 
18 #include <cstdint>
19 #include <memory>
20 #include <regex>
21 
22 #include "ability_business_error.h"
23 #include "ability_manager_client.h"
24 #include "acquire_share_data_callback_stub.h"
25 #include "app_mgr_interface.h"
26 #include "errors.h"
27 #include "event_runner.h"
28 #include "hilog_tag_wrapper.h"
29 #include "if_system_ability_manager.h"
30 #include "ipc_skeleton.h"
31 #include "iservice_registry.h"
32 #include "js_ability_foreground_state_observer.h"
33 #include "js_ability_manager_utils.h"
34 #include "js_error_utils.h"
35 #include "js_runtime.h"
36 #include "js_runtime_utils.h"
37 #include "napi/native_api.h"
38 #include "napi_base_context.h"
39 #include "napi_common_configuration.h"
40 #include "napi_common_util.h"
41 #include "napi_common_want.h"
42 #include "system_ability_definition.h"
43 #include "tokenid_kit.h"
44 
45 namespace OHOS {
46 namespace AbilityRuntime {
47 using AbilityManagerClient = AAFwk::AbilityManagerClient;
48 namespace {
GetAppManagerInstance()49 OHOS::sptr<OHOS::AppExecFwk::IAppMgr> GetAppManagerInstance()
50 {
51     OHOS::sptr<OHOS::ISystemAbilityManager> systemAbilityManager =
52         OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
53     OHOS::sptr<OHOS::IRemoteObject> appObject = systemAbilityManager->GetSystemAbility(OHOS::APP_MGR_SERVICE_ID);
54     return OHOS::iface_cast<OHOS::AppExecFwk::IAppMgr>(appObject);
55 }
56 
57 constexpr size_t ARGC_ZERO = 0;
58 constexpr size_t ARGC_ONE = 1;
59 constexpr size_t ARGC_TWO = 2;
60 constexpr size_t INDEX_ZERO = 0;
61 constexpr size_t INDEX_ONE = 1;
62 constexpr const char *ON_OFF_TYPE_ABILITY_FOREGROUND_STATE = "abilityForegroundState";
63 const std::string MAX_UINT64_VALUE = "18446744073709551615";
64 static std::shared_ptr<AppExecFwk::EventHandler> mainHandler_ = nullptr;
65 
66 class JsAbilityManager final {
67 public:
68     JsAbilityManager() = default;
69     ~JsAbilityManager() = default;
70 
Finalizer(napi_env env,void * data,void * hint)71     static void Finalizer(napi_env env, void* data, void* hint)
72     {
73         TAG_LOGI(AAFwkTag::ABILITYMGR, "finalizer called");
74         std::unique_ptr<JsAbilityManager>(static_cast<JsAbilityManager*>(data));
75     }
76 
GetAbilityRunningInfos(napi_env env,napi_callback_info info)77     static napi_value GetAbilityRunningInfos(napi_env env, napi_callback_info info)
78     {
79         GET_NAPI_INFO_AND_CALL(env, info, JsAbilityManager, OnGetAbilityRunningInfos);
80     }
81 
GetExtensionRunningInfos(napi_env env,napi_callback_info info)82     static napi_value GetExtensionRunningInfos(napi_env env, napi_callback_info info)
83     {
84         GET_NAPI_INFO_AND_CALL(env, info, JsAbilityManager, OnGetExtensionRunningInfos);
85     }
86 
UpdateConfiguration(napi_env env,napi_callback_info info)87     static napi_value UpdateConfiguration(napi_env env, napi_callback_info info)
88     {
89         GET_NAPI_INFO_AND_CALL(env, info, JsAbilityManager, OnUpdateConfiguration);
90     }
91 
GetTopAbility(napi_env env,napi_callback_info info)92     static napi_value GetTopAbility(napi_env env, napi_callback_info info)
93     {
94         GET_NAPI_INFO_AND_CALL(env, info, JsAbilityManager, OnGetTopAbility);
95     }
96 
AcquireShareData(napi_env env,napi_callback_info info)97     static napi_value AcquireShareData(napi_env env, napi_callback_info info)
98     {
99         GET_NAPI_INFO_AND_CALL(env, info, JsAbilityManager, OnAcquireShareData);
100     }
101 
NotifySaveAsResult(napi_env env,napi_callback_info info)102     static napi_value NotifySaveAsResult(napi_env env, napi_callback_info info)
103     {
104         GET_NAPI_INFO_AND_CALL(env, info, JsAbilityManager, OnNotifySaveAsResult);
105     }
GetForegroundUIAbilities(napi_env env,napi_callback_info info)106     static napi_value GetForegroundUIAbilities(napi_env env, napi_callback_info info)
107     {
108         GET_CB_INFO_AND_CALL(env, info, JsAbilityManager, OnGetForegroundUIAbilities);
109     }
110 
On(napi_env env,napi_callback_info info)111     static napi_value On(napi_env env, napi_callback_info info)
112     {
113         GET_CB_INFO_AND_CALL(env, info, JsAbilityManager, OnOn);
114     }
115 
Off(napi_env env,napi_callback_info info)116     static napi_value Off(napi_env env, napi_callback_info info)
117     {
118         GET_CB_INFO_AND_CALL(env, info, JsAbilityManager, OnOff);
119     }
120 
IsEmbeddedOpenAllowed(napi_env env,napi_callback_info info)121     static napi_value IsEmbeddedOpenAllowed(napi_env env, napi_callback_info info)
122     {
123         GET_NAPI_INFO_AND_CALL(env, info, JsAbilityManager, OnIsEmbeddedOpenAllowed);
124     }
125 
SetResidentProcessEnabled(napi_env env,napi_callback_info info)126     static napi_value SetResidentProcessEnabled(napi_env env, napi_callback_info info)
127     {
128         GET_CB_INFO_AND_CALL(env, info, JsAbilityManager, OnSetResidentProcessEnabled);
129     }
130 
NotifyDebugAssertResult(napi_env env,napi_callback_info info)131     static napi_value NotifyDebugAssertResult(napi_env env, napi_callback_info info)
132     {
133         GET_CB_INFO_AND_CALL(env, info, JsAbilityManager, OnNotifyDebugAssertResult);
134     }
135 
136 private:
137     sptr<OHOS::AbilityRuntime::JSAbilityForegroundStateObserver> observerForeground_ = nullptr;
138     sptr<OHOS::AppExecFwk::IAppMgr> appManager_ = nullptr;
139 
ParseParamType(const napi_env & env,size_t argc,const napi_value * argv)140     std::string ParseParamType(const napi_env &env, size_t argc, const napi_value *argv)
141     {
142         std::string type;
143         if (argc > INDEX_ZERO && ConvertFromJsValue(env, argv[INDEX_ZERO], type)) {
144             return type;
145         }
146         return "";
147     }
148 
OnOn(napi_env env,size_t argc,napi_value * argv)149     napi_value OnOn(napi_env env, size_t argc, napi_value *argv)
150     {
151         TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
152         if (argc < ARGC_TWO) {
153             TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid argc");
154             ThrowTooFewParametersError(env);
155             return CreateJsUndefined(env);
156         }
157         if (!AppExecFwk::IsTypeForNapiValue(env, argv[INDEX_ONE], napi_object)) {
158             TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid param");
159             ThrowInvalidParamError(env, "Parse param observer failed, must be a AbilityForegroundStateObserver.");
160             return CreateJsUndefined(env);
161         }
162 
163         std::string type = ParseParamType(env, argc, argv);
164         if (type == ON_OFF_TYPE_ABILITY_FOREGROUND_STATE) {
165             return OnOnAbilityForeground(env, argc, argv);
166         }
167         ThrowInvalidParamError(env, "Parse param type failed, must be a string, value must be abilityForegroundState.");
168         return CreateJsUndefined(env);
169     }
170 
OnOnAbilityForeground(napi_env env,size_t argc,napi_value * argv)171     napi_value OnOnAbilityForeground(napi_env env, size_t argc, napi_value *argv)
172     {
173         if (observerForeground_ == nullptr) {
174             observerForeground_ = new (std::nothrow) JSAbilityForegroundStateObserver(env);
175             if (observerForeground_ == nullptr) {
176                 TAG_LOGE(AAFwkTag::ABILITYMGR, "null observerForeground_");
177                 ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER);
178                 return CreateJsUndefined(env);
179             }
180         }
181 
182         if (observerForeground_->IsEmpty()) {
183             int32_t ret = GetAppManagerInstance()->RegisterAbilityForegroundStateObserver(observerForeground_);
184             if (ret != NO_ERROR) {
185                 TAG_LOGE(AAFwkTag::ABILITYMGR, "error: %{public}d", ret);
186                 ThrowErrorByNativeErr(env, ret);
187                 return CreateJsUndefined(env);
188             }
189         }
190         observerForeground_->AddJsObserverObject(argv[INDEX_ONE]);
191 
192         return CreateJsUndefined(env);
193     }
194 
OnOff(napi_env env,size_t argc,napi_value * argv)195     napi_value OnOff(napi_env env, size_t argc, napi_value *argv)
196     {
197         TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
198         if (argc < ARGC_ONE) {
199             TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid argc");
200             ThrowTooFewParametersError(env);
201             return CreateJsUndefined(env);
202         }
203         if (argc == ARGC_TWO && !AppExecFwk::IsTypeForNapiValue(env, argv[INDEX_ONE], napi_object)) {
204             TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid param");
205             ThrowInvalidParamError(env, "Parse param observer failed, must be a AbilityForegroundStateObserver.");
206             return CreateJsUndefined(env);
207         }
208 
209         std::string type = ParseParamType(env, argc, argv);
210         if (type == ON_OFF_TYPE_ABILITY_FOREGROUND_STATE) {
211             return OnOffAbilityForeground(env, argc, argv);
212         }
213         ThrowInvalidParamError(env, "Parse param type failed, must be a string, value must be abilityForegroundState.");
214         return CreateJsUndefined(env);
215     }
216 
CheckIsNumString(const std::string & numStr)217     bool CheckIsNumString(const std::string &numStr)
218     {
219         const std::regex regexJsperf(R"(^\d*)");
220         std::match_results<std::string::const_iterator> matchResults;
221         if (numStr.empty() || !std::regex_match(numStr, matchResults, regexJsperf)) {
222             TAG_LOGE(AAFwkTag::ABILITYMGR, "parse failed: %{public}s", numStr.c_str());
223             return false;
224         }
225         if (MAX_UINT64_VALUE.length() < numStr.length() ||
226             (MAX_UINT64_VALUE.length() == numStr.length() && MAX_UINT64_VALUE.compare(numStr) < 0)) {
227             TAG_LOGE(AAFwkTag::ABILITYMGR, "parse failed: %{public}s", numStr.c_str());
228             return false;
229         }
230         return true;
231     }
232 
OnNotifyDebugAssertResult(napi_env env,size_t argc,napi_value * argv)233     napi_value OnNotifyDebugAssertResult(napi_env env, size_t argc, napi_value *argv)
234     {
235         TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
236         if (argc < ARGC_TWO) {
237             TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid argc");
238             ThrowTooFewParametersError(env);
239             return CreateJsUndefined(env);
240         }
241 
242         std::string assertSessionStr;
243         if (!ConvertFromJsValue(env, argv[INDEX_ZERO], assertSessionStr) || !CheckIsNumString(assertSessionStr)) {
244             TAG_LOGE(AAFwkTag::ABILITYMGR, "convert sessionId failed");
245             ThrowInvalidParamError(env, "Parse param sessionId failed, must be a string.");
246             return CreateJsUndefined(env);
247         }
248         uint64_t assertSessionId = std::stoull(assertSessionStr);
249         if (assertSessionId == 0) {
250             TAG_LOGE(AAFwkTag::ABILITYMGR, "convert sessionId failed");
251             ThrowInvalidParamError(env, "Parse param sessionId failed, value must not be equal to zero.");
252             return CreateJsUndefined(env);
253         }
254         int32_t userStatus;
255         if (!ConvertFromJsValue(env, argv[INDEX_ONE], userStatus)) {
256             TAG_LOGE(AAFwkTag::ABILITYMGR, "convert status failed");
257             ThrowInvalidParamError(env, "Parse param status failed, must be a UserStatus.");
258             return CreateJsUndefined(env);
259         }
260 
261         NapiAsyncTask::CompleteCallback complete =
262             [assertSessionId, userStatus](napi_env env, NapiAsyncTask &task, int32_t status) {
263             auto amsClient = AbilityManagerClient::GetInstance();
264             if (amsClient == nullptr) {
265                 TAG_LOGE(AAFwkTag::ABILITYMGR, "null amsClient");
266                 task.Reject(env, CreateJsError(env, GetJsErrorCodeByNativeError(AAFwk::INNER_ERR)));
267                 return;
268             }
269             auto ret = amsClient->NotifyDebugAssertResult(assertSessionId, static_cast<AAFwk::UserStatus>(userStatus));
270             if (ret != ERR_OK) {
271                 TAG_LOGE(AAFwkTag::ABILITYMGR, "notify assert ret failed, ret: %{public}d", ret);
272                 task.Reject(env, CreateJsError(env, GetJsErrorCodeByNativeError(ret)));
273                 return;
274             }
275             task.ResolveWithNoError(env, CreateJsUndefined(env));
276         };
277 
278         napi_value result = nullptr;
279         NapiAsyncTask::Schedule("JsAbilityManager::OnNotifyDebugAssertResult", env,
280             CreateAsyncTaskWithLastParam(env, nullptr, nullptr, std::move(complete), &result));
281         return result;
282     }
283 
OnOffAbilityForeground(napi_env env,size_t argc,napi_value * argv)284     napi_value OnOffAbilityForeground(napi_env env, size_t argc, napi_value *argv)
285     {
286         if (observerForeground_ == nullptr) {
287             TAG_LOGE(AAFwkTag::ABILITYMGR, "null observer");
288             ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER);
289             return CreateJsUndefined(env);
290         }
291         if (argc == ARGC_TWO) {
292             observerForeground_->RemoveJsObserverObject(argv[INDEX_ONE]);
293         } else {
294             observerForeground_->RemoveAllJsObserverObject();
295         }
296 
297         if (observerForeground_->IsEmpty()) {
298             int32_t ret = GetAppManagerInstance()->UnregisterAbilityForegroundStateObserver(observerForeground_);
299             if (ret != NO_ERROR) {
300                 TAG_LOGE(AAFwkTag::ABILITYMGR, "error: %{public}d", ret);
301                 ThrowErrorByNativeErr(env, ret);
302                 return CreateJsUndefined(env);
303             }
304         }
305         return CreateJsUndefined(env);
306     }
307 
OnGetAbilityRunningInfos(napi_env env,NapiCallbackInfo & info)308     napi_value OnGetAbilityRunningInfos(napi_env env, NapiCallbackInfo& info)
309     {
310         TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
311         NapiAsyncTask::CompleteCallback complete =
312             [](napi_env env, NapiAsyncTask &task, int32_t status) {
313                 std::vector<AAFwk::AbilityRunningInfo> infos;
314                 auto errcode = AbilityManagerClient::GetInstance()->GetAbilityRunningInfos(infos);
315                 if (errcode == 0) {
316 #ifdef ENABLE_ERRCODE
317                     task.ResolveWithNoError(env, CreateJsAbilityRunningInfoArray(env, infos));
318                 } else {
319                     task.Reject(env, CreateJsError(env, GetJsErrorCodeByNativeError(errcode)));
320 #else
321                     task.Resolve(env, CreateJsAbilityRunningInfoArray(env, infos));
322                 } else {
323                     task.Reject(env, CreateJsError(env, errcode, "Get mission infos failed."));
324 #endif
325                 }
326             };
327 
328         napi_value lastParam = (info.argc == 0) ? nullptr : info.argv[0];
329         napi_value result = nullptr;
330         NapiAsyncTask::ScheduleHighQos("JsAbilityManager::OnGetAbilityRunningInfos",
331             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
332         return result;
333     }
334 
OnGetExtensionRunningInfos(napi_env env,NapiCallbackInfo & info)335     napi_value OnGetExtensionRunningInfos(napi_env env, NapiCallbackInfo& info)
336     {
337         TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
338         if (info.argc == 0) {
339             TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid argc");
340 #ifdef ENABLE_ERRCODE
341             ThrowTooFewParametersError(env);
342 #endif
343             return CreateJsUndefined(env);
344         }
345         int upperLimit = -1;
346         if (!ConvertFromJsValue(env, info.argv[0], upperLimit)) {
347 #ifdef ENABLE_ERRCODE
348             ThrowInvalidParamError(env, "Parse param upperLimit failed, must be a number.");
349 #endif
350             return CreateJsUndefined(env);
351         }
352 
353         NapiAsyncTask::CompleteCallback complete =
354             [upperLimit](napi_env env, NapiAsyncTask &task, int32_t status) {
355                 std::vector<AAFwk::ExtensionRunningInfo> infos;
356                 auto errcode = AbilityManagerClient::GetInstance()->GetExtensionRunningInfos(upperLimit, infos);
357                 if (errcode == 0) {
358 #ifdef ENABLE_ERRCODE
359                     task.ResolveWithNoError(env, CreateJsExtensionRunningInfoArray(env, infos));
360                 } else {
361                     task.Reject(env, CreateJsError(env, GetJsErrorCodeByNativeError(errcode)));
362 #else
363                     task.Resolve(env, CreateJsExtensionRunningInfoArray(env, infos));
364                 } else {
365                     task.Reject(env, CreateJsError(env, errcode, "Get mission infos failed."));
366 #endif
367                 }
368             };
369 
370         napi_value lastParam = (info.argc == 1) ? nullptr : info.argv[1];
371         napi_value result = nullptr;
372         NapiAsyncTask::ScheduleHighQos("JsAbilityManager::OnGetExtensionRunningInfos",
373             env, CreateAsyncTaskWithLastParam(env,
374             lastParam, nullptr, std::move(complete), &result));
375         return result;
376     }
377 
OnUpdateConfiguration(napi_env env,NapiCallbackInfo & info)378     napi_value OnUpdateConfiguration(napi_env env, NapiCallbackInfo& info)
379     {
380         TAG_LOGI(AAFwkTag::ABILITYMGR, "called");
381         NapiAsyncTask::CompleteCallback complete;
382 
383         do {
384             if (info.argc == 0) {
385                 TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid argc");
386 #ifdef ENABLE_ERRCODE
387                 ThrowTooFewParametersError(env);
388 #else
389                 complete = [](napi_env env, NapiAsyncTask& task, int32_t status) {
390                     task.Reject(env, CreateJsError(env, ERR_INVALID_VALUE, "no enough params."));
391                 };
392 #endif
393                 break;
394             }
395 
396             AppExecFwk::Configuration changeConfig;
397             if (!UnwrapConfiguration(env, info.argv[0], changeConfig)) {
398 #ifdef ENABLE_ERRCODE
399                 ThrowInvalidParamError(env, "Parse param config failed, must be a Configuration.");
400 #else
401                 complete = [](napi_env env, NapiAsyncTask& task, int32_t status) {
402                     task.Reject(env, CreateJsError(env, ERR_INVALID_VALUE, "config is invalid."));
403                 };
404 #endif
405                 break;
406             }
407 
408             complete = [changeConfig](napi_env env, NapiAsyncTask& task, int32_t status) {
409                 auto errcode = GetAppManagerInstance()->UpdateConfiguration(changeConfig);
410                 if (errcode == 0) {
411 #ifdef ENABLE_ERRCODE
412                     task.ResolveWithNoError(env, CreateJsUndefined(env));
413                 } else {
414                     task.Reject(env, CreateJsError(env, GetJsErrorCodeByNativeError(errcode)));
415 #else
416                     task.Resolve(env, CreateJsUndefined(env));
417                 } else {
418                     task.Reject(env, CreateJsError(env, errcode, "update config failed."));
419 #endif
420                 }
421             };
422         } while (0);
423 
424         napi_value lastParam = (info.argc == 1) ? nullptr : info.argv[1];
425         napi_value result = nullptr;
426         NapiAsyncTask::ScheduleHighQos("JsAbilityManager::OnGetExtensionRunningInfos",
427             env, CreateAsyncTaskWithLastParam(env,
428             lastParam, nullptr, std::move(complete), &result));
429         return result;
430     }
431 
OnGetTopAbility(napi_env env,NapiCallbackInfo & info)432     napi_value OnGetTopAbility(napi_env env, NapiCallbackInfo& info)
433     {
434         TAG_LOGI(AAFwkTag::ABILITYMGR, "called");
435 #ifdef ENABLE_ERRCODE
436         auto selfToken = IPCSkeleton::GetSelfTokenID();
437         if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken)) {
438             TAG_LOGE(AAFwkTag::ABILITYMGR, "not system app");
439             ThrowError(env, AbilityErrorCode::ERROR_CODE_NOT_SYSTEM_APP);
440             return CreateJsUndefined(env);
441         }
442 #endif
443         NapiAsyncTask::CompleteCallback complete =
444             [](napi_env env, NapiAsyncTask &task, int32_t status) {
445                 AppExecFwk::ElementName elementName = AbilityManagerClient::GetInstance()->GetTopAbility();
446 #ifdef ENABLE_ERRCOE
447                 task.ResolveWithNoError(env, CreateJsElementName(env, elementName));
448 #else
449                 task.Resolve(env, CreateJsElementName(env, elementName));
450 #endif
451             };
452 
453         napi_value lastParam = (info.argc == 0) ? nullptr : info.argv[0];
454         napi_value result = nullptr;
455         NapiAsyncTask::ScheduleHighQos("JsAbilityManager::OnGetTopAbility",
456             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
457         return result;
458     }
459 
OnAcquireShareData(napi_env env,NapiCallbackInfo & info)460     napi_value OnAcquireShareData(napi_env env, NapiCallbackInfo& info)
461     {
462         TAG_LOGI(AAFwkTag::ABILITYMGR, "called");
463         if (info.argc < ARGC_ONE) {
464             ThrowTooFewParametersError(env);
465             return CreateJsUndefined(env);
466         }
467         int32_t missionId = -1;
468         if (!ConvertFromJsValue(env, info.argv[INDEX_ZERO], missionId)) {
469             ThrowInvalidParamError(env, "Parse param missionId failed, must be a number.");
470             return CreateJsUndefined(env);
471         }
472         napi_value lastParam = info.argc > ARGC_ONE  ? info.argv[INDEX_ONE] : nullptr;
473         napi_value result = nullptr;
474         std::unique_ptr<NapiAsyncTask> uasyncTask = CreateAsyncTaskWithLastParam(
475             env, lastParam, nullptr, nullptr, &result);
476         std::shared_ptr<NapiAsyncTask> asyncTask = std::move(uasyncTask);
477 
478         AAFwk::ShareRuntimeTask task = [env, asyncTask](int32_t resultCode, const AAFwk::WantParams &wantParam) {
479             if (resultCode != 0) {
480                 asyncTask->Reject(env, CreateJsError(env, GetJsErrorCodeByNativeError(resultCode)));
481                 return;
482             }
483             napi_value abilityResult = AppExecFwk::WrapWantParams(env, wantParam);
484             if (abilityResult == nullptr) {
485                 asyncTask->Reject(env, CreateJsError(env, AbilityErrorCode::ERROR_CODE_INNER));
486             } else {
487                 asyncTask->ResolveWithNoError(env, abilityResult);
488             }
489         };
490         sptr<AAFwk::AcquireShareDataCallbackStub> shareDataCallbackStub = new AAFwk::AcquireShareDataCallbackStub();
491         mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
492         shareDataCallbackStub->SetHandler(mainHandler_);
493         shareDataCallbackStub->SetShareRuntimeTask(task);
494         auto err = AbilityManagerClient::GetInstance()->AcquireShareData(missionId, shareDataCallbackStub);
495         if (err != 0) {
496             asyncTask->Reject(env, CreateJsError(env, GetJsErrorCodeByNativeError(err)));
497         }
498         return result;
499     }
500 
OnNotifySaveAsResult(napi_env env,NapiCallbackInfo & info)501     napi_value OnNotifySaveAsResult(napi_env env, NapiCallbackInfo& info)
502     {
503         TAG_LOGI(AAFwkTag::ABILITYMGR, "called");
504         NapiAsyncTask::CompleteCallback complete;
505         NapiAsyncTask::ExecuteCallback execute;
506 
507         do {
508             if (info.argc < ARGC_TWO) {
509                 TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid argc");
510                 ThrowTooFewParametersError(env);
511                 break;
512             }
513 
514             int reqCode = 0;
515             if (!ConvertFromJsValue(env, info.argv[1], reqCode)) {
516                 TAG_LOGE(AAFwkTag::ABILITYMGR, "get requestCode failed");
517                 ThrowInvalidParamError(env, "Parse param requestCode failed, must be a number.");
518                 break;
519             }
520 
521             AppExecFwk::Want want;
522             int resultCode = ERR_OK;
523             if (!AppExecFwk::UnWrapAbilityResult(env, info.argv[0], resultCode, want)) {
524                 TAG_LOGE(AAFwkTag::ABILITYMGR, "unwrap abilityResult failed");
525                 ThrowInvalidParamError(env, "Parse param parameter failed, must be a AbilityResult.");
526                 break;
527             }
528 
529             auto sharedCode = std::make_shared<ErrCode>(ERR_OK);
530             execute = [sharedCode, want, resultCode, reqCode]() {
531                 *sharedCode = AbilityManagerClient::GetInstance()->NotifySaveAsResult(want, resultCode, reqCode);
532             };
533             complete = [sharedCode](napi_env env, NapiAsyncTask& task, int32_t status) {
534                 auto errCode = *sharedCode;
535                 if (errCode == ERR_OK) {
536                     task.ResolveWithNoError(env, CreateJsUndefined(env));
537                 } else {
538                     task.Reject(env, CreateJsError(env, GetJsErrorCodeByNativeError(errCode)));
539                 }
540             };
541         } while (0);
542 
543         napi_value lastParam = (info.argc == ARGC_TWO) ? nullptr : info.argv[ARGC_TWO];
544         napi_value result = nullptr;
545         NapiAsyncTask::ScheduleHighQos("JsAbilityManager::OnNotifySaveAsResult", env,
546             CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
547         return result;
548     }
549 
OnGetForegroundUIAbilities(napi_env env,size_t argc,napi_value * argv)550     napi_value OnGetForegroundUIAbilities(napi_env env, size_t argc, napi_value *argv)
551     {
552         TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
553         NapiAsyncTask::CompleteCallback complete = [](napi_env env, NapiAsyncTask &task, int32_t status) {
554             std::vector<AppExecFwk::AbilityStateData> list;
555             int32_t ret = AbilityManagerClient::GetInstance()->GetForegroundUIAbilities(list);
556             if (ret == ERR_OK) {
557                 task.ResolveWithNoError(env, CreateJsAbilityStateDataArray(env, list));
558             } else {
559                 TAG_LOGE(AAFwkTag::ABILITYMGR, "error: %{public}d", ret);
560                 task.Reject(env, CreateJsError(env, GetJsErrorCodeByNativeError(ret)));
561             }
562         };
563 
564         napi_value lastParam = (argc > ARGC_ZERO) ? argv[INDEX_ZERO] : nullptr;
565         napi_value result = nullptr;
566         NapiAsyncTask::Schedule("JsAbilityManager::OnGetForegroundUIAbilities", env,
567             CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
568         return result;
569     }
570 
OnSetResidentProcessEnabled(napi_env env,size_t argc,napi_value * argv)571     napi_value OnSetResidentProcessEnabled(napi_env env, size_t argc, napi_value *argv)
572     {
573         TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
574         if (argc < ARGC_TWO) {
575             TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid argc");
576             ThrowTooFewParametersError(env);
577             return CreateJsUndefined(env);
578         }
579 
580         std::string bundleName;
581         if (!ConvertFromJsValue(env, argv[INDEX_ZERO], bundleName) || bundleName.empty()) {
582             TAG_LOGE(AAFwkTag::ABILITYMGR, "parse bundleName failed, not string");
583             ThrowInvalidParamError(env, "Parse param bundleName failed, must be a string.");
584             return CreateJsUndefined(env);
585         }
586 
587         bool enableState = false;
588         if (!ConvertFromJsValue(env, argv[INDEX_ONE], enableState)) {
589             TAG_LOGE(AAFwkTag::ABILITYMGR, "parse enable failed, not boolean");
590             ThrowInvalidParamError(env, "Parse param enable failed, must be a boolean.");
591             return CreateJsUndefined(env);
592         }
593 
594         auto innerErrorCode = std::make_shared<int32_t>(ERR_OK);
595         NapiAsyncTask::ExecuteCallback execute = [bundleName, enableState, innerErrorCode, env]() {
596             auto amsClient = AbilityManagerClient::GetInstance();
597             if (amsClient == nullptr) {
598                 TAG_LOGE(AAFwkTag::ABILITYMGR, "null amsClient");
599                 *innerErrorCode = static_cast<int32_t>(AAFwk::INNER_ERR);
600                 return;
601             }
602             *innerErrorCode = amsClient->SetResidentProcessEnabled(bundleName, enableState);
603         };
604 
605         NapiAsyncTask::CompleteCallback complete = [innerErrorCode](napi_env env, NapiAsyncTask &task, int32_t status) {
606             if (*innerErrorCode != ERR_OK) {
607                 TAG_LOGE(AAFwkTag::ABILITYMGR, "set resident process result failed, error: %{public}d",
608                     *innerErrorCode);
609                 task.Reject(env, CreateJsErrorByNativeErr(env, *innerErrorCode));
610                 return;
611             }
612             task.ResolveWithNoError(env, CreateJsUndefined(env));
613         };
614 
615         napi_value result = nullptr;
616         NapiAsyncTask::Schedule("JsAbilityManager::OnSetResidentProcessEnabled", env,
617             CreateAsyncTaskWithLastParam(env, nullptr, std::move(execute), std::move(complete), &result));
618         return result;
619     }
620 
OnIsEmbeddedOpenAllowed(napi_env env,NapiCallbackInfo & info)621     napi_value OnIsEmbeddedOpenAllowed(napi_env env, NapiCallbackInfo& info)
622     {
623         TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
624         if (info.argc < ARGC_TWO) {
625             TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid argc");
626             ThrowTooFewParametersError(env);
627             return CreateJsUndefined(env);
628         }
629 
630         bool stageMode = false;
631         napi_status status = OHOS::AbilityRuntime::IsStageContext(env, info.argv[0], stageMode);
632         if (status != napi_ok || !stageMode) {
633             TAG_LOGE(AAFwkTag::ABILITYMGR, "not stageMode");
634             ThrowInvalidParamError(env, "Parse param context failed, must be a context of stageMode.");
635             return CreateJsUndefined(env);
636         }
637         auto context = OHOS::AbilityRuntime::GetStageModeContext(env, info.argv[0]);
638         if (context == nullptr) {
639             TAG_LOGE(AAFwkTag::ABILITYMGR, "null context");
640             ThrowInvalidParamError(env, "Parse param context failed, must not be nullptr.");
641             return CreateJsUndefined(env);
642         }
643         auto uiAbilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context);
644         if (uiAbilityContext == nullptr) {
645             TAG_LOGE(AAFwkTag::ABILITYMGR, "null UIAbilityContext");
646             ThrowInvalidParamError(env, "Parse param context failed, must be UIAbilityContext.");
647             return CreateJsUndefined(env);
648         }
649 
650         std::string appId;
651         if (!ConvertFromJsValue(env, info.argv[1], appId)) {
652             TAG_LOGE(AAFwkTag::ABILITYMGR, "parse appId failed");
653             ThrowInvalidParamError(env, "Parse param appId failed, must be a string.");
654             return CreateJsUndefined(env);
655         }
656 
657         auto token = uiAbilityContext->GetToken();
658         auto sharedResult = std::make_shared<bool>(false);
659         NapiAsyncTask::ExecuteCallback execute = [sharedResult, token, appId]() {
660             *sharedResult = AbilityManagerClient::GetInstance()->IsEmbeddedOpenAllowed(token, appId);
661         };
662 
663         NapiAsyncTask::CompleteCallback complete = [sharedResult](napi_env env, NapiAsyncTask &task, int32_t status) {
664             task.Resolve(env, CreateJsValue(env, *sharedResult));
665         };
666 
667         napi_value lastParam = (info.argc > ARGC_TWO) ? info. argv[ARGC_TWO] : nullptr;
668         napi_value result = nullptr;
669         NapiAsyncTask::Schedule("JsAbilityManager::OnIsEmbeddedOpenAllowed", env,
670             CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
671         return result;
672     }
673 };
674 } // namespace
675 
JsAbilityManagerInit(napi_env env,napi_value exportObj)676 napi_value JsAbilityManagerInit(napi_env env, napi_value exportObj)
677 {
678     TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
679 
680     std::unique_ptr<JsAbilityManager> jsAbilityManager = std::make_unique<JsAbilityManager>();
681     napi_wrap(env, exportObj, jsAbilityManager.release(), JsAbilityManager::Finalizer, nullptr, nullptr);
682 
683     napi_set_named_property(env, exportObj, "AbilityState", AbilityStateInit(env));
684     napi_set_named_property(env, exportObj, "UserStatus", UserStatusInit(env));
685 
686     const char *moduleName = "JsAbilityManager";
687     BindNativeFunction(env, exportObj, "getAbilityRunningInfos", moduleName,
688         JsAbilityManager::GetAbilityRunningInfos);
689     BindNativeFunction(env, exportObj, "getExtensionRunningInfos", moduleName,
690         JsAbilityManager::GetExtensionRunningInfos);
691     BindNativeFunction(env, exportObj, "updateConfiguration", moduleName, JsAbilityManager::UpdateConfiguration);
692     BindNativeFunction(env, exportObj, "getTopAbility", moduleName, JsAbilityManager::GetTopAbility);
693     BindNativeFunction(env, exportObj, "acquireShareData", moduleName, JsAbilityManager::AcquireShareData);
694     BindNativeFunction(env, exportObj, "notifySaveAsResult", moduleName, JsAbilityManager::NotifySaveAsResult);
695     BindNativeFunction(
696         env, exportObj, "getForegroundUIAbilities", moduleName, JsAbilityManager::GetForegroundUIAbilities);
697     BindNativeFunction(env, exportObj, "on", moduleName, JsAbilityManager::On);
698     BindNativeFunction(env, exportObj, "off", moduleName, JsAbilityManager::Off);
699     BindNativeFunction(env, exportObj, "isEmbeddedOpenAllowed", moduleName, JsAbilityManager::IsEmbeddedOpenAllowed);
700     BindNativeFunction(
701         env, exportObj, "notifyDebugAssertResult", moduleName, JsAbilityManager::NotifyDebugAssertResult);
702     BindNativeFunction(
703         env, exportObj, "setResidentProcessEnabled", moduleName, JsAbilityManager::SetResidentProcessEnabled);
704     TAG_LOGD(AAFwkTag::ABILITYMGR, "end");
705     return CreateJsUndefined(env);
706 }
707 }  // namespace AbilityRuntime
708 }  // namespace OHOS
709