• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "js_query_erms_observer.h"
43 #include "system_ability_definition.h"
44 #include "tokenid_kit.h"
45 
46 namespace OHOS {
47 namespace AbilityRuntime {
48 using AbilityManagerClient = AAFwk::AbilityManagerClient;
49 namespace {
GetAppManagerInstance()50 OHOS::sptr<OHOS::AppExecFwk::IAppMgr> GetAppManagerInstance()
51 {
52     OHOS::sptr<OHOS::ISystemAbilityManager> systemAbilityManager =
53         OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
54     OHOS::sptr<OHOS::IRemoteObject> appObject = systemAbilityManager->GetSystemAbility(OHOS::APP_MGR_SERVICE_ID);
55     return OHOS::iface_cast<OHOS::AppExecFwk::IAppMgr>(appObject);
56 }
57 
58 constexpr size_t ARGC_ZERO = 0;
59 constexpr size_t ARGC_ONE = 1;
60 constexpr size_t ARGC_TWO = 2;
61 constexpr size_t INDEX_ZERO = 0;
62 constexpr size_t INDEX_ONE = 1;
63 constexpr const char *ON_OFF_TYPE_ABILITY_FOREGROUND_STATE = "abilityForegroundState";
64 const std::string MAX_UINT64_VALUE = "18446744073709551615";
65 static std::shared_ptr<AppExecFwk::EventHandler> mainHandler_ = nullptr;
66 
67 class JsAbilityManager final {
68 public:
69     JsAbilityManager() = default;
70     ~JsAbilityManager() = default;
71 
Finalizer(napi_env env,void * data,void * hint)72     static void Finalizer(napi_env env, void* data, void* hint)
73     {
74         TAG_LOGI(AAFwkTag::ABILITYMGR, "finalizer called");
75         std::unique_ptr<JsAbilityManager>(static_cast<JsAbilityManager*>(data));
76     }
77 
GetAbilityRunningInfos(napi_env env,napi_callback_info info)78     static napi_value GetAbilityRunningInfos(napi_env env, napi_callback_info info)
79     {
80         GET_NAPI_INFO_AND_CALL(env, info, JsAbilityManager, OnGetAbilityRunningInfos);
81     }
82 
GetExtensionRunningInfos(napi_env env,napi_callback_info info)83     static napi_value GetExtensionRunningInfos(napi_env env, napi_callback_info info)
84     {
85         GET_NAPI_INFO_AND_CALL(env, info, JsAbilityManager, OnGetExtensionRunningInfos);
86     }
87 
UpdateConfiguration(napi_env env,napi_callback_info info)88     static napi_value UpdateConfiguration(napi_env env, napi_callback_info info)
89     {
90         GET_NAPI_INFO_AND_CALL(env, info, JsAbilityManager, OnUpdateConfiguration);
91     }
92 
GetTopAbility(napi_env env,napi_callback_info info)93     static napi_value GetTopAbility(napi_env env, napi_callback_info info)
94     {
95         GET_NAPI_INFO_AND_CALL(env, info, JsAbilityManager, OnGetTopAbility);
96     }
97 
AcquireShareData(napi_env env,napi_callback_info info)98     static napi_value AcquireShareData(napi_env env, napi_callback_info info)
99     {
100         GET_NAPI_INFO_AND_CALL(env, info, JsAbilityManager, OnAcquireShareData);
101     }
102 
NotifySaveAsResult(napi_env env,napi_callback_info info)103     static napi_value NotifySaveAsResult(napi_env env, napi_callback_info info)
104     {
105         GET_NAPI_INFO_AND_CALL(env, info, JsAbilityManager, OnNotifySaveAsResult);
106     }
GetForegroundUIAbilities(napi_env env,napi_callback_info info)107     static napi_value GetForegroundUIAbilities(napi_env env, napi_callback_info info)
108     {
109         GET_CB_INFO_AND_CALL(env, info, JsAbilityManager, OnGetForegroundUIAbilities);
110     }
111 
On(napi_env env,napi_callback_info info)112     static napi_value On(napi_env env, napi_callback_info info)
113     {
114         GET_CB_INFO_AND_CALL(env, info, JsAbilityManager, OnOn);
115     }
116 
Off(napi_env env,napi_callback_info info)117     static napi_value Off(napi_env env, napi_callback_info info)
118     {
119         GET_CB_INFO_AND_CALL(env, info, JsAbilityManager, OnOff);
120     }
121 
IsEmbeddedOpenAllowed(napi_env env,napi_callback_info info)122     static napi_value IsEmbeddedOpenAllowed(napi_env env, napi_callback_info info)
123     {
124         GET_NAPI_INFO_AND_CALL(env, info, JsAbilityManager, OnIsEmbeddedOpenAllowed);
125     }
126 
QueryAtomicServiceStartupRule(napi_env env,napi_callback_info info)127     static napi_value QueryAtomicServiceStartupRule(napi_env env, napi_callback_info info)
128     {
129         GET_NAPI_INFO_AND_CALL(env, info, JsAbilityManager, OnQueryAtomicServiceStartupRule);
130     }
131 
RestartSelfAtomicService(napi_env env,napi_callback_info info)132     static napi_value RestartSelfAtomicService(napi_env env, napi_callback_info info)
133     {
134         GET_NAPI_INFO_AND_CALL(env, info, JsAbilityManager, OnRestartSelfAtomicService);
135     }
136 
SetResidentProcessEnabled(napi_env env,napi_callback_info info)137     static napi_value SetResidentProcessEnabled(napi_env env, napi_callback_info info)
138     {
139         GET_CB_INFO_AND_CALL(env, info, JsAbilityManager, OnSetResidentProcessEnabled);
140     }
141 
NotifyDebugAssertResult(napi_env env,napi_callback_info info)142     static napi_value NotifyDebugAssertResult(napi_env env, napi_callback_info info)
143     {
144         GET_CB_INFO_AND_CALL(env, info, JsAbilityManager, OnNotifyDebugAssertResult);
145     }
146 
147 private:
148     sptr<OHOS::AbilityRuntime::JSAbilityForegroundStateObserver> observerForeground_ = nullptr;
149     sptr<JsQueryERMSObserver> queryERMSObserver_ = nullptr;
150 
ParseParamType(const napi_env & env,size_t argc,const napi_value * argv)151     std::string ParseParamType(const napi_env &env, size_t argc, const napi_value *argv)
152     {
153         std::string type;
154         if (argc > INDEX_ZERO && ConvertFromJsValue(env, argv[INDEX_ZERO], type)) {
155             return type;
156         }
157         return "";
158     }
159 
OnOn(napi_env env,size_t argc,napi_value * argv)160     napi_value OnOn(napi_env env, size_t argc, napi_value *argv)
161     {
162         TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
163         if (argc < ARGC_TWO) {
164             TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid argc");
165             ThrowTooFewParametersError(env);
166             return CreateJsUndefined(env);
167         }
168         if (!AppExecFwk::IsTypeForNapiValue(env, argv[INDEX_ONE], napi_object)) {
169             TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid param");
170             ThrowInvalidParamError(env, "Parse param observer failed, must be a AbilityForegroundStateObserver.");
171             return CreateJsUndefined(env);
172         }
173 
174         std::string type = ParseParamType(env, argc, argv);
175         if (type == ON_OFF_TYPE_ABILITY_FOREGROUND_STATE) {
176             return OnOnAbilityForeground(env, argc, argv);
177         }
178         ThrowInvalidParamError(env, "Parse param type failed, must be a string, value must be abilityForegroundState.");
179         return CreateJsUndefined(env);
180     }
181 
OnOnAbilityForeground(napi_env env,size_t argc,napi_value * argv)182     napi_value OnOnAbilityForeground(napi_env env, size_t argc, napi_value *argv)
183     {
184         if (observerForeground_ == nullptr) {
185             observerForeground_ = new (std::nothrow) JSAbilityForegroundStateObserver(env);
186             if (observerForeground_ == nullptr) {
187                 TAG_LOGE(AAFwkTag::ABILITYMGR, "null observerForeground_");
188                 ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER);
189                 return CreateJsUndefined(env);
190             }
191             napi_add_env_cleanup_hook(env, JSAbilityForegroundStateObserver::CleanUp,
192                 new wptr<JSAbilityForegroundStateObserver>(observerForeground_));
193         }
194 
195         if (observerForeground_->IsEmpty()) {
196             int32_t ret = GetAppManagerInstance()->RegisterAbilityForegroundStateObserver(observerForeground_);
197             if (ret != NO_ERROR) {
198                 TAG_LOGE(AAFwkTag::ABILITYMGR, "error: %{public}d", ret);
199                 ThrowErrorByNativeErr(env, ret);
200                 return CreateJsUndefined(env);
201             }
202         }
203         observerForeground_->AddJsObserverObject(argv[INDEX_ONE]);
204 
205         return CreateJsUndefined(env);
206     }
207 
OnOff(napi_env env,size_t argc,napi_value * argv)208     napi_value OnOff(napi_env env, size_t argc, napi_value *argv)
209     {
210         TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
211         if (argc < ARGC_ONE) {
212             TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid argc");
213             ThrowTooFewParametersError(env);
214             return CreateJsUndefined(env);
215         }
216         if (argc == ARGC_TWO && !AppExecFwk::IsTypeForNapiValue(env, argv[INDEX_ONE], napi_object)) {
217             TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid param");
218             ThrowInvalidParamError(env, "Parse param observer failed, must be a AbilityForegroundStateObserver.");
219             return CreateJsUndefined(env);
220         }
221 
222         std::string type = ParseParamType(env, argc, argv);
223         if (type == ON_OFF_TYPE_ABILITY_FOREGROUND_STATE) {
224             return OnOffAbilityForeground(env, argc, argv);
225         }
226         ThrowInvalidParamError(env, "Parse param type failed, must be a string, value must be abilityForegroundState.");
227         return CreateJsUndefined(env);
228     }
229 
CheckIsNumString(const std::string & numStr)230     bool CheckIsNumString(const std::string &numStr)
231     {
232         const std::regex regexJsperf(R"(^\d*)");
233         std::match_results<std::string::const_iterator> matchResults;
234         if (numStr.empty() || !std::regex_match(numStr, matchResults, regexJsperf)) {
235             TAG_LOGE(AAFwkTag::ABILITYMGR, "parse failed: %{public}s", numStr.c_str());
236             return false;
237         }
238         if (MAX_UINT64_VALUE.length() < numStr.length() ||
239             (MAX_UINT64_VALUE.length() == numStr.length() && MAX_UINT64_VALUE.compare(numStr) < 0)) {
240             TAG_LOGE(AAFwkTag::ABILITYMGR, "parse failed: %{public}s", numStr.c_str());
241             return false;
242         }
243         return true;
244     }
245 
OnNotifyDebugAssertResult(napi_env env,size_t argc,napi_value * argv)246     napi_value OnNotifyDebugAssertResult(napi_env env, size_t argc, napi_value *argv)
247     {
248         TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
249         if (argc < ARGC_TWO) {
250             TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid argc");
251             ThrowTooFewParametersError(env);
252             return CreateJsUndefined(env);
253         }
254 
255         std::string assertSessionStr;
256         if (!ConvertFromJsValue(env, argv[INDEX_ZERO], assertSessionStr) || !CheckIsNumString(assertSessionStr)) {
257             TAG_LOGE(AAFwkTag::ABILITYMGR, "convert sessionId failed");
258             ThrowInvalidParamError(env, "Parse param sessionId failed, must be a string.");
259             return CreateJsUndefined(env);
260         }
261         uint64_t assertSessionId = std::stoull(assertSessionStr);
262         if (assertSessionId == 0) {
263             TAG_LOGE(AAFwkTag::ABILITYMGR, "convert sessionId failed");
264             ThrowInvalidParamError(env, "Parse param sessionId failed, value must not be equal to zero.");
265             return CreateJsUndefined(env);
266         }
267         int32_t userStatus;
268         if (!ConvertFromJsValue(env, argv[INDEX_ONE], userStatus)) {
269             TAG_LOGE(AAFwkTag::ABILITYMGR, "convert status failed");
270             ThrowInvalidParamError(env, "Parse param status failed, must be a UserStatus.");
271             return CreateJsUndefined(env);
272         }
273 
274         NapiAsyncTask::CompleteCallback complete =
275             [assertSessionId, userStatus](napi_env env, NapiAsyncTask &task, int32_t status) {
276             auto amsClient = AbilityManagerClient::GetInstance();
277             if (amsClient == nullptr) {
278                 TAG_LOGE(AAFwkTag::ABILITYMGR, "null amsClient");
279                 task.Reject(env, CreateJsError(env, GetJsErrorCodeByNativeError(AAFwk::INNER_ERR)));
280                 return;
281             }
282             auto ret = amsClient->NotifyDebugAssertResult(assertSessionId, static_cast<AAFwk::UserStatus>(userStatus));
283             if (ret != ERR_OK) {
284                 TAG_LOGE(AAFwkTag::ABILITYMGR, "failed %{public}d", ret);
285                 task.Reject(env, CreateJsError(env, GetJsErrorCodeByNativeError(ret)));
286                 return;
287             }
288             task.ResolveWithNoError(env, CreateJsUndefined(env));
289         };
290 
291         napi_value result = nullptr;
292         NapiAsyncTask::Schedule("JsAbilityManager::OnNotifyDebugAssertResult", env,
293             CreateAsyncTaskWithLastParam(env, nullptr, nullptr, std::move(complete), &result));
294         return result;
295     }
296 
OnOffAbilityForeground(napi_env env,size_t argc,napi_value * argv)297     napi_value OnOffAbilityForeground(napi_env env, size_t argc, napi_value *argv)
298     {
299         if (observerForeground_ == nullptr) {
300             TAG_LOGE(AAFwkTag::ABILITYMGR, "null observer");
301             ThrowError(env, AbilityErrorCode::ERROR_CODE_INNER);
302             return CreateJsUndefined(env);
303         }
304         if (argc == ARGC_TWO) {
305             observerForeground_->RemoveJsObserverObject(argv[INDEX_ONE]);
306         } else {
307             observerForeground_->RemoveAllJsObserverObject();
308         }
309 
310         if (observerForeground_->IsEmpty()) {
311             int32_t ret = GetAppManagerInstance()->UnregisterAbilityForegroundStateObserver(observerForeground_);
312             if (ret != NO_ERROR) {
313                 TAG_LOGE(AAFwkTag::ABILITYMGR, "error: %{public}d", ret);
314                 ThrowErrorByNativeErr(env, ret);
315                 return CreateJsUndefined(env);
316             }
317         }
318         return CreateJsUndefined(env);
319     }
320 
OnGetAbilityRunningInfos(napi_env env,NapiCallbackInfo & info)321     napi_value OnGetAbilityRunningInfos(napi_env env, NapiCallbackInfo& info)
322     {
323         TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
324         NapiAsyncTask::CompleteCallback complete =
325             [](napi_env env, NapiAsyncTask &task, int32_t status) {
326                 std::vector<AAFwk::AbilityRunningInfo> infos;
327                 auto errcode = AbilityManagerClient::GetInstance()->GetAbilityRunningInfos(infos);
328                 if (errcode == 0) {
329 #ifdef ENABLE_ERRCODE
330                     task.ResolveWithNoError(env, CreateJsAbilityRunningInfoArray(env, infos));
331                 } else {
332                     task.Reject(env, CreateJsError(env, GetJsErrorCodeByNativeError(errcode)));
333 #else
334                     task.Resolve(env, CreateJsAbilityRunningInfoArray(env, infos));
335                 } else {
336                     task.Reject(env, CreateJsError(env, errcode, "Get mission infos failed."));
337 #endif
338                 }
339             };
340 
341         napi_value lastParam = (info.argc == 0) ? nullptr : info.argv[0];
342         napi_value result = nullptr;
343         NapiAsyncTask::ScheduleHighQos("JsAbilityManager::OnGetAbilityRunningInfos",
344             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
345         return result;
346     }
347 
OnGetExtensionRunningInfos(napi_env env,NapiCallbackInfo & info)348     napi_value OnGetExtensionRunningInfos(napi_env env, NapiCallbackInfo& info)
349     {
350         TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
351         if (info.argc == 0) {
352             TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid argc");
353 #ifdef ENABLE_ERRCODE
354             ThrowTooFewParametersError(env);
355 #endif
356             return CreateJsUndefined(env);
357         }
358         int upperLimit = -1;
359         if (!ConvertFromJsValue(env, info.argv[0], upperLimit)) {
360 #ifdef ENABLE_ERRCODE
361             ThrowInvalidParamError(env, "Parse param upperLimit failed, must be a number.");
362 #endif
363             return CreateJsUndefined(env);
364         }
365 
366         NapiAsyncTask::CompleteCallback complete =
367             [upperLimit](napi_env env, NapiAsyncTask &task, int32_t status) {
368                 std::vector<AAFwk::ExtensionRunningInfo> infos;
369                 auto errcode = AbilityManagerClient::GetInstance()->GetExtensionRunningInfos(upperLimit, infos);
370                 if (errcode == 0) {
371 #ifdef ENABLE_ERRCODE
372                     task.ResolveWithNoError(env, CreateJsExtensionRunningInfoArray(env, infos));
373                 } else {
374                     task.Reject(env, CreateJsError(env, GetJsErrorCodeByNativeError(errcode)));
375 #else
376                     task.Resolve(env, CreateJsExtensionRunningInfoArray(env, infos));
377                 } else {
378                     task.Reject(env, CreateJsError(env, errcode, "Get mission infos failed."));
379 #endif
380                 }
381             };
382 
383         napi_value lastParam = (info.argc == 1) ? nullptr : info.argv[1];
384         napi_value result = nullptr;
385         NapiAsyncTask::ScheduleHighQos("JsAbilityManager::OnGetExtensionRunningInfos",
386             env, CreateAsyncTaskWithLastParam(env,
387             lastParam, nullptr, std::move(complete), &result));
388         return result;
389     }
390 
OnUpdateConfiguration(napi_env env,NapiCallbackInfo & info)391     napi_value OnUpdateConfiguration(napi_env env, NapiCallbackInfo& info)
392     {
393         TAG_LOGI(AAFwkTag::ABILITYMGR, "called");
394         NapiAsyncTask::CompleteCallback complete;
395 
396         do {
397             if (info.argc == 0) {
398                 TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid argc");
399 #ifdef ENABLE_ERRCODE
400                 ThrowTooFewParametersError(env);
401 #else
402                 complete = [](napi_env env, NapiAsyncTask& task, int32_t status) {
403                     task.Reject(env, CreateJsError(env, ERR_INVALID_VALUE, "no enough params."));
404                 };
405 #endif
406                 break;
407             }
408 
409             AppExecFwk::Configuration changeConfig;
410             if (!UnwrapConfiguration(env, info.argv[0], changeConfig)) {
411 #ifdef ENABLE_ERRCODE
412                 ThrowInvalidParamError(env, "Parse param config failed, must be a Configuration.");
413 #else
414                 complete = [](napi_env env, NapiAsyncTask& task, int32_t status) {
415                     task.Reject(env, CreateJsError(env, ERR_INVALID_VALUE, "config is invalid."));
416                 };
417 #endif
418                 break;
419             }
420 
421             complete = [changeConfig](napi_env env, NapiAsyncTask& task, int32_t status) {
422                 auto errcode = GetAppManagerInstance()->UpdateConfiguration(changeConfig);
423                 if (errcode == 0) {
424 #ifdef ENABLE_ERRCODE
425                     task.ResolveWithNoError(env, CreateJsUndefined(env));
426                 } else {
427                     task.Reject(env, CreateJsError(env, GetJsErrorCodeByNativeError(errcode)));
428 #else
429                     task.Resolve(env, CreateJsUndefined(env));
430                 } else {
431                     task.Reject(env, CreateJsError(env, errcode, "update config failed."));
432 #endif
433                 }
434             };
435         } while (0);
436 
437         napi_value lastParam = (info.argc == 1) ? nullptr : info.argv[1];
438         napi_value result = nullptr;
439         NapiAsyncTask::ScheduleHighQos("JsAbilityManager::OnGetExtensionRunningInfos",
440             env, CreateAsyncTaskWithLastParam(env,
441             lastParam, nullptr, std::move(complete), &result));
442         return result;
443     }
444 
OnGetTopAbility(napi_env env,NapiCallbackInfo & info)445     napi_value OnGetTopAbility(napi_env env, NapiCallbackInfo& info)
446     {
447         TAG_LOGI(AAFwkTag::ABILITYMGR, "called");
448 #ifdef ENABLE_ERRCODE
449         auto selfToken = IPCSkeleton::GetSelfTokenID();
450         if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken)) {
451             TAG_LOGE(AAFwkTag::ABILITYMGR, "not system app");
452             ThrowError(env, AbilityErrorCode::ERROR_CODE_NOT_SYSTEM_APP);
453             return CreateJsUndefined(env);
454         }
455 #endif
456         NapiAsyncTask::CompleteCallback complete =
457             [](napi_env env, NapiAsyncTask &task, int32_t status) {
458                 AppExecFwk::ElementName elementName = AbilityManagerClient::GetInstance()->GetTopAbility();
459 #ifdef ENABLE_ERRCOE
460                 task.ResolveWithNoError(env, CreateJsElementName(env, elementName));
461 #else
462                 task.Resolve(env, CreateJsElementName(env, elementName));
463 #endif
464             };
465 
466         napi_value lastParam = (info.argc == 0) ? nullptr : info.argv[0];
467         napi_value result = nullptr;
468         NapiAsyncTask::ScheduleHighQos("JsAbilityManager::OnGetTopAbility",
469             env, CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
470         return result;
471     }
472 
OnAcquireShareData(napi_env env,NapiCallbackInfo & info)473     napi_value OnAcquireShareData(napi_env env, NapiCallbackInfo& info)
474     {
475         TAG_LOGI(AAFwkTag::ABILITYMGR, "called");
476         if (info.argc < ARGC_ONE) {
477             ThrowTooFewParametersError(env);
478             return CreateJsUndefined(env);
479         }
480         int32_t missionId = -1;
481         if (!ConvertFromJsValue(env, info.argv[INDEX_ZERO], missionId)) {
482             ThrowInvalidParamError(env, "Parse param missionId failed, must be a number.");
483             return CreateJsUndefined(env);
484         }
485         napi_value lastParam = info.argc > ARGC_ONE  ? info.argv[INDEX_ONE] : nullptr;
486         napi_value result = nullptr;
487         std::unique_ptr<NapiAsyncTask> uasyncTask = CreateAsyncTaskWithLastParam(
488             env, lastParam, nullptr, nullptr, &result);
489         std::shared_ptr<NapiAsyncTask> asyncTask = std::move(uasyncTask);
490 
491         AAFwk::ShareRuntimeTask task = [env, asyncTask](int32_t resultCode, const AAFwk::WantParams &wantParam) {
492             if (resultCode != 0) {
493                 asyncTask->Reject(env, CreateJsError(env, GetJsErrorCodeByNativeError(resultCode)));
494                 return;
495             }
496             napi_value abilityResult = AppExecFwk::WrapWantParams(env, wantParam);
497             if (abilityResult == nullptr) {
498                 asyncTask->Reject(env, CreateJsError(env, AbilityErrorCode::ERROR_CODE_INNER));
499             } else {
500                 asyncTask->ResolveWithNoError(env, abilityResult);
501             }
502         };
503         sptr<AAFwk::AcquireShareDataCallbackStub> shareDataCallbackStub = new AAFwk::AcquireShareDataCallbackStub();
504         mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
505         shareDataCallbackStub->SetHandler(mainHandler_);
506         shareDataCallbackStub->SetShareRuntimeTask(task);
507         auto err = AbilityManagerClient::GetInstance()->AcquireShareData(missionId, shareDataCallbackStub);
508         if (err != 0) {
509             asyncTask->Reject(env, CreateJsError(env, GetJsErrorCodeByNativeError(err)));
510         }
511         return result;
512     }
513 
OnNotifySaveAsResult(napi_env env,NapiCallbackInfo & info)514     napi_value OnNotifySaveAsResult(napi_env env, NapiCallbackInfo& info)
515     {
516         TAG_LOGI(AAFwkTag::ABILITYMGR, "called");
517         NapiAsyncTask::CompleteCallback complete;
518         NapiAsyncTask::ExecuteCallback execute;
519 
520         do {
521             if (info.argc < ARGC_TWO) {
522                 TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid argc");
523                 ThrowTooFewParametersError(env);
524                 break;
525             }
526 
527             int reqCode = 0;
528             if (!ConvertFromJsValue(env, info.argv[1], reqCode)) {
529                 TAG_LOGE(AAFwkTag::ABILITYMGR, "get requestCode failed");
530                 ThrowInvalidParamError(env, "Parse param requestCode failed, must be a number.");
531                 break;
532             }
533 
534             AppExecFwk::Want want;
535             int resultCode = ERR_OK;
536             if (!AppExecFwk::UnWrapAbilityResult(env, info.argv[0], resultCode, want)) {
537                 TAG_LOGE(AAFwkTag::ABILITYMGR, "unwrap abilityResult failed");
538                 ThrowInvalidParamError(env, "Parse param parameter failed, must be a AbilityResult.");
539                 break;
540             }
541 
542             auto sharedCode = std::make_shared<ErrCode>(ERR_OK);
543             execute = [sharedCode, want, resultCode, reqCode]() {
544                 *sharedCode = AbilityManagerClient::GetInstance()->NotifySaveAsResult(want, resultCode, reqCode);
545             };
546             complete = [sharedCode](napi_env env, NapiAsyncTask& task, int32_t status) {
547                 auto errCode = *sharedCode;
548                 if (errCode == ERR_OK) {
549                     task.ResolveWithNoError(env, CreateJsUndefined(env));
550                 } else {
551                     task.Reject(env, CreateJsError(env, GetJsErrorCodeByNativeError(errCode)));
552                 }
553             };
554         } while (0);
555 
556         napi_value lastParam = (info.argc == ARGC_TWO) ? nullptr : info.argv[ARGC_TWO];
557         napi_value result = nullptr;
558         NapiAsyncTask::ScheduleHighQos("JsAbilityManager::OnNotifySaveAsResult", env,
559             CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
560         return result;
561     }
562 
OnGetForegroundUIAbilities(napi_env env,size_t argc,napi_value * argv)563     napi_value OnGetForegroundUIAbilities(napi_env env, size_t argc, napi_value *argv)
564     {
565         TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
566         NapiAsyncTask::CompleteCallback complete = [](napi_env env, NapiAsyncTask &task, int32_t status) {
567             std::vector<AppExecFwk::AbilityStateData> list;
568             int32_t ret = AbilityManagerClient::GetInstance()->GetForegroundUIAbilities(list);
569             if (ret == ERR_OK) {
570                 task.ResolveWithNoError(env, CreateJsAbilityStateDataArray(env, list));
571             } else {
572                 TAG_LOGE(AAFwkTag::ABILITYMGR, "error: %{public}d", ret);
573                 task.Reject(env, CreateJsError(env, GetJsErrorCodeByNativeError(ret)));
574             }
575         };
576 
577         napi_value lastParam = (argc > ARGC_ZERO) ? argv[INDEX_ZERO] : nullptr;
578         napi_value result = nullptr;
579         NapiAsyncTask::Schedule("JsAbilityManager::OnGetForegroundUIAbilities", env,
580             CreateAsyncTaskWithLastParam(env, lastParam, nullptr, std::move(complete), &result));
581         return result;
582     }
583 
OnSetResidentProcessEnabled(napi_env env,size_t argc,napi_value * argv)584     napi_value OnSetResidentProcessEnabled(napi_env env, size_t argc, napi_value *argv)
585     {
586         TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
587         if (argc < ARGC_TWO) {
588             TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid argc");
589             ThrowTooFewParametersError(env);
590             return CreateJsUndefined(env);
591         }
592 
593         std::string bundleName;
594         if (!ConvertFromJsValue(env, argv[INDEX_ZERO], bundleName) || bundleName.empty()) {
595             TAG_LOGE(AAFwkTag::ABILITYMGR, "parse bundleName failed, not string");
596             ThrowInvalidParamError(env, "Parse param bundleName failed, must be a string.");
597             return CreateJsUndefined(env);
598         }
599 
600         bool enableState = false;
601         if (!ConvertFromJsValue(env, argv[INDEX_ONE], enableState)) {
602             TAG_LOGE(AAFwkTag::ABILITYMGR, "parse enable failed, not boolean");
603             ThrowInvalidParamError(env, "Parse param enable failed, must be a boolean.");
604             return CreateJsUndefined(env);
605         }
606 
607         auto innerErrorCode = std::make_shared<int32_t>(ERR_OK);
608         NapiAsyncTask::ExecuteCallback execute = [bundleName, enableState, innerErrorCode, env]() {
609             auto amsClient = AbilityManagerClient::GetInstance();
610             if (amsClient == nullptr) {
611                 TAG_LOGE(AAFwkTag::ABILITYMGR, "null amsClient");
612                 *innerErrorCode = static_cast<int32_t>(AAFwk::INNER_ERR);
613                 return;
614             }
615             *innerErrorCode = amsClient->SetResidentProcessEnabled(bundleName, enableState);
616         };
617 
618         NapiAsyncTask::CompleteCallback complete = [innerErrorCode](napi_env env, NapiAsyncTask &task, int32_t status) {
619             if (*innerErrorCode != ERR_OK) {
620                 TAG_LOGE(AAFwkTag::ABILITYMGR, "error: %{public}d",
621                     *innerErrorCode);
622                 task.Reject(env, CreateJsErrorByNativeErr(env, *innerErrorCode));
623                 return;
624             }
625             task.ResolveWithNoError(env, CreateJsUndefined(env));
626         };
627 
628         napi_value result = nullptr;
629         NapiAsyncTask::Schedule("JsAbilityManager::OnSetResidentProcessEnabled", env,
630             CreateAsyncTaskWithLastParam(env, nullptr, std::move(execute), std::move(complete), &result));
631         return result;
632     }
633 
OnIsEmbeddedOpenAllowed(napi_env env,NapiCallbackInfo & info)634     napi_value OnIsEmbeddedOpenAllowed(napi_env env, NapiCallbackInfo& info)
635     {
636         TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
637         if (info.argc < ARGC_TWO) {
638             TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid argc");
639             ThrowTooFewParametersError(env);
640             return CreateJsUndefined(env);
641         }
642 
643         bool stageMode = false;
644         napi_status status = OHOS::AbilityRuntime::IsStageContext(env, info.argv[0], stageMode);
645         if (status != napi_ok || !stageMode) {
646             TAG_LOGE(AAFwkTag::ABILITYMGR, "not stageMode");
647             ThrowInvalidParamError(env, "Parse param context failed, must be a context of stageMode.");
648             return CreateJsUndefined(env);
649         }
650         auto context = OHOS::AbilityRuntime::GetStageModeContext(env, info.argv[0]);
651         if (context == nullptr) {
652             TAG_LOGE(AAFwkTag::ABILITYMGR, "null context");
653             ThrowInvalidParamError(env, "Parse param context failed, must not be nullptr.");
654             return CreateJsUndefined(env);
655         }
656         auto uiAbilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context);
657         if (uiAbilityContext == nullptr) {
658             TAG_LOGE(AAFwkTag::ABILITYMGR, "null UIAbilityContext");
659             ThrowInvalidParamError(env, "Parse param context failed, must be UIAbilityContext.");
660             return CreateJsUndefined(env);
661         }
662 
663         std::string appId;
664         if (!ConvertFromJsValue(env, info.argv[1], appId)) {
665             TAG_LOGE(AAFwkTag::ABILITYMGR, "parse appId failed");
666             ThrowInvalidParamError(env, "Parse param appId failed, must be a string.");
667             return CreateJsUndefined(env);
668         }
669 
670         auto token = uiAbilityContext->GetToken();
671         auto sharedResult = std::make_shared<bool>(false);
672         NapiAsyncTask::ExecuteCallback execute = [sharedResult, token, appId]() {
673             *sharedResult = AbilityManagerClient::GetInstance()->IsEmbeddedOpenAllowed(token, appId);
674         };
675 
676         NapiAsyncTask::CompleteCallback complete = [sharedResult](napi_env env, NapiAsyncTask &task, int32_t status) {
677             task.Resolve(env, CreateJsValue(env, *sharedResult));
678         };
679 
680         napi_value lastParam = (info.argc > ARGC_TWO) ? info. argv[ARGC_TWO] : nullptr;
681         napi_value result = nullptr;
682         NapiAsyncTask::Schedule("JsAbilityManager::OnIsEmbeddedOpenAllowed", env,
683             CreateAsyncTaskWithLastParam(env, lastParam, std::move(execute), std::move(complete), &result));
684         return result;
685     }
686 
AddQueryERMSObserver(napi_env env,sptr<IRemoteObject> token,const std::string & appId,const std::string & startTime,napi_value * result)687     int AddQueryERMSObserver(napi_env env, sptr<IRemoteObject> token, const std::string &appId,
688         const std::string &startTime, napi_value *result)
689     {
690         TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
691         int ret = 0;
692         if (queryERMSObserver_ == nullptr) {
693             queryERMSObserver_ = new JsQueryERMSObserver(env);
694         }
695         queryERMSObserver_->AddJsObserverObject(appId, startTime, result);
696 
697         ret = AbilityManagerClient::GetInstance()->AddQueryERMSObserver(token, queryERMSObserver_);
698         if (ret != ERR_OK) {
699             TAG_LOGE(AAFwkTag::ABILITYMGR, "addQueryERMSObserver error");
700             AtomicServiceStartupRule rule;
701             queryERMSObserver_->OnQueryFinished(appId, startTime, rule, AAFwk::INNER_ERR);
702             return ret;
703         }
704         return ERR_OK;
705     }
706 
OnQueryAtomicServiceStartupRuleInner(napi_env env,sptr<IRemoteObject> token,const std::string & appId)707     napi_value OnQueryAtomicServiceStartupRuleInner(napi_env env, sptr<IRemoteObject> token,
708         const std::string &appId)
709     {
710         auto innerErrorCode = std::make_shared<int32_t>(ERR_OK);
711         auto rule = std::make_shared<AtomicServiceStartupRule>();
712         std::string startTime = std::to_string(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::
713             system_clock::now().time_since_epoch()).count());
714         napi_value result = nullptr;
715         auto ret = AddQueryERMSObserver(env, token, appId, startTime, &result);
716         if (ret != ERR_OK) {
717             TAG_LOGE(AAFwkTag::ABILITYMGR, "AddQueryERMSObserver failed, ret=%{public}d", ret);
718             return CreateJsUndefined(env);
719         }
720 
721         NapiAsyncTask::ExecuteCallback execute = [innerErrorCode, rule, token, appId, startTime]() {
722             *innerErrorCode = AbilityManagerClient::GetInstance()->QueryAtomicServiceStartupRule(
723                 token, appId, startTime, *rule);
724         };
725 
726         NapiAsyncTask::CompleteCallback complete = [appId, startTime, innerErrorCode, rule,
727             observer = queryERMSObserver_](
728             napi_env env, NapiAsyncTask &task, int32_t status) {
729             if (observer == nullptr) {
730                 TAG_LOGW(AAFwkTag::ABILITYMGR, "null observer");
731                 return;
732             }
733             if (*innerErrorCode == AAFwk::ERR_ECOLOGICAL_CONTROL_STATUS) {
734                 TAG_LOGI(AAFwkTag::ABILITYMGR, "openning dialog to confirm");
735                 return;
736             }
737             if (*innerErrorCode != ERR_OK) {
738                 TAG_LOGE(AAFwkTag::ABILITYMGR, "query failed: %{public}d", *innerErrorCode);
739                 observer->OnQueryFinished(appId, startTime, *rule, *innerErrorCode);
740                 return;
741             }
742             observer->OnQueryFinished(appId, startTime, *rule, ERR_OK);
743         };
744 
745         NapiAsyncTask::Schedule("JsAbilityManager::OnQueryAtomicServiceStartupRule", env,
746             CreateAsyncTaskWithLastParam(env, nullptr, std::move(execute), std::move(complete), nullptr));
747         return result;
748     }
749 
OnQueryAtomicServiceStartupRule(napi_env env,NapiCallbackInfo & info)750     napi_value OnQueryAtomicServiceStartupRule(napi_env env, NapiCallbackInfo& info)
751     {
752         TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
753         if (info.argc < ARGC_TWO) {
754             TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid argc");
755             ThrowTooFewParametersError(env);
756             return CreateJsUndefined(env);
757         }
758 
759         bool stageMode = false;
760         napi_status status = OHOS::AbilityRuntime::IsStageContext(env, info.argv[0], stageMode);
761         if (status != napi_ok || !stageMode) {
762             TAG_LOGE(AAFwkTag::ABILITYMGR, "not stageMode");
763             ThrowInvalidParamError(env, "Parse param context failed, must be a context of stageMode.");
764             return CreateJsUndefined(env);
765         }
766         auto context = OHOS::AbilityRuntime::GetStageModeContext(env, info.argv[0]);
767         if (context == nullptr) {
768             TAG_LOGE(AAFwkTag::ABILITYMGR, "null context");
769             ThrowInvalidParamError(env, "Parse param context failed, must not be nullptr.");
770             return CreateJsUndefined(env);
771         }
772         auto uiAbilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context);
773         if (uiAbilityContext == nullptr) {
774             TAG_LOGE(AAFwkTag::ABILITYMGR, "null UIAbilityContext");
775             ThrowInvalidParamError(env, "Parse param context failed, must be UIAbilityContext.");
776             return CreateJsUndefined(env);
777         }
778 
779         std::string appId;
780         if (!ConvertFromJsValue(env, info.argv[1], appId)) {
781             TAG_LOGE(AAFwkTag::ABILITYMGR, "parse appId failed");
782             ThrowInvalidParamError(env, "Parse param appId failed, must be a string.");
783             return CreateJsUndefined(env);
784         }
785 
786         auto token = uiAbilityContext->GetToken();
787         return OnQueryAtomicServiceStartupRuleInner(env, token, appId);
788     }
789 
OnRestartSelfAtomicServiceInner(napi_env env,sptr<IRemoteObject> token)790     napi_value OnRestartSelfAtomicServiceInner(napi_env env, sptr<IRemoteObject> token)
791     {
792         auto ret = AbilityManagerClient::GetInstance()->RestartSelfAtomicService(token);
793         if (ret != ERR_OK) {
794             TAG_LOGE(AAFwkTag::ABILITYMGR, "resatrt atomic service failed: %{public}d", ret);
795             ThrowErrorByNativeErr(env, ret);
796         }
797         return CreateJsUndefined(env);
798     }
799 
OnRestartSelfAtomicService(napi_env env,NapiCallbackInfo & info)800     napi_value OnRestartSelfAtomicService(napi_env env, NapiCallbackInfo& info)
801     {
802         TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
803         if (info.argc < ARGC_ONE) {
804             TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid argc");
805             ThrowTooFewParametersError(env);
806             return CreateJsUndefined(env);
807         }
808 
809         bool stageMode = false;
810         napi_status status = OHOS::AbilityRuntime::IsStageContext(env, info.argv[0], stageMode);
811         if (status != napi_ok || !stageMode) {
812             TAG_LOGE(AAFwkTag::ABILITYMGR, "not stageMode");
813             ThrowInvalidParamError(env, "Parse param context failed, must be a context of stageMode.");
814             return CreateJsUndefined(env);
815         }
816         auto context = OHOS::AbilityRuntime::GetStageModeContext(env, info.argv[0]);
817         if (context == nullptr) {
818             TAG_LOGE(AAFwkTag::ABILITYMGR, "null context");
819             ThrowInvalidParamError(env, "Parse param context failed, must not be nullptr.");
820             return CreateJsUndefined(env);
821         }
822         auto uiAbilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context);
823         if (uiAbilityContext == nullptr) {
824             TAG_LOGE(AAFwkTag::ABILITYMGR, "null UIAbilityContext");
825             ThrowError(env, AbilityErrorCode::ERROR_CODE_NOT_UI_ABILITY_CONTEXT);
826             return CreateJsUndefined(env);
827         }
828 
829         auto token = uiAbilityContext->GetToken();
830         return OnRestartSelfAtomicServiceInner(env, token);
831     }
832 };
833 } // namespace
834 
JsAbilityManagerInit(napi_env env,napi_value exportObj)835 napi_value JsAbilityManagerInit(napi_env env, napi_value exportObj)
836 {
837     TAG_LOGD(AAFwkTag::ABILITYMGR, "called");
838 
839     std::unique_ptr<JsAbilityManager> jsAbilityManager = std::make_unique<JsAbilityManager>();
840     napi_wrap(env, exportObj, jsAbilityManager.release(), JsAbilityManager::Finalizer, nullptr, nullptr);
841 
842     napi_set_named_property(env, exportObj, "AbilityState", AbilityStateInit(env));
843     napi_set_named_property(env, exportObj, "UserStatus", UserStatusInit(env));
844 
845     const char *moduleName = "JsAbilityManager";
846     BindNativeFunction(env, exportObj, "getAbilityRunningInfos", moduleName,
847         JsAbilityManager::GetAbilityRunningInfos);
848     BindNativeFunction(env, exportObj, "getExtensionRunningInfos", moduleName,
849         JsAbilityManager::GetExtensionRunningInfos);
850     BindNativeFunction(env, exportObj, "updateConfiguration", moduleName, JsAbilityManager::UpdateConfiguration);
851     BindNativeFunction(env, exportObj, "getTopAbility", moduleName, JsAbilityManager::GetTopAbility);
852     BindNativeFunction(env, exportObj, "acquireShareData", moduleName, JsAbilityManager::AcquireShareData);
853     BindNativeFunction(env, exportObj, "notifySaveAsResult", moduleName, JsAbilityManager::NotifySaveAsResult);
854     BindNativeFunction(
855         env, exportObj, "getForegroundUIAbilities", moduleName, JsAbilityManager::GetForegroundUIAbilities);
856     BindNativeFunction(env, exportObj, "on", moduleName, JsAbilityManager::On);
857     BindNativeFunction(env, exportObj, "off", moduleName, JsAbilityManager::Off);
858     BindNativeFunction(env, exportObj, "isEmbeddedOpenAllowed", moduleName, JsAbilityManager::IsEmbeddedOpenAllowed);
859     BindNativeFunction(
860         env, exportObj, "restartSelfAtomicService", moduleName, JsAbilityManager::RestartSelfAtomicService);
861     BindNativeFunction(
862         env, exportObj, "notifyDebugAssertResult", moduleName, JsAbilityManager::NotifyDebugAssertResult);
863     BindNativeFunction(
864         env, exportObj, "setResidentProcessEnabled", moduleName, JsAbilityManager::SetResidentProcessEnabled);
865     BindNativeFunction(env, exportObj, "queryAtomicServiceStartupRule",
866         moduleName, JsAbilityManager::QueryAtomicServiceStartupRule);
867     TAG_LOGD(AAFwkTag::ABILITYMGR, "end");
868     return CreateJsUndefined(env);
869 }
870 }  // namespace AbilityRuntime
871 }  // namespace OHOS
872