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