• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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