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