• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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_kiosk_manager.h"
17 
18 #include <memory>
19 #include <regex>
20 
21 #include "ability_manager_client.h"
22 #include "errors.h"
23 #include "hilog_tag_wrapper.h"
24 #include "js_error_utils.h"
25 #include "napi/native_api.h"
26 #include "napi_base_context.h"
27 #include "napi_common_configuration.h"
28 #include "napi_common_util.h"
29 #include "napi_common_want.h"
30 #include "kiosk_status.h"
31 
32 namespace OHOS {
33 namespace AbilityRuntime {
34 using AbilityManagerClient = AAFwk::AbilityManagerClient;
35 namespace {
36 constexpr size_t ARGC_ZERO = 0;
37 constexpr size_t ARGC_ONE = 1;
38 constexpr size_t INDEX_ZERO = 0;
39 
40 class JsKioskManager final {
41 public:
42     JsKioskManager() = default;
43     ~JsKioskManager() = default;
44 
45     static napi_value UpdateKioskApplicationList(napi_env env, napi_callback_info info);
46     static napi_value EnterKioskMode(napi_env env, napi_callback_info info);
47     static napi_value ExitKioskMode(napi_env env, napi_callback_info info);
48     static napi_value GetKioskStatus(napi_env env, napi_callback_info info);
Finalizer(napi_env env,void * data,void * hint)49     static void Finalizer(napi_env env, void* data, void* hint)
50     {
51         TAG_LOGI(AAFwkTag::APPKIT, "finalizer called");
52         std::unique_ptr<JsKioskManager>(static_cast<JsKioskManager*>(data));
53     }
54 
55 private:
56     static napi_value CreateJsKioskStatus(napi_env env,
57                                           std::shared_ptr<AAFwk::KioskStatus> kioskStatus);
58     napi_value OnUpdateKioskApplicationList(napi_env env, NapiCallbackInfo &info);
59     napi_value OnEnterKioskMode(napi_env env, NapiCallbackInfo &info);
60     napi_value OnExitKioskMode(napi_env env, NapiCallbackInfo &info);
61     napi_value OnGetKioskStatus(napi_env env, NapiCallbackInfo &info);
62 };
63 } // namespace
64 
CreateJsKioskStatus(napi_env env,std::shared_ptr<AAFwk::KioskStatus> kioskStatus)65 napi_value JsKioskManager::CreateJsKioskStatus(napi_env env,
66                                                std::shared_ptr<AAFwk::KioskStatus> kioskStatus)
67 {
68     napi_value objValue = nullptr;
69     napi_create_object(env, &objValue);
70     if (objValue == nullptr) {
71         TAG_LOGE(AAFwkTag::APPKIT, "null ObjValue");
72         return nullptr;
73     }
74     if (kioskStatus == nullptr) {
75         TAG_LOGE(AAFwkTag::APPKIT, "null kioskStatus");
76         return nullptr;
77     }
78     napi_set_named_property(env, objValue, "isKioskMode",
79                             CreateJsValue(env, kioskStatus->isKioskMode_));
80     napi_set_named_property(env, objValue, "kioskBundleName",
81                             CreateJsValue(env, kioskStatus->kioskBundleName_));
82     napi_set_named_property(env, objValue, "kioskBundleUid", CreateJsValue(env, kioskStatus->kioskBundleUid_));
83     return objValue;
84 }
85 
UpdateKioskApplicationList(napi_env env,napi_callback_info info)86 napi_value JsKioskManager::UpdateKioskApplicationList(napi_env env, napi_callback_info info)
87 {
88     GET_NAPI_INFO_AND_CALL(env, info, JsKioskManager, OnUpdateKioskApplicationList);
89 }
90 
OnUpdateKioskApplicationList(napi_env env,NapiCallbackInfo & info)91 napi_value JsKioskManager::OnUpdateKioskApplicationList(napi_env env, NapiCallbackInfo &info)
92 {
93     TAG_LOGD(AAFwkTag::APPKIT, "On Update Kiosk AppList");
94     if (info.argc < ARGC_ONE) {
95         TAG_LOGE(AAFwkTag::APPKIT, "too few params");
96         ThrowTooFewParametersError(env);
97         return CreateJsUndefined(env);
98     }
99     auto innerErrCode = std::make_shared<ErrCode>(ERR_OK);
100 
101     std::vector<std::string> appList;
102     if (!OHOS::AppExecFwk::UnwrapArrayStringFromJS(env, info.argv[ARGC_ZERO], appList)) {
103         TAG_LOGE(AAFwkTag::APPKIT, "app list is invalid");
104         ThrowInvalidParamError(env, "Failed to parse application list. Application list must be an Array<string>.");
105         return CreateJsUndefined(env);
106     }
107     NapiAsyncTask::ExecuteCallback execute = [innerErrCode, appList]() {
108         auto amsClient = AbilityManagerClient::GetInstance();
109         if (amsClient == nullptr) {
110             TAG_LOGE(AAFwkTag::APPKIT, "null amsClient");
111             *innerErrCode = static_cast<int32_t>(AAFwk::INNER_ERR);
112             return;
113         }
114         *innerErrCode = amsClient->UpdateKioskApplicationList(appList);
115     };
116 
117     auto complete = [innerErrCode](napi_env env, NapiAsyncTask &task, int32_t status) {
118         if (*innerErrCode != ERR_OK) {
119             TAG_LOGE(AAFwkTag::APPKIT, "innerErrCode=%{public}d", *innerErrCode);
120             task.Reject(env, CreateJsErrorByNativeErr(env, *innerErrCode));
121             return;
122         }
123         task.ResolveWithNoError(env, CreateJsUndefined(env));
124     };
125     napi_value result = nullptr;
126     NapiAsyncTask::Schedule("JsKioskManager::OnUpdateKioskApplicationList", env,
127                             CreateAsyncTaskWithLastParam(env, nullptr, std::move(execute),
128                                                          std::move(complete), &result));
129     return result;
130 }
131 
EnterKioskMode(napi_env env,napi_callback_info info)132 napi_value JsKioskManager::EnterKioskMode(napi_env env, napi_callback_info info)
133 {
134     GET_NAPI_INFO_AND_CALL(env, info, JsKioskManager, OnEnterKioskMode);
135 }
136 
OnEnterKioskMode(napi_env env,NapiCallbackInfo & info)137 napi_value JsKioskManager::OnEnterKioskMode(napi_env env, NapiCallbackInfo &info)
138 {
139     TAG_LOGD(AAFwkTag::APPKIT, "On Enter KioskMode  start");
140     if (info.argc < ARGC_ONE) {
141         TAG_LOGE(AAFwkTag::APPKIT, "too few params");
142         ThrowTooFewParametersError(env);
143         return CreateJsUndefined(env);
144     }
145 
146     auto context = OHOS::AbilityRuntime::GetStageModeContext(env, info.argv[INDEX_ZERO]);
147     if (context == nullptr) {
148         TAG_LOGE(AAFwkTag::APPKIT, "null context");
149         ThrowInvalidParamError(env, "Failed to get context. Context must not be nullptr.");
150         return CreateJsUndefined(env);
151     }
152     auto uiAbilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context);
153     if (uiAbilityContext == nullptr) {
154         TAG_LOGE(AAFwkTag::APPKIT, "null UIAbilityContext");
155         ThrowInvalidParamError(env, "Failed to get uiAbilityContext, uiAbilityContext must not be nullptr.");
156         return CreateJsUndefined(env);
157     }
158     auto token = uiAbilityContext->GetToken();
159     auto innerErrCode = std::make_shared<ErrCode>(ERR_OK);
160 
161     NapiAsyncTask::ExecuteCallback execute = [innerErrCode, token]() {
162         auto amsClient = AbilityManagerClient::GetInstance();
163         if (amsClient == nullptr) {
164             TAG_LOGE(AAFwkTag::APPKIT, "null amsClient");
165             *innerErrCode = static_cast<int32_t>(AAFwk::INNER_ERR);
166             return;
167         }
168 
169         *innerErrCode = amsClient->EnterKioskMode(token);
170     };
171 
172     auto complete = [innerErrCode](napi_env env, NapiAsyncTask &task, int32_t status) {
173         if (*innerErrCode != ERR_OK) {
174             TAG_LOGE(AAFwkTag::APPKIT, "innerErrCode=%{public}d", *innerErrCode);
175             task.Reject(env, CreateJsErrorByNativeErr(env, *innerErrCode));
176             return;
177         }
178         task.ResolveWithNoError(env, CreateJsUndefined(env));
179     };
180 
181     napi_value result = nullptr;
182     NapiAsyncTask::Schedule("JsKioskManager::OnEnterKioskMode", env,
183                             CreateAsyncTaskWithLastParam(env, nullptr, std::move(execute),
184                                                          std::move(complete), &result));
185     return result;
186 }
187 
ExitKioskMode(napi_env env,napi_callback_info info)188 napi_value JsKioskManager::ExitKioskMode(napi_env env, napi_callback_info info)
189 {
190     GET_NAPI_INFO_AND_CALL(env, info, JsKioskManager, OnExitKioskMode);
191 }
192 
OnExitKioskMode(napi_env env,NapiCallbackInfo & info)193 napi_value JsKioskManager::OnExitKioskMode(napi_env env, NapiCallbackInfo &info)
194 {
195     TAG_LOGD(AAFwkTag::APPKIT, "On Exit KioskMode");
196     if (info.argc < ARGC_ONE) {
197         TAG_LOGE(AAFwkTag::APPKIT, "too few params");
198         ThrowTooFewParametersError(env);
199         return CreateJsUndefined(env);
200     }
201 
202     auto context = OHOS::AbilityRuntime::GetStageModeContext(env, info.argv[INDEX_ZERO]);
203     if (context == nullptr) {
204         TAG_LOGE(AAFwkTag::APPKIT, "null context");
205         ThrowInvalidParamError(env, "Failed to get context. Context must not be nullptr.");
206         return CreateJsUndefined(env);
207     }
208     auto uiAbilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context);
209     if (uiAbilityContext == nullptr) {
210         TAG_LOGE(AAFwkTag::APPKIT, "null UIAbilityContext");
211         ThrowInvalidParamError(env, "Failed to get uIAbilityContext. Context must be uIAbilityContext.");
212         return CreateJsUndefined(env);
213     }
214     auto token = uiAbilityContext->GetToken();
215     auto innerErrCode = std::make_shared<ErrCode>(ERR_OK);
216 
217     NapiAsyncTask::ExecuteCallback execute = [innerErrCode, token]() {
218         auto amsClient = AbilityManagerClient::GetInstance();
219         if (amsClient == nullptr) {
220             TAG_LOGE(AAFwkTag::APPKIT, "null amsClient");
221             *innerErrCode = static_cast<int32_t>(AAFwk::INNER_ERR);
222             return;
223         }
224         *innerErrCode = amsClient->ExitKioskMode(token);
225     };
226 
227     auto complete = [innerErrCode](napi_env env, NapiAsyncTask &task, int32_t status) {
228         if (*innerErrCode != ERR_OK) {
229             TAG_LOGE(AAFwkTag::APPKIT, "innerErrCode=%{public}d", *innerErrCode);
230             task.Reject(env, CreateJsErrorByNativeErr(env, *innerErrCode));
231             return;
232         }
233         task.ResolveWithNoError(env, CreateJsUndefined(env));
234     };
235     napi_value result = nullptr;
236     NapiAsyncTask::Schedule("JsKioskManager::OnExitKioskMode", env,
237                             CreateAsyncTaskWithLastParam(env, nullptr, std::move(execute),
238                                                          std::move(complete), &result));
239     return result;
240 }
241 
GetKioskStatus(napi_env env,napi_callback_info info)242 napi_value JsKioskManager::GetKioskStatus(napi_env env, napi_callback_info info)
243 {
244     GET_NAPI_INFO_AND_CALL(env, info, JsKioskManager, OnGetKioskStatus);
245 }
246 
OnGetKioskStatus(napi_env env,NapiCallbackInfo & info)247 napi_value JsKioskManager::OnGetKioskStatus(napi_env env, NapiCallbackInfo &info)
248 {
249     TAG_LOGD(AAFwkTag::APPKIT, "Get KioskStatus");
250     auto innerErrCode = std::make_shared<ErrCode>(ERR_OK);
251     std::shared_ptr<AAFwk::KioskStatus> kioskStatus = std::make_shared<AAFwk::KioskStatus>();
252 
253     NapiAsyncTask::ExecuteCallback execute = [innerErrCode, kioskStatus]() {
254         auto amsClient = AbilityManagerClient::GetInstance();
255         if (amsClient == nullptr) {
256             TAG_LOGE(AAFwkTag::APPKIT, "null amsClient");
257             *innerErrCode = static_cast<int32_t>(AAFwk::INNER_ERR);
258             return;
259         }
260         *innerErrCode = amsClient->GetKioskStatus(*kioskStatus);
261     };
262 
263     auto complete = [innerErrCode, kioskStatus](napi_env env, NapiAsyncTask &task, int32_t status) {
264         if (*innerErrCode != ERR_OK) {
265             TAG_LOGE(AAFwkTag::APPKIT, "innerErrCode=%{public}d", *innerErrCode);
266             task.Reject(env, CreateJsErrorByNativeErr(env, *innerErrCode));
267             return;
268         }
269         task.ResolveWithNoError(env, JsKioskManager::CreateJsKioskStatus(env, kioskStatus));
270     };
271     napi_value result = nullptr;
272     NapiAsyncTask::Schedule("JsKioskManager::OnGetKioskStatus", env,
273                             CreateAsyncTaskWithLastParam(env, nullptr, std::move(execute),
274                                                          std::move(complete), &result));
275     return result;
276 }
277 
JsKioskManagerInit(napi_env env,napi_value exportObj)278 napi_value JsKioskManagerInit(napi_env env, napi_value exportObj)
279 {
280     std::unique_ptr<JsKioskManager> jsKioskManager = std::make_unique<JsKioskManager>();
281     napi_wrap(env, exportObj, jsKioskManager.release(), JsKioskManager::Finalizer, nullptr,
282               nullptr);
283 
284     const char *moduleName = "JsKioskManager";
285 
286     BindNativeFunction(env, exportObj, "updateKioskAppList", moduleName,
287                        JsKioskManager::UpdateKioskApplicationList);
288     BindNativeFunction(env, exportObj, "enterKioskMode", moduleName, JsKioskManager::EnterKioskMode);
289     BindNativeFunction(env, exportObj, "exitKioskMode", moduleName, JsKioskManager::ExitKioskMode);
290     BindNativeFunction(env, exportObj, "getKioskStatus", moduleName, JsKioskManager::GetKioskStatus);
291 
292     TAG_LOGD(AAFwkTag::APPKIT, "end");
293     return CreateJsUndefined(env);
294 }
295 }  // namespace AbilityRuntime
296 }  // namespace OHOS
297