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