• 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 #include "napi_screenlock_ability.h"
16 
17 #include <hitrace_meter.h>
18 #include <map>
19 #include <napi/native_api.h>
20 #include <pthread.h>
21 #include <unistd.h>
22 #include <uv.h>
23 
24 #include "event_listener.h"
25 #include "ipc_skeleton.h"
26 #include "sclock_log.h"
27 #include "screenlock_callback.h"
28 #include "screenlock_common.h"
29 #include "screenlock_js_util.h"
30 #include "screenlock_manager.h"
31 #include "screenlock_system_ability_callback.h"
32 
33 using namespace OHOS;
34 using namespace OHOS::ScreenLock;
35 
36 namespace OHOS {
37 namespace ScreenLock {
38 constexpr const char *PERMISSION_VALIDATION_FAILED = "Permission verification failed.";
39 constexpr const char *PARAMETER_VALIDATION_FAILED = "Parameter verification failed.";
40 constexpr const char *CANCEL_UNLOCK_OPERATION = "The user canceled the unlock operation.";
41 constexpr const char *SERVICE_IS_ABNORMAL = "The screenlock management service is abnormal.";
42 constexpr const char *ILLEGAL_USE = "Invalid use.";
43 constexpr const char *NON_SYSTEM_APP = "Permission verification failed, application which is not a system application "
44                                        "uses system API.";
45 constexpr const char *USER_ID_INVALID = "The userId is not same as the caller, and is not allowed for the caller.";
46 
47 const std::map<int, uint32_t> ERROR_CODE_CONVERSION = {
48     { E_SCREENLOCK_NO_PERMISSION, JsErrorCode::ERR_NO_PERMISSION },
49     { E_SCREENLOCK_PARAMETERS_INVALID, JsErrorCode::ERR_INVALID_PARAMS },
50     { E_SCREENLOCK_WRITE_PARCEL_ERROR, JsErrorCode::ERR_SERVICE_ABNORMAL },
51     { E_SCREENLOCK_NULLPTR, JsErrorCode::ERR_SERVICE_ABNORMAL },
52     { E_SCREENLOCK_SENDREQUEST_FAILED, JsErrorCode::ERR_SERVICE_ABNORMAL },
53     { E_SCREENLOCK_NOT_FOCUS_APP, JsErrorCode::ERR_ILLEGAL_USE },
54     { E_SCREENLOCK_NOT_SYSTEM_APP, JsErrorCode::ERR_NOT_SYSTEM_APP },
55     { E_SCREENLOCK_USER_ID_INVALID, JsErrorCode::ERR_USER_ID_INVALID },
56 };
57 const std::map<uint32_t, std::string> ERROR_INFO_MAP = {
58     { JsErrorCode::ERR_NO_PERMISSION, PERMISSION_VALIDATION_FAILED },
59     { JsErrorCode::ERR_INVALID_PARAMS, PARAMETER_VALIDATION_FAILED },
60     { JsErrorCode::ERR_CANCEL_UNLOCK, CANCEL_UNLOCK_OPERATION },
61     { JsErrorCode::ERR_SERVICE_ABNORMAL, SERVICE_IS_ABNORMAL },
62     { JsErrorCode::ERR_ILLEGAL_USE, ILLEGAL_USE },
63     { JsErrorCode::ERR_NOT_SYSTEM_APP, NON_SYSTEM_APP },
64     { JsErrorCode::ERR_USER_ID_INVALID, USER_ID_INVALID },
65 };
66 
Init(napi_env env,napi_value exports)67 napi_status Init(napi_env env, napi_value exports)
68 {
69     napi_property_descriptor exportFuncs[] = {
70         DECLARE_NAPI_FUNCTION("isScreenLocked", OHOS::ScreenLock::NAPI_IsScreenLocked),
71         DECLARE_NAPI_FUNCTION("isLocked", OHOS::ScreenLock::NAPI_IsLocked),
72         DECLARE_NAPI_FUNCTION("lock", OHOS::ScreenLock::NAPI_Lock),
73         DECLARE_NAPI_FUNCTION("unlockScreen", OHOS::ScreenLock::NAPI_UnlockScreen),
74         DECLARE_NAPI_FUNCTION("unlock", OHOS::ScreenLock::NAPI_Unlock),
75         DECLARE_NAPI_FUNCTION("isSecureMode", OHOS::ScreenLock::NAPI_IsSecureMode),
76         DECLARE_NAPI_FUNCTION("onSystemEvent", NAPI_OnSystemEvent),
77         DECLARE_NAPI_FUNCTION("sendScreenLockEvent", OHOS::ScreenLock::NAPI_ScreenLockSendEvent),
78         DECLARE_NAPI_FUNCTION("isScreenLockDisabled", OHOS::ScreenLock::NAPI_IsScreenLockDisabled),
79         DECLARE_NAPI_FUNCTION("setScreenLockDisabled", OHOS::ScreenLock::NAPI_SetScreenLockDisabled),
80         DECLARE_NAPI_FUNCTION("setScreenLockAuthState", OHOS::ScreenLock::NAPI_SetScreenLockAuthState),
81         DECLARE_NAPI_FUNCTION("getScreenLockAuthState", OHOS::ScreenLock::NAPI_GetScreenLockAuthState),
82         DECLARE_NAPI_FUNCTION("requestStrongAuth", OHOS::ScreenLock::NAPI_RequestStrongAuth),
83         DECLARE_NAPI_FUNCTION("getStrongAuth", OHOS::ScreenLock::NAPI_GetStrongAuth),
84         DECLARE_NAPI_FUNCTION("isDeviceLocked", OHOS::ScreenLock::NAPI_IsDeviceLocked),
85     };
86     napi_define_properties(env, exports, sizeof(exportFuncs) / sizeof(*exportFuncs), exportFuncs);
87     return napi_ok;
88 }
89 
IsValidEvent(const std::string & type)90 napi_status IsValidEvent(const std::string &type)
91 {
92     if (type == UNLOCK_SCREEN_RESULT || type == SCREEN_DRAWDONE || type == LOCK_SCREEN_RESULT) {
93         return napi_ok;
94     }
95     return napi_invalid_arg;
96 }
97 
CheckParamType(napi_env env,napi_value param,napi_valuetype jsType)98 napi_status CheckParamType(napi_env env, napi_value param, napi_valuetype jsType)
99 {
100     napi_valuetype valueType = napi_undefined;
101     napi_status status = napi_typeof(env, param, &valueType);
102     if (status != napi_ok || valueType != jsType) {
103         return napi_invalid_arg;
104     }
105     return napi_ok;
106 }
107 
CheckParamArrayType(napi_env env,napi_value param,napi_typedarray_type jsType)108 napi_status CheckParamArrayType(napi_env env, napi_value param, napi_typedarray_type jsType)
109 {
110     size_t length = 0;
111     void *data = nullptr;
112     napi_typedarray_type type = napi_biguint64_array;
113     napi_value inputBuffer = nullptr;
114     size_t byteOffset = 0;
115     napi_get_typedarray_info(env, param, &type, &length, &data, &inputBuffer, &byteOffset);
116     if (type != jsType || data == nullptr) {
117         SCLOCK_HILOGE("napi_get_typedarray_info err");
118         return napi_invalid_arg;
119     }
120     return napi_ok;
121 }
122 
CheckParamNumber(size_t argc,std::uint32_t paramNumber)123 napi_status CheckParamNumber(size_t argc, std::uint32_t paramNumber)
124 {
125     if (argc < paramNumber) {
126         return napi_invalid_arg;
127     }
128     return napi_ok;
129 }
130 
ThrowError(napi_env env,const uint32_t & code,const std::string & msg)131 void ThrowError(napi_env env, const uint32_t &code, const std::string &msg)
132 {
133     napi_value message;
134     NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(env, msg.c_str(), NAPI_AUTO_LENGTH, &message));
135     napi_value error;
136     NAPI_CALL_RETURN_VOID(env, napi_create_error(env, nullptr, message, &error));
137     napi_value errorCode;
138     NAPI_CALL_RETURN_VOID(env, napi_create_uint32(env, code, &errorCode));
139     NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, error, "code", errorCode));
140     NAPI_CALL_RETURN_VOID(env, napi_throw(env, error));
141     SCLOCK_HILOGD("ThrowError");
142 }
143 
GetErrorInfo(int32_t errorCode,ErrorInfo & errorInfo)144 void GetErrorInfo(int32_t errorCode, ErrorInfo &errorInfo)
145 {
146     std::map<int, uint32_t>::const_iterator iter = ERROR_CODE_CONVERSION.find(errorCode);
147     if (iter != ERROR_CODE_CONVERSION.end()) {
148         errorInfo.errorCode_ = iter->second;
149         errorInfo.message_ = GetErrorMessage(errorInfo.errorCode_);
150         SCLOCK_HILOGD("GetErrorInfo errorInfo.code: %{public}d, errorInfo.message: %{public}s", errorInfo.errorCode_,
151             errorInfo.message_.c_str());
152     } else {
153         SCLOCK_HILOGD("GetErrorInfo errCode: %{public}d", errorCode);
154     }
155 }
156 
GetErrorMessage(const uint32_t & code)157 std::string GetErrorMessage(const uint32_t &code)
158 {
159     std::string message;
160     std::map<uint32_t, std::string>::const_iterator iter = ERROR_INFO_MAP.find(code);
161     if (iter != ERROR_INFO_MAP.end()) {
162         message = iter->second;
163     }
164     SCLOCK_HILOGD("GetErrorMessage: message is %{public}s", message.c_str());
165     return message;
166 }
167 
NAPI_IsScreenLocked(napi_env env,napi_callback_info info)168 napi_value NAPI_IsScreenLocked(napi_env env, napi_callback_info info)
169 {
170     SCLOCK_HILOGD("NAPI_IsScreenLocked begin");
171     AsyncScreenLockInfo *context = new AsyncScreenLockInfo();
172     auto input = [context](napi_env env, size_t argc, napi_value argv[], napi_value self) -> napi_status {
173         NAPI_ASSERT_BASE(
174             env, argc == ARGS_SIZE_ZERO || argc == ARGS_SIZE_ONE, " should 0 or 1 parameters!", napi_invalid_arg);
175         SCLOCK_HILOGD("input ---- argc : %{public}zu", argc);
176         return napi_ok;
177     };
178     auto output = [context](napi_env env, napi_value *result) -> napi_status {
179         napi_status status = napi_get_boolean(env, context->allowed, result);
180         SCLOCK_HILOGD("output ---- napi_get_boolean[%{public}d]", status);
181         return napi_ok;
182     };
183     auto exec = [context](AsyncCall::Context *ctx) {
184         context->allowed = ScreenLockManager::GetInstance()->IsScreenLocked();
185         SCLOCK_HILOGD("NAPI_IsScreenLocked exec allowed = %{public}d ", context->allowed);
186         context->SetStatus(napi_ok);
187     };
188     context->SetAction(std::move(input), std::move(output));
189     AsyncCall asyncCall(env, info, context, ARGS_SIZE_ZERO);
190     return asyncCall.Call(env, exec, "isScreenLocked");
191 }
192 
NAPI_IsLocked(napi_env env,napi_callback_info info)193 napi_value NAPI_IsLocked(napi_env env, napi_callback_info info)
194 {
195     napi_value result = nullptr;
196     bool isLocked = false;
197     int32_t status = ScreenLockManager::GetInstance()->IsLocked(isLocked);
198     if (status != E_SCREENLOCK_OK) {
199         ErrorInfo errInfo;
200         errInfo.errorCode_ = static_cast<uint32_t>(status);
201         GetErrorInfo(status, errInfo);
202         ThrowError(env, errInfo.errorCode_, errInfo.message_);
203         return result;
204     }
205     napi_get_boolean(env, isLocked, &result);
206     return result;
207 }
208 
CompleteAsyncWork(napi_env env,napi_status status,void * data)209 static void CompleteAsyncWork(napi_env env, napi_status status, void *data)
210 {
211     EventListener *eventListener = reinterpret_cast<EventListener *>(data);
212     if (eventListener == nullptr) {
213         return;
214     }
215     if (eventListener->work != nullptr) {
216         napi_delete_async_work(env, eventListener->work);
217     }
218     delete eventListener;
219 }
220 
AsyncCallFunc(napi_env env,EventListener * listener,const std::string & resourceName)221 void AsyncCallFunc(napi_env env, EventListener *listener, const std::string &resourceName)
222 {
223     napi_value resource = nullptr;
224     auto execute = [](napi_env env, void *data) {
225         EventListener *eventListener = reinterpret_cast<EventListener *>(data);
226         if (eventListener == nullptr) {
227             return;
228         }
229 
230         sptr<ScreenlockCallback> callback = new (std::nothrow) ScreenlockCallback(*eventListener);
231         if (callback == nullptr) {
232             SCLOCK_HILOGE("NAPI_Lock create callback object fail");
233             if (eventListener->callbackRef != nullptr) {
234                 napi_delete_reference(env, eventListener->callbackRef);
235             }
236             return;
237         }
238         int32_t status = 0;
239         if (eventListener->action == Action::LOCK) {
240             status = ScreenLockManager::GetInstance()->Lock(callback);
241         } else if (eventListener->action == Action::UNLOCK || eventListener->action == Action::UNLOCKSCREEN) {
242             status = ScreenLockManager::GetInstance()->Unlock(eventListener->action, callback);
243         }
244         if (status != E_SCREENLOCK_OK) {
245             ErrorInfo errInfo;
246             errInfo.errorCode_ = static_cast<uint32_t>(status);
247             GetErrorInfo(status, errInfo);
248             callback->SetErrorInfo(errInfo);
249             callback->OnCallBack(status);
250         }
251     };
252     std::string name = "THEME_" + resourceName;
253     napi_create_string_utf8(env, name.c_str(), NAPI_AUTO_LENGTH, &resource);
254     napi_create_async_work(
255         env, nullptr, resource, execute, CompleteAsyncWork, static_cast<void *>(listener), &(listener->work));
256     auto ret = napi_queue_async_work_with_qos(env, listener->work, napi_qos_user_initiated);
257     if (ret != napi_ok) {
258         CompleteAsyncWork(env, ret, listener);
259         NAPI_CALL_RETURN_VOID(env, ret);
260     }
261 }
262 
NAPI_Lock(napi_env env,napi_callback_info info)263 napi_value NAPI_Lock(napi_env env, napi_callback_info info)
264 {
265     SCLOCK_HILOGD("NAPI_Lock begin");
266     napi_value ret = nullptr;
267     size_t argc = ARGS_SIZE_ONE;
268     napi_value argv[ARGS_SIZE_ONE] = { nullptr };
269     napi_value thisVar = nullptr;
270     void *data = nullptr;
271     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
272     napi_ref callbackRef = nullptr;
273     EventListener *eventListener = nullptr;
274     if (argc == ARGS_SIZE_ONE) {
275         SCLOCK_HILOGD("NAPI_Lock callback");
276         if (CheckParamType(env, argv[ARGV_ZERO], napi_function) != napi_ok) {
277             std::string errMsg = "Parameter error. The type of \"callback\" must be function";
278             ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, errMsg);
279             return ret;
280         }
281         SCLOCK_HILOGD("NAPI_Lock create callback");
282         napi_create_reference(env, argv[ARGV_ZERO], 1, &callbackRef);
283         eventListener = new (std::nothrow)
284             EventListener{ .env = env, .thisVar = thisVar, .callbackRef = callbackRef, .action = Action::LOCK };
285 
286         if (eventListener == nullptr) {
287             SCLOCK_HILOGE("eventListener is nullptr");
288             return nullptr;
289         }
290     }
291     if (callbackRef == nullptr) {
292         SCLOCK_HILOGD("NAPI_Lock create promise");
293         napi_deferred deferred;
294         napi_create_promise(env, &deferred, &ret);
295         eventListener = new (std::nothrow)
296             EventListener{ .env = env, .thisVar = thisVar, .deferred = deferred, .action = Action::LOCK };
297 
298         if (eventListener == nullptr) {
299             SCLOCK_HILOGE("eventListener is nullptr");
300             return nullptr;
301         }
302     } else {
303         SCLOCK_HILOGD("NAPI_Lock create callback");
304         napi_get_undefined(env, &ret);
305     }
306     AsyncCallFunc(env, eventListener, "lock");
307     return ret;
308 }
309 
NAPI_UnlockScreen(napi_env env,napi_callback_info info)310 napi_value NAPI_UnlockScreen(napi_env env, napi_callback_info info)
311 {
312     StartAsyncTrace(HITRACE_TAG_MISC, "NAPI_UnlockScreen start", HITRACE_UNLOCKSCREEN);
313     napi_value ret = nullptr;
314     size_t argc = ARGS_SIZE_ONE;
315     napi_value argv[ARGS_SIZE_ONE] = { nullptr };
316     napi_value thisVar = nullptr;
317     void *data = nullptr;
318     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
319     NAPI_ASSERT(env, argc == ARGS_SIZE_ZERO || argc == ARGS_SIZE_ONE, "Wrong number of arguments, requires one");
320     napi_ref callbackRef = nullptr;
321     EventListener *eventListener = nullptr;
322     napi_valuetype valueType = napi_undefined;
323     if (argc == ARGS_SIZE_ONE) {
324         napi_typeof(env, argv[ARGV_ZERO], &valueType);
325         SCLOCK_HILOGD("NAPI_UnlockScreen callback");
326         NAPI_ASSERT(env, valueType == napi_function, "callback is not a function");
327         napi_create_reference(env, argv[ARGV_ZERO], 1, &callbackRef);
328         eventListener = new (std::nothrow)
329             EventListener{ .env = env, .thisVar = thisVar, .callbackRef = callbackRef, .action = Action::UNLOCKSCREEN };
330         if (eventListener == nullptr) {
331             SCLOCK_HILOGE("eventListener is nullptr");
332             return nullptr;
333         }
334     }
335     if (callbackRef == nullptr) {
336         SCLOCK_HILOGD("NAPI_UnlockScreen create promise");
337         napi_deferred deferred;
338         napi_create_promise(env, &deferred, &ret);
339         eventListener = new (std::nothrow)
340             EventListener{ .env = env, .thisVar = thisVar, .deferred = deferred, .action = Action::UNLOCKSCREEN };
341         if (eventListener == nullptr) {
342             SCLOCK_HILOGE("eventListener is nullptr");
343             return nullptr;
344         }
345     } else {
346         SCLOCK_HILOGD("NAPI_UnlockScreen create callback");
347         napi_get_undefined(env, &ret);
348     }
349     AsyncCallFunc(env, eventListener, "unLockScreen");
350     return ret;
351 }
352 
NAPI_Unlock(napi_env env,napi_callback_info info)353 napi_value NAPI_Unlock(napi_env env, napi_callback_info info)
354 {
355     SCLOCK_HILOGD("NAPI_Unlock begin");
356     napi_value ret = nullptr;
357     size_t argc = ARGS_SIZE_ONE;
358     napi_value argv[ARGS_SIZE_ONE] = { nullptr };
359     napi_value thisVar = nullptr;
360     void *data = nullptr;
361     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
362     napi_ref callbackRef = nullptr;
363     EventListener *eventListener = nullptr;
364     if (argc == ARGS_SIZE_ONE) {
365         SCLOCK_HILOGD("NAPI_Unlock callback");
366         if (CheckParamType(env, argv[ARGV_ZERO], napi_function) != napi_ok) {
367             std::string errMsg = "Parameter error. The type of \"callback\" must be function";
368             ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, errMsg);
369             return nullptr;
370         }
371         SCLOCK_HILOGD("NAPI_Unlock create callback");
372         napi_create_reference(env, argv[ARGV_ZERO], 1, &callbackRef);
373         eventListener = new (std::nothrow)
374             EventListener{ .env = env, .thisVar = thisVar, .callbackRef = callbackRef, .action = Action::UNLOCK };
375         if (eventListener == nullptr) {
376             SCLOCK_HILOGE("eventListener is nullptr");
377             return nullptr;
378         }
379     }
380     if (callbackRef == nullptr) {
381         SCLOCK_HILOGD("NAPI_Unlock create promise");
382         napi_deferred deferred;
383         napi_create_promise(env, &deferred, &ret);
384         eventListener = new (std::nothrow)
385             EventListener{ .env = env, .thisVar = thisVar, .deferred = deferred, .action = Action::UNLOCK };
386         if (eventListener == nullptr) {
387             SCLOCK_HILOGE("eventListener is nullptr");
388             return nullptr;
389         }
390     } else {
391         SCLOCK_HILOGD("NAPI_Unlock create callback");
392         napi_get_undefined(env, &ret);
393     }
394     AsyncCallFunc(env, eventListener, "unLock");
395     return ret;
396 }
397 
NAPI_IsSecureMode(napi_env env,napi_callback_info info)398 napi_value NAPI_IsSecureMode(napi_env env, napi_callback_info info)
399 {
400     SCLOCK_HILOGD("NAPI_IsSecureMode begin");
401     AsyncScreenLockInfo *context = new AsyncScreenLockInfo();
402     auto input = [context](napi_env env, size_t argc, napi_value argv[], napi_value self) -> napi_status {
403         SCLOCK_HILOGD("input ---- argc : %{public}zu", argc);
404         return napi_ok;
405     };
406     auto output = [context](napi_env env, napi_value *result) -> napi_status {
407         napi_status status = napi_get_boolean(env, context->allowed, result);
408         SCLOCK_HILOGD("output ---- napi_get_boolean[%{public}d]", status);
409         return napi_ok;
410     };
411     auto exec = [context](AsyncCall::Context *ctx) {
412         SCLOCK_HILOGD("exec ---- NAPI_IsSecureMode begin");
413         context->allowed = ScreenLockManager::GetInstance()->GetSecure();
414         SCLOCK_HILOGD("NAPI_IsSecureMode exec allowed = %{public}d ", context->allowed);
415         context->SetStatus(napi_ok);
416     };
417     context->SetAction(std::move(input), std::move(output));
418     AsyncCall asyncCall(env, info, context, ARGS_SIZE_ZERO);
419     return asyncCall.Call(env, exec, "isSecureMode");
420 }
421 
NAPI_OnSystemEvent(napi_env env,napi_callback_info info)422 napi_value NAPI_OnSystemEvent(napi_env env, napi_callback_info info)
423 {
424     SCLOCK_HILOGD("NAPI_OnSystemEvent in");
425     napi_value result = nullptr;
426     bool status = false;
427     napi_get_boolean(env, status, &result);
428     size_t argc = ARGS_SIZE_ONE;
429     napi_value argv = { nullptr };
430     napi_value thisVar = nullptr;
431     void *data = nullptr;
432     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &argv, &thisVar, &data));
433     if (CheckParamNumber(argc, ARGS_SIZE_ONE) != napi_ok) {
434         std::string errMsg = "Parameter error. The number of parameters should 1";
435         ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, errMsg);
436         return result;
437     }
438     if (CheckParamType(env, argv, napi_function) != napi_ok) {
439         std::string errMsg = "Parameter error. The type of \"callback\" must be function";
440         ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, errMsg);
441         return result;
442     }
443     napi_ref callbackRef = nullptr;
444     napi_create_reference(env, argv, ARGS_SIZE_ONE, &callbackRef);
445     EventListener eventListener{ .env = env, .thisVar = thisVar, .callbackRef = callbackRef };
446     sptr<ScreenlockSystemAbilityCallback> listener = new (std::nothrow) ScreenlockSystemAbilityCallback(eventListener);
447     if (listener != nullptr) {
448         ScreenlockSystemAbilityCallback::GetEventHandler();
449         int32_t retCode = ScreenLockManager::GetInstance()->OnSystemEvent(listener);
450         if (retCode != E_SCREENLOCK_OK) {
451             ErrorInfo errInfo;
452             errInfo.errorCode_ = static_cast<uint32_t>(retCode);
453             GetErrorInfo(retCode, errInfo);
454             ThrowError(env, errInfo.errorCode_, errInfo.message_);
455             status = false;
456         } else {
457             status = true;
458         }
459     }
460     SCLOCK_HILOGD("on system event  status=%{public}d", status);
461     napi_get_boolean(env, status, &result);
462     return result;
463 }
464 
NAPI_ScreenLockSendEvent(napi_env env,napi_callback_info info)465 napi_value NAPI_ScreenLockSendEvent(napi_env env, napi_callback_info info)
466 {
467     SendEventInfo *context = new SendEventInfo();
468     auto input = [context](napi_env env, size_t argc, napi_value argv[], napi_value self) -> napi_status {
469         if (CheckParamNumber(argc, ARGS_SIZE_TWO) != napi_ok) {
470             std::string errMsg = "Parameter error. The number of parameters should 2";
471             ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, errMsg);
472             return napi_invalid_arg;
473         }
474         if (CheckParamType(env, argv[ARGV_ZERO], napi_string) != napi_ok) {
475             std::string errMsg = "Parameter error. The type of \"event\" must be string";
476             ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, errMsg);
477             return napi_invalid_arg;
478         }
479         char event[MAX_VALUE_LEN] = { 0 };
480         size_t len;
481         napi_get_value_string_utf8(env, argv[ARGV_ZERO], event, MAX_VALUE_LEN, &len);
482         context->eventInfo = event;
483         if (IsValidEvent(context->eventInfo) != napi_ok) {
484             ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, PARAMETER_VALIDATION_FAILED);
485             return napi_invalid_arg;
486         }
487         if (CheckParamType(env, argv[ARGV_ONE], napi_number) != napi_ok) {
488             ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, PARAMETER_VALIDATION_FAILED);
489             return napi_invalid_arg;
490         }
491         napi_get_value_int32(env, argv[ARGV_ONE], &context->param);
492         return napi_ok;
493     };
494     auto output = [context](napi_env env, napi_value *result) -> napi_status {
495         napi_status status = napi_get_boolean(env, context->allowed, result);
496         SCLOCK_HILOGD("output ---- napi_get_boolean[%{public}d]", status);
497         return napi_ok;
498     };
499     auto exec = [context](AsyncCall::Context *ctx) {
500         int32_t retCode = ScreenLockManager::GetInstance()->SendScreenLockEvent(context->eventInfo, context->param);
501         if (retCode != E_SCREENLOCK_OK) {
502             ErrorInfo errInfo;
503             errInfo.errorCode_ = static_cast<uint32_t>(retCode);
504             GetErrorInfo(retCode, errInfo);
505             context->SetErrorInfo(errInfo);
506             context->allowed = false;
507         } else {
508             context->SetStatus(napi_ok);
509             context->allowed = true;
510         }
511     };
512     context->SetAction(std::move(input), std::move(output));
513     AsyncCall asyncCall(env, info, context, ARGV_TWO);
514     return asyncCall.Call(env, exec, "screenLockSendEvent");
515 }
516 
NAPI_IsScreenLockDisabled(napi_env env,napi_callback_info info)517 napi_value NAPI_IsScreenLockDisabled(napi_env env, napi_callback_info info)
518 {
519     SCLOCK_HILOGD("NAPI_IsScreenLockDisabled in");
520     napi_value result = nullptr;
521     size_t argc = ARGS_SIZE_ONE;
522     napi_value argv[ARGS_SIZE_ONE] = { 0 };
523     napi_value thisVar = nullptr;
524     void *data = nullptr;
525     int userId = -1;
526     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
527     if (CheckParamNumber(argc, ARGS_SIZE_ONE) != napi_ok) {
528         std::string errMsg = "Parameter error. The number of parameters should 1";
529         ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, errMsg);
530         return result;
531     }
532     if (CheckParamType(env, argv[ARGV_ZERO], napi_number) != napi_ok) {
533         std::string errMsg = "Parameter error. The type of \"userId\" must be number";
534         ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, errMsg);
535         return result;
536     }
537     napi_get_value_int32(env, argv[ARGV_ZERO], &userId);
538     bool isDisabled = false;
539     int32_t status = ScreenLockManager::GetInstance()->IsScreenLockDisabled(userId, isDisabled);
540     if (status != E_SCREENLOCK_OK) {
541         ErrorInfo errInfo;
542         errInfo.errorCode_ = static_cast<uint32_t>(status);
543         GetErrorInfo(status, errInfo);
544         ThrowError(env, errInfo.errorCode_, errInfo.message_);
545         return result;
546     }
547     SCLOCK_HILOGI("NAPI_IsScreenLockDisabled [isDisabled]=%{public}d", isDisabled);
548     napi_get_boolean(env, isDisabled, &result);
549     return result;
550 }
551 
NAPI_SetScreenLockDisabled(napi_env env,napi_callback_info info)552 napi_value NAPI_SetScreenLockDisabled(napi_env env, napi_callback_info info)
553 {
554     SCLOCK_HILOGD("NAPI_SetScreenLockDisabled begin");
555     ScreenLockDisableInfo *context = new ScreenLockDisableInfo();
556     auto input = [context](napi_env env, size_t argc, napi_value argv[], napi_value self) -> napi_status {
557         if (CheckParamNumber(argc, ARGS_SIZE_TWO) != napi_ok) {
558             std::string errMsg = "Parameter error. The number of parameters should be at least 2";
559             ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, errMsg);
560             return napi_invalid_arg;
561         }
562         if (CheckParamType(env, argv[ARGV_ZERO], napi_boolean) != napi_ok) {
563             std::string errMsg = "Parameter error. The type of \"disable\" must be boolean";
564             ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, errMsg);
565             return napi_invalid_arg;
566         }
567         napi_get_value_bool(env, argv[ARGV_ZERO], &context->disable);
568         if (CheckParamType(env, argv[ARGV_ONE], napi_number) != napi_ok) {
569             std::string errMsg = "Parameter error. The type of \"userId\" must be number";
570             ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, errMsg);
571             return napi_invalid_arg;
572         }
573         napi_get_value_int32(env, argv[ARGV_ONE], &context->userId);
574         return napi_ok;
575     };
576     auto output = [context](napi_env env, napi_value *result) -> napi_status {
577         napi_status status = napi_get_boolean(env, context->allowed, result);
578         SCLOCK_HILOGD("output ---- napi_get_boolean[%{public}d]", status);
579         return napi_ok;
580     };
581     auto exec = [context](AsyncCall::Context *ctx) {
582         int32_t retCode = ScreenLockManager::GetInstance()->SetScreenLockDisabled(context->disable, context->userId);
583         if (retCode != E_SCREENLOCK_OK) {
584             ErrorInfo errInfo;
585             errInfo.errorCode_ = static_cast<uint32_t>(retCode);
586             GetErrorInfo(retCode, errInfo);
587             context->SetErrorInfo(errInfo);
588             context->allowed = false;
589         } else {
590             context->SetStatus(napi_ok);
591             context->allowed = true;
592         }
593     };
594     context->SetAction(std::move(input), std::move(output));
595     AsyncCall asyncCall(env, info, context, ARGV_TWO);
596     return asyncCall.Call(env, exec, "setScreenLockDisabled");
597 }
598 
NAPI_SetScreenLockAuthState(napi_env env,napi_callback_info info)599 napi_value NAPI_SetScreenLockAuthState(napi_env env, napi_callback_info info)
600 {
601     ScreenLockAuthStatInfo *context = new ScreenLockAuthStatInfo();
602     auto input = [context](napi_env env, size_t argc, napi_value argv[], napi_value self) -> napi_status {
603         if (CheckParamNumber(argc, ARGS_SIZE_THREE) != napi_ok) {
604             ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, PARAMETER_VALIDATION_FAILED);
605             return napi_invalid_arg;
606         }
607         if (CheckParamType(env, argv[ARGV_ZERO], napi_number) != napi_ok) {
608             ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, PARAMETER_VALIDATION_FAILED);
609             return napi_invalid_arg;
610         }
611         napi_get_value_int32(env, argv[ARGV_ZERO], &context->authState);
612 
613         if (CheckParamType(env, argv[ARGV_ONE], napi_number) != napi_ok) {
614             ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, PARAMETER_VALIDATION_FAILED);
615             return napi_invalid_arg;
616         }
617         napi_get_value_int32(env, argv[ARGV_ONE], &context->userId);
618 
619         if (CheckParamArrayType(env, argv[ARGV_TWO], napi_uint8_array) != napi_ok) {
620             ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, PARAMETER_VALIDATION_FAILED);
621             return napi_invalid_arg;
622         }
623         char authToken[MAX_VALUE_LEN] = { 0 };
624         size_t len;
625         napi_get_value_string_utf8(env, argv[ARGV_TWO], authToken, MAX_VALUE_LEN, &len);
626         context->authToken = authToken;
627 
628         return napi_ok;
629     };
630     auto output = [context](napi_env env, napi_value *result) -> napi_status {
631         napi_status status = napi_get_boolean(env, context->allowed, result);
632         SCLOCK_HILOGD("output ---- napi_get_boolean[%{public}d]", status);
633         return napi_ok;
634     };
635     auto exec = [context](AsyncCall::Context *ctx) {
636         int32_t retCode = ScreenLockManager::GetInstance()->SetScreenLockAuthState(context->authState,
637             context->userId, context->authToken);
638         if (retCode != E_SCREENLOCK_OK) {
639             ErrorInfo errInfo;
640             errInfo.errorCode_ = static_cast<uint32_t>(retCode);
641             GetErrorInfo(retCode, errInfo);
642             context->SetErrorInfo(errInfo);
643             context->allowed = false;
644         } else {
645             context->SetStatus(napi_ok);
646             context->allowed = true;
647         }
648     };
649     context->SetAction(std::move(input), std::move(output));
650     AsyncCall asyncCall(env, info, context, ARGS_SIZE_THREE);
651     return asyncCall.Call(env, exec, "setScreenLockDisabled");
652 }
653 
NAPI_GetScreenLockAuthState(napi_env env,napi_callback_info info)654 napi_value NAPI_GetScreenLockAuthState(napi_env env, napi_callback_info info)
655 {
656     SCLOCK_HILOGD("NAPI_GetScreenLockAuthState in");
657     napi_value result = nullptr;
658     size_t argc = ARGS_SIZE_ONE;
659     napi_value argv[ARGS_SIZE_ONE] = { 0 };
660     napi_value thisVar = nullptr;
661     void *data = nullptr;
662     int userId = -1;
663     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
664     if (CheckParamNumber(argc, ARGS_SIZE_ONE) != napi_ok) {
665         ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, PARAMETER_VALIDATION_FAILED);
666         return result;
667     }
668     if (CheckParamType(env, argv[ARGV_ZERO], napi_number) != napi_ok) {
669         ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, PARAMETER_VALIDATION_FAILED);
670         return result;
671     }
672     napi_get_value_int32(env, argv[ARGV_ZERO], &userId);
673     int32_t authState = -1;
674     int32_t status = ScreenLockManager::GetInstance()->GetScreenLockAuthState(userId, authState);
675     if (status != E_SCREENLOCK_OK) {
676         ErrorInfo errInfo;
677         errInfo.errorCode_ = static_cast<uint32_t>(status);
678         GetErrorInfo(status, errInfo);
679         ThrowError(env, errInfo.errorCode_, errInfo.message_);
680         return result;
681     }
682     SCLOCK_HILOGI("NAPI_GetScreenLockAuthState [authState]=%{public}d", authState);
683     napi_create_int32(env, authState, &result);
684     return result;
685 }
686 
NAPI_RequestStrongAuth(napi_env env,napi_callback_info info)687 napi_value NAPI_RequestStrongAuth(napi_env env, napi_callback_info info)
688 {
689     ScreenLockStrongAuthInfo *context = new ScreenLockStrongAuthInfo();
690     auto input = [context](napi_env env, size_t argc, napi_value argv[], napi_value self) -> napi_status {
691         if (CheckParamNumber(argc, ARGS_SIZE_TWO) != napi_ok) {
692             ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, PARAMETER_VALIDATION_FAILED);
693             return napi_invalid_arg;
694         }
695         if (CheckParamType(env, argv[ARGV_ZERO], napi_number) != napi_ok) {
696             ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, PARAMETER_VALIDATION_FAILED);
697             return napi_invalid_arg;
698         }
699         napi_get_value_int32(env, argv[ARGV_ZERO], &context->reasonFlag);
700 
701         if (CheckParamType(env, argv[ARGV_ONE], napi_number) != napi_ok) {
702             ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, PARAMETER_VALIDATION_FAILED);
703             return napi_invalid_arg;
704         }
705         napi_get_value_int32(env, argv[ARGV_ONE], &context->userId);
706         return napi_ok;
707     };
708     auto output = [context](napi_env env, napi_value *result) -> napi_status {
709         napi_status status = napi_get_boolean(env, context->allowed, result);
710         SCLOCK_HILOGD("output ---- napi_get_boolean[%{public}d]", status);
711         return napi_ok;
712     };
713     auto exec = [context](AsyncCall::Context *ctx) {
714         int32_t retCode = ScreenLockManager::GetInstance()->RequestStrongAuth(context->reasonFlag,
715             context->userId);
716         if (retCode != E_SCREENLOCK_OK) {
717             ErrorInfo errInfo;
718             errInfo.errorCode_ = static_cast<uint32_t>(retCode);
719             GetErrorInfo(retCode, errInfo);
720             context->SetErrorInfo(errInfo);
721             context->allowed = false;
722         } else {
723             context->SetStatus(napi_ok);
724             context->allowed = true;
725         }
726     };
727     context->SetAction(std::move(input), std::move(output));
728     AsyncCall asyncCall(env, info, context, ARGS_SIZE_THREE);
729     return asyncCall.Call(env, exec, "requestStrongAuth");
730 }
731 
NAPI_GetStrongAuth(napi_env env,napi_callback_info info)732 napi_value NAPI_GetStrongAuth(napi_env env, napi_callback_info info)
733 {
734     SCLOCK_HILOGD("NAPI_GetStrongAuth in");
735     napi_value result = nullptr;
736     size_t argc = ARGS_SIZE_ONE;
737     napi_value argv[ARGS_SIZE_ONE] = { 0 };
738     napi_value thisVar = nullptr;
739     void *data = nullptr;
740     int userId = -1;
741     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
742     if (CheckParamNumber(argc, ARGS_SIZE_ONE) != napi_ok) {
743         ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, PARAMETER_VALIDATION_FAILED);
744         return result;
745     }
746     if (CheckParamType(env, argv[ARGV_ZERO], napi_number) != napi_ok) {
747         ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, PARAMETER_VALIDATION_FAILED);
748         return result;
749     }
750     napi_get_value_int32(env, argv[ARGV_ZERO], &userId);
751     int32_t reasonFlag = -1;
752     int32_t status = ScreenLockManager::GetInstance()->GetStrongAuth(userId, reasonFlag);
753     if (status != E_SCREENLOCK_OK) {
754         ErrorInfo errInfo;
755         errInfo.errorCode_ = static_cast<uint32_t>(status);
756         GetErrorInfo(status, errInfo);
757         ThrowError(env, errInfo.errorCode_, errInfo.message_);
758         return result;
759     }
760     SCLOCK_HILOGI("NAPI_GetStrongAuth [reasonFlag]=%{public}d", reasonFlag);
761     napi_create_int32(env, reasonFlag, &result);
762     return result;
763 }
764 
NAPI_IsDeviceLocked(napi_env env,napi_callback_info info)765 napi_value NAPI_IsDeviceLocked(napi_env env, napi_callback_info info)
766 {
767     SCLOCK_HILOGD("NAPI_IsDeviceLocked in");
768     napi_value result = nullptr;
769     size_t argc = ARGS_SIZE_ONE;
770     napi_value argv[ARGS_SIZE_ONE] = { 0 };
771     napi_value thisVar = nullptr;
772     void *data = nullptr;
773     int userId = static_cast<int>(SpecialUserId::USER_CURRENT);
774     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
775     if (CheckParamNumber(argc, ARGS_SIZE_ONE) != napi_ok) {
776         ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, PARAMETER_VALIDATION_FAILED);
777         return result;
778     }
779     if (CheckParamType(env, argv[ARGV_ZERO], napi_number) != napi_ok) {
780         ThrowError(env, JsErrorCode::ERR_INVALID_PARAMS, PARAMETER_VALIDATION_FAILED);
781         return result;
782     }
783     napi_get_value_int32(env, argv[ARGV_ZERO], &userId);
784     bool isDeviceLoced = true;
785     int32_t status = ScreenLockManager::GetInstance()->IsDeviceLocked(userId, isDeviceLoced);
786     if (status != E_SCREENLOCK_OK) {
787         ErrorInfo errInfo;
788         errInfo.errorCode_ = static_cast<uint32_t>(status);
789         GetErrorInfo(status, errInfo);
790         ThrowError(env, errInfo.errorCode_, errInfo.message_);
791         return result;
792     }
793     SCLOCK_HILOGI("NAPI_IsDeviceLocked [isDeviceLoced]=%{public}d", isDeviceLoced);
794     napi_get_boolean(env, isDeviceLoced, &result);
795     return result;
796 }
797 
ScreenlockInit(napi_env env,napi_value exports)798 static napi_value ScreenlockInit(napi_env env, napi_value exports)
799 {
800     napi_status ret = Init(env, exports);
801     if (ret != napi_ok) {
802         SCLOCK_HILOGE("ModuleInit failed!");
803     }
804     return exports;
805 }
806 
RegisterModule(void)807 extern "C" __attribute__((constructor)) void RegisterModule(void)
808 {
809     napi_module module = { .nm_version = 1, // NAPI v1
810         .nm_flags = 0,                      // normal
811         .nm_filename = nullptr,
812         .nm_register_func = ScreenlockInit,
813         .nm_modname = "screenLock",
814         .nm_priv = nullptr,
815         .reserved = {} };
816     napi_module_register(&module);
817 }
818 } // namespace ScreenLock
819 } // namespace OHOS