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