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