1 /*
2 * Copyright (c) 2022 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
21 #include "ability_business_error.h"
22 #include "ability_manager_client.h"
23 #include "acquire_share_data_callback_stub.h"
24 #include "app_mgr_interface.h"
25 #include "errors.h"
26 #include "hilog_wrapper.h"
27 #include "js_error_utils.h"
28 #include "js_runtime.h"
29 #include "js_runtime_utils.h"
30 #include "napi/native_api.h"
31 #include "if_system_ability_manager.h"
32 #include "ipc_skeleton.h"
33 #include "iservice_registry.h"
34 #include "system_ability_definition.h"
35 #include "js_ability_manager_utils.h"
36 #include "event_runner.h"
37 #include "napi_common_configuration.h"
38 #include "napi_common_util.h"
39 #include "napi_common_want.h"
40 #include "tokenid_kit.h"
41 #include "js_api_utils.h"
42
43 namespace OHOS {
44 namespace AbilityRuntime {
45 using AbilityManagerClient = AAFwk::AbilityManagerClient;
46 namespace {
GetAppManagerInstance()47 OHOS::sptr<OHOS::AppExecFwk::IAppMgr> GetAppManagerInstance()
48 {
49 OHOS::sptr<OHOS::ISystemAbilityManager> systemAbilityManager =
50 OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
51 OHOS::sptr<OHOS::IRemoteObject> appObject = systemAbilityManager->GetSystemAbility(OHOS::APP_MGR_SERVICE_ID);
52 return OHOS::iface_cast<OHOS::AppExecFwk::IAppMgr>(appObject);
53 }
54
55
56 constexpr size_t ARGC_ONE = 1;
57 constexpr size_t ARGC_TWO = 2;
58 constexpr size_t INDEX_ZERO = 0;
59 constexpr size_t INDEX_ONE = 1;
60 static std::shared_ptr<AppExecFwk::EventHandler> mainHandler_ = nullptr;
61
62 class JsAbilityManager final {
63 public:
64 JsAbilityManager() = default;
65 ~JsAbilityManager() = default;
66
Finalizer(NativeEngine * engine,void * data,void * hint)67 static void Finalizer(NativeEngine* engine, void* data, void* hint)
68 {
69 HILOG_INFO("JsAbilityManager::Finalizer is called");
70 std::unique_ptr<JsAbilityManager>(static_cast<JsAbilityManager*>(data));
71 }
72
GetAbilityRunningInfos(NativeEngine * engine,NativeCallbackInfo * info)73 static NativeValue* GetAbilityRunningInfos(NativeEngine* engine, NativeCallbackInfo* info)
74 {
75 JsAbilityManager* me = CheckParamsAndGetThis<JsAbilityManager>(engine, info);
76 return (me != nullptr) ? me->OnGetAbilityRunningInfos(*engine, *info) : nullptr;
77 }
78
GetExtensionRunningInfos(NativeEngine * engine,NativeCallbackInfo * info)79 static NativeValue* GetExtensionRunningInfos(NativeEngine* engine, NativeCallbackInfo* info)
80 {
81 JsAbilityManager* me = CheckParamsAndGetThis<JsAbilityManager>(engine, info);
82 return (me != nullptr) ? me->OnGetExtensionRunningInfos(*engine, *info) : nullptr;
83 }
84
UpdateConfiguration(NativeEngine * engine,NativeCallbackInfo * info)85 static NativeValue* UpdateConfiguration(NativeEngine* engine, NativeCallbackInfo* info)
86 {
87 JsAbilityManager* me = CheckParamsAndGetThis<JsAbilityManager>(engine, info);
88 return (me != nullptr) ? me->OnUpdateConfiguration(*engine, *info) : nullptr;
89 }
90
GetTopAbility(NativeEngine * engine,NativeCallbackInfo * info)91 static NativeValue* GetTopAbility(NativeEngine* engine, NativeCallbackInfo* info)
92 {
93 JsAbilityManager* me = CheckParamsAndGetThis<JsAbilityManager>(engine, info);
94 return (me != nullptr) ? me->OnGetTopAbility(*engine, *info) : nullptr;
95 }
96
AcquireShareData(NativeEngine * engine,NativeCallbackInfo * info)97 static NativeValue* AcquireShareData(NativeEngine* engine, NativeCallbackInfo* info)
98 {
99 JsAbilityManager* me = CheckParamsAndGetThis<JsAbilityManager>(engine, info);
100 return (me != nullptr) ? me->OnAcquireShareData(*engine, *info) : nullptr;
101 }
102
NotifySaveAsResult(NativeEngine * engine,NativeCallbackInfo * info)103 static NativeValue* NotifySaveAsResult(NativeEngine* engine, NativeCallbackInfo* info)
104 {
105 JsAbilityManager* me = CheckParamsAndGetThis<JsAbilityManager>(engine, info);
106 return (me != nullptr) ? me->OnNotifySaveAsResult(*engine, *info) : nullptr;
107 }
108
109 private:
OnGetAbilityRunningInfos(NativeEngine & engine,const NativeCallbackInfo & info)110 NativeValue* OnGetAbilityRunningInfos(NativeEngine &engine, const NativeCallbackInfo &info)
111 {
112 HILOG_INFO("%{public}s is called", __FUNCTION__);
113 AsyncTask::CompleteCallback complete =
114 [](NativeEngine &engine, AsyncTask &task, int32_t status) {
115 std::vector<AAFwk::AbilityRunningInfo> infos;
116 auto errcode = AbilityManagerClient::GetInstance()->GetAbilityRunningInfos(infos);
117 if (errcode == 0) {
118 #ifdef ENABLE_ERRCODE
119 task.ResolveWithNoError(engine, CreateJsAbilityRunningInfoArray(engine, infos));
120 } else {
121 task.Reject(engine, CreateJsError(engine, GetJsErrorCodeByNativeError(errcode)));
122 #else
123 task.Resolve(engine, CreateJsAbilityRunningInfoArray(engine, infos));
124 } else {
125 task.Reject(engine, CreateJsError(engine, errcode, "Get mission infos failed."));
126 #endif
127 }
128 };
129
130 NativeValue* lastParam = (info.argc == 0) ? nullptr : info.argv[0];
131 NativeValue* result = nullptr;
132 AsyncTask::ScheduleHighQos("JsAbilityManager::OnGetAbilityRunningInfos",
133 engine, CreateAsyncTaskWithLastParam(engine,
134 lastParam, nullptr, std::move(complete), &result));
135 return result;
136 }
137
OnGetExtensionRunningInfos(NativeEngine & engine,NativeCallbackInfo & info)138 NativeValue* OnGetExtensionRunningInfos(NativeEngine &engine, NativeCallbackInfo &info)
139 {
140 HILOG_INFO("%{public}s is called", __FUNCTION__);
141 if (info.argc == 0) {
142 HILOG_ERROR("Not enough params");
143 #ifdef ENABLE_ERRCODE
144 ThrowTooFewParametersError(engine);
145 #endif
146 return engine.CreateUndefined();
147 }
148 int upperLimit = -1;
149 if (!ConvertFromJsValue(engine, info.argv[0], upperLimit)) {
150 #ifdef ENABLE_ERRCODE
151 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
152 #endif
153 return engine.CreateUndefined();
154 }
155
156 AsyncTask::CompleteCallback complete =
157 [upperLimit](NativeEngine &engine, AsyncTask &task, int32_t status) {
158 std::vector<AAFwk::ExtensionRunningInfo> infos;
159 auto errcode = AbilityManagerClient::GetInstance()->GetExtensionRunningInfos(upperLimit, infos);
160 if (errcode == 0) {
161 #ifdef ENABLE_ERRCODE
162 task.ResolveWithNoError(engine, CreateJsExtensionRunningInfoArray(engine, infos));
163 } else {
164 task.Reject(engine, CreateJsError(engine, GetJsErrorCodeByNativeError(errcode)));
165 #else
166 task.Resolve(engine, CreateJsExtensionRunningInfoArray(engine, infos));
167 } else {
168 task.Reject(engine, CreateJsError(engine, errcode, "Get mission infos failed."));
169 #endif
170 }
171 };
172
173 NativeValue* lastParam = (info.argc == 1) ? nullptr : info.argv[1];
174 NativeValue* result = nullptr;
175 AsyncTask::ScheduleHighQos("JsAbilityManager::OnGetExtensionRunningInfos",
176 engine, CreateAsyncTaskWithLastParam(engine,
177 lastParam, nullptr, std::move(complete), &result));
178 return result;
179 }
180
OnUpdateConfiguration(NativeEngine & engine,NativeCallbackInfo & info)181 NativeValue* OnUpdateConfiguration(NativeEngine &engine, NativeCallbackInfo &info)
182 {
183 HILOG_INFO("%{public}s is called", __FUNCTION__);
184 AsyncTask::CompleteCallback complete;
185
186 do {
187 if (info.argc == 0) {
188 HILOG_ERROR("Not enough params");
189 #ifdef ENABLE_ERRCODE
190 ThrowTooFewParametersError(engine);
191 #else
192 complete = [](NativeEngine& engine, AsyncTask& task, int32_t status) {
193 task.Reject(engine, CreateJsError(engine, ERR_INVALID_VALUE, "no enough params."));
194 };
195 #endif
196 break;
197 }
198
199 AppExecFwk::Configuration changeConfig;
200 if (!UnwrapConfiguration(reinterpret_cast<napi_env>(&engine),
201 reinterpret_cast<napi_value>(info.argv[0]), changeConfig)) {
202 #ifdef ENABLE_ERRCODE
203 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
204 #else
205 complete = [](NativeEngine& engine, AsyncTask& task, int32_t status) {
206 task.Reject(engine, CreateJsError(engine, ERR_INVALID_VALUE, "config is invalid."));
207 };
208 #endif
209 break;
210 }
211
212 complete = [changeConfig](NativeEngine& engine, AsyncTask& task, int32_t status) {
213 auto errcode = GetAppManagerInstance()->UpdateConfiguration(changeConfig);
214 if (errcode == 0) {
215 #ifdef ENABLE_ERRCODE
216 task.ResolveWithNoError(engine, engine.CreateUndefined());
217 } else {
218 task.Reject(engine, CreateJsError(engine, GetJsErrorCodeByNativeError(errcode)));
219 #else
220 task.Resolve(engine, engine.CreateUndefined());
221 } else {
222 task.Reject(engine, CreateJsError(engine, errcode, "update config failed."));
223 #endif
224 }
225 };
226 } while (0);
227
228 NativeValue* lastParam = (info.argc == 1) ? nullptr : info.argv[1];
229 NativeValue* result = nullptr;
230 AsyncTask::ScheduleHighQos("JsAbilityManager::OnGetExtensionRunningInfos",
231 engine, CreateAsyncTaskWithLastParam(engine,
232 lastParam, nullptr, std::move(complete), &result));
233 return result;
234 }
235
OnGetTopAbility(NativeEngine & engine,const NativeCallbackInfo & info)236 NativeValue* OnGetTopAbility(NativeEngine &engine, const NativeCallbackInfo &info)
237 {
238 HILOG_INFO("%{public}s is called", __FUNCTION__);
239 #ifdef ENABLE_ERRCODE
240 auto selfToken = IPCSkeleton::GetSelfTokenID();
241 if (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(selfToken)) {
242 HILOG_ERROR("This application is not system-app, can not use system-api");
243 ThrowError(engine, AbilityErrorCode::ERROR_CODE_NOT_SYSTEM_APP);
244 return engine.CreateUndefined();
245 }
246 #endif
247 AsyncTask::CompleteCallback complete =
248 [](NativeEngine &engine, AsyncTask &task, int32_t status) {
249 AppExecFwk::ElementName elementName = AbilityManagerClient::GetInstance()->GetTopAbility();
250 #ifdef ENABLE_ERRCOE
251 task.ResolveWithNoError(engine, CreateJsElementName(engine, elementName));
252 #else
253 task.Resolve(engine, CreateJsElementName(engine, elementName));
254 #endif
255 };
256
257 NativeValue* lastParam = (info.argc == 0) ? nullptr : info.argv[0];
258 NativeValue* result = nullptr;
259 AsyncTask::ScheduleHighQos("JsAbilityManager::OnGetTopAbility",
260 engine, CreateAsyncTaskWithLastParam(engine,
261 lastParam, nullptr, std::move(complete), &result));
262 return result;
263 }
264
OnAcquireShareData(NativeEngine & engine,NativeCallbackInfo & info)265 NativeValue* OnAcquireShareData(NativeEngine &engine, NativeCallbackInfo &info)
266 {
267 HILOG_INFO("%{public}s is called", __FUNCTION__);
268 if (info.argc < ARGC_ONE) {
269 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
270 return engine.CreateUndefined();
271 }
272 int32_t missionId = -1;
273 if (!ConvertFromJsValue(engine, info.argv[INDEX_ZERO], missionId)) {
274 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
275 return engine.CreateUndefined();
276 }
277 NativeValue* lastParam = info.argc > ARGC_ONE ? info.argv[INDEX_ONE] : nullptr;
278 NativeValue *result = nullptr;
279 std::unique_ptr<AsyncTask> uasyncTask = CreateAsyncTaskWithLastParam(
280 engine, lastParam, nullptr, nullptr, &result);
281 std::shared_ptr<AsyncTask> asyncTask = std::move(uasyncTask);
282
283 AAFwk::ShareRuntimeTask task = [&engine, asyncTask](int32_t resultCode, const AAFwk::WantParams &wantParam) {
284 if (resultCode != 0) {
285 asyncTask->Reject(engine, CreateJsError(engine, GetJsErrorCodeByNativeError(resultCode)));
286 return;
287 }
288 NativeValue* abilityResult = AppExecFwk::CreateJsWantParams(engine, wantParam);
289 if (abilityResult == nullptr) {
290 asyncTask->Reject(engine, CreateJsError(engine, AbilityErrorCode::ERROR_CODE_INNER));
291 } else {
292 asyncTask->ResolveWithNoError(engine, abilityResult);
293 }
294 };
295 sptr<AAFwk::AcquireShareDataCallbackStub> shareDataCallbackStub = new AAFwk::AcquireShareDataCallbackStub();
296 mainHandler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
297 shareDataCallbackStub->SetHandler(mainHandler_);
298 shareDataCallbackStub->SetShareRuntimeTask(task);
299 auto err = AbilityManagerClient::GetInstance()->AcquireShareData(missionId, shareDataCallbackStub);
300 if (err != 0) {
301 asyncTask->Reject(engine, CreateJsError(engine, GetJsErrorCodeByNativeError(err)));
302 }
303 return result;
304 }
305
OnNotifySaveAsResult(NativeEngine & engine,NativeCallbackInfo & info)306 NativeValue* OnNotifySaveAsResult(NativeEngine &engine, NativeCallbackInfo &info)
307 {
308 HILOG_INFO("called");
309 AsyncTask::CompleteCallback complete;
310 AsyncTask::ExecuteCallback execute;
311
312 do {
313 if (info.argc < ARGC_TWO) {
314 HILOG_ERROR("Not enough params");
315 ThrowTooFewParametersError(engine);
316 break;
317 }
318
319 int reqCode = 0;
320 if (!JsApiUtils::UnwrapNumberValue(info.argv[1], reqCode)) {
321 HILOG_ERROR("Get requestCode param error");
322 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
323 break;
324 }
325
326 AppExecFwk::Want want;
327 int resultCode = ERR_OK;
328 if (!JsApiUtils::UnWrapAbilityResult(engine, info.argv[0], resultCode, want)) {
329 HILOG_ERROR("Unrwrap abilityResult param error");
330 ThrowError(engine, AbilityErrorCode::ERROR_CODE_INVALID_PARAM);
331 break;
332 }
333
334 auto sharedCode = std::make_shared<ErrCode>(ERR_OK);
335 execute = [sharedCode, want, resultCode, reqCode]() {
336 *sharedCode = AbilityManagerClient::GetInstance()->NotifySaveAsResult(want, resultCode, reqCode);
337 };
338 complete = [sharedCode](NativeEngine& engine, AsyncTask& task, int32_t status) {
339 auto errCode = *sharedCode;
340 if (errCode == ERR_OK) {
341 task.ResolveWithNoError(engine, engine.CreateUndefined());
342 } else {
343 task.Reject(engine, CreateJsError(engine, GetJsErrorCodeByNativeError(errCode)));
344 }
345 };
346 } while (0);
347
348 NativeValue* lastParam = (info.argc == ARGC_TWO) ? nullptr : info.argv[ARGC_TWO];
349 NativeValue* result = nullptr;
350 AsyncTask::ScheduleHighQos("JsAbilityManager::OnNotifySaveAsResult",
351 engine, CreateAsyncTaskWithLastParam(engine,
352 lastParam, std::move(execute), std::move(complete), &result));
353 return result;
354 }
355 };
356 } // namespace
357
JsAbilityManagerInit(NativeEngine * engine,NativeValue * exportObj)358 NativeValue* JsAbilityManagerInit(NativeEngine* engine, NativeValue* exportObj)
359 {
360 HILOG_INFO("JsAbilityManagerInit is called");
361
362 if (engine == nullptr || exportObj == nullptr) {
363 HILOG_INFO("engine or exportObj null");
364 return nullptr;
365 }
366
367 NativeObject* object = ConvertNativeValueTo<NativeObject>(exportObj);
368 if (object == nullptr) {
369 HILOG_INFO("object null");
370 return nullptr;
371 }
372
373 std::unique_ptr<JsAbilityManager> jsAbilityManager = std::make_unique<JsAbilityManager>();
374 object->SetNativePointer(jsAbilityManager.release(), JsAbilityManager::Finalizer, nullptr);
375
376 object->SetProperty("AbilityState", AbilityStateInit(engine));
377
378 HILOG_INFO("JsAbilityManagerInit BindNativeFunction called");
379 const char *moduleName = "JsAbilityManager";
380 BindNativeFunction(*engine, *object, "getAbilityRunningInfos", moduleName,
381 JsAbilityManager::GetAbilityRunningInfos);
382 BindNativeFunction(*engine, *object, "getExtensionRunningInfos", moduleName,
383 JsAbilityManager::GetExtensionRunningInfos);
384 BindNativeFunction(*engine, *object, "updateConfiguration", moduleName, JsAbilityManager::UpdateConfiguration);
385 BindNativeFunction(*engine, *object, "getTopAbility", moduleName, JsAbilityManager::GetTopAbility);
386 BindNativeFunction(*engine, *object, "acquireShareData", moduleName, JsAbilityManager::AcquireShareData);
387 BindNativeFunction(*engine, *object, "notifySaveAsResult", moduleName, JsAbilityManager::NotifySaveAsResult);
388 HILOG_INFO("JsAbilityManagerInit end");
389 return engine->CreateUndefined();
390 }
391 } // namespace AbilityRuntime
392 } // namespace OHOS
393