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