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