1 /*
2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "user_auth_callback_v6.h"
17
18 #include <uv.h>
19
20 #include "iam_logger.h"
21
22 #include "user_auth_napi_helper.h"
23
24 #define LOG_TAG "USER_AUTH_NAPI"
25
26 namespace OHOS {
27 namespace UserIam {
28 namespace UserAuth {
29 namespace {
30 struct ResultCallbackV6Holder {
31 std::shared_ptr<UserAuthCallbackV6> callback {nullptr};
32 int32_t result {0};
33 napi_env env;
34 };
35
36 const std::map<int32_t, AuthenticationResult> g_result2ExecuteResult = {
37 {ResultCode::SUCCESS, AuthenticationResult::SUCCESS},
38 {ResultCode::FAIL, AuthenticationResult::COMPARE_FAILURE},
39 {ResultCode::GENERAL_ERROR, AuthenticationResult::GENERAL_ERROR},
40 {ResultCode::CANCELED, AuthenticationResult::CANCELED},
41 {ResultCode::TIMEOUT, AuthenticationResult::TIMEOUT},
42 {ResultCode::TYPE_NOT_SUPPORT, AuthenticationResult::NO_SUPPORT},
43 {ResultCode::TRUST_LEVEL_NOT_SUPPORT, AuthenticationResult::NO_SUPPORT},
44 {ResultCode::BUSY, AuthenticationResult::BUSY},
45 {ResultCode::INVALID_PARAMETERS, AuthenticationResult::INVALID_PARAMETERS},
46 {ResultCode::LOCKED, AuthenticationResult::LOCKED},
47 {ResultCode::NOT_ENROLLED, AuthenticationResult::NOT_ENROLLED},
48 {ResultCode::IPC_ERROR, AuthenticationResult::GENERAL_ERROR},
49 {ResultCode::INVALID_CONTEXT_ID, AuthenticationResult::GENERAL_ERROR},
50 {ResultCode::WRITE_PARCEL_ERROR, AuthenticationResult::GENERAL_ERROR},
51 {ResultCode::READ_PARCEL_ERROR, AuthenticationResult::GENERAL_ERROR},
52 {ResultCode::CHECK_PERMISSION_FAILED, AuthenticationResult::GENERAL_ERROR},
53 {ResultCode::PIN_EXPIRED, AuthenticationResult::GENERAL_ERROR},
54 };
55
DestoryWork(uv_work_t * work)56 void DestoryWork(uv_work_t *work)
57 {
58 if (work == nullptr) {
59 return;
60 }
61 if (work->data != nullptr) {
62 delete (reinterpret_cast<ResultCallbackV6Holder *>(work->data));
63 }
64 delete work;
65 }
66
OnCallbackV6Work(uv_work_t * work,int status)67 void OnCallbackV6Work(uv_work_t *work, int status)
68 {
69 IAM_LOGI("start");
70 if (work == nullptr) {
71 IAM_LOGE("work is null");
72 return;
73 }
74 ResultCallbackV6Holder *resultHolder = reinterpret_cast<ResultCallbackV6Holder *>(work->data);
75 if (resultHolder == nullptr || resultHolder->callback == nullptr) {
76 IAM_LOGE("resultHolder is invalid");
77 DestoryWork(work);
78 return;
79 }
80 napi_handle_scope scope = nullptr;
81 napi_open_handle_scope(resultHolder->env, &scope);
82 if (scope == nullptr) {
83 IAM_LOGE("scope is invalid");
84 DestoryWork(work);
85 return;
86 }
87 napi_status ret = resultHolder->callback->DoPromise(resultHolder->result);
88 if (ret != napi_ok) {
89 IAM_LOGE("DoPromise fail %{public}d", ret);
90 napi_close_handle_scope(resultHolder->env, scope);
91 DestoryWork(work);
92 return;
93 }
94 ret = resultHolder->callback->DoCallback(resultHolder->result);
95 if (ret != napi_ok) {
96 IAM_LOGE("DoCallback fail %{public}d", ret);
97 napi_close_handle_scope(resultHolder->env, scope);
98 DestoryWork(work);
99 return;
100 }
101 napi_close_handle_scope(resultHolder->env, scope);
102 DestoryWork(work);
103 return;
104 }
105 }
106
UserAuthCallbackV6(napi_env env,const std::shared_ptr<JsRefHolder> & callback,napi_deferred promise)107 UserAuthCallbackV6::UserAuthCallbackV6(napi_env env,
108 const std::shared_ptr<JsRefHolder> &callback, napi_deferred promise)
109 : env_(env), callback_(callback), promise_(promise)
110 {
111 if (env_ == nullptr) {
112 IAM_LOGE("UserAuthCallbackV6 get null env");
113 }
114 }
115
~UserAuthCallbackV6()116 UserAuthCallbackV6::~UserAuthCallbackV6()
117 {
118 }
119
DoPromise(int32_t result)120 napi_status UserAuthCallbackV6::DoPromise(int32_t result)
121 {
122 if (promise_ == nullptr) {
123 return napi_ok;
124 }
125 IAM_LOGI("start");
126 napi_value resultVal;
127 napi_status ret = napi_create_int32(env_, result, &resultVal);
128 if (ret != napi_ok) {
129 IAM_LOGE("napi_create_int32 failed %{public}d", ret);
130 return ret;
131 }
132 if (result == ResultCode::SUCCESS) {
133 ret = napi_resolve_deferred(env_, promise_, resultVal);
134 if (ret != napi_ok) {
135 IAM_LOGE("napi_resolve_deferred failed %{public}d", ret);
136 }
137 } else {
138 ret = napi_reject_deferred(env_, promise_, resultVal);
139 if (ret != napi_ok) {
140 IAM_LOGE("napi_reject_deferred failed %{public}d", ret);
141 }
142 }
143 return ret;
144 }
145
DoCallback(int32_t result)146 napi_status UserAuthCallbackV6::DoCallback(int32_t result)
147 {
148 if (callback_ == nullptr) {
149 return napi_ok;
150 }
151 IAM_LOGI("start");
152 napi_value resultVal;
153 napi_status ret = napi_create_int32(env_, result, &resultVal);
154 if (ret != napi_ok) {
155 IAM_LOGE("napi_create_int32 failed %{public}d", ret);
156 return ret;
157 }
158 return UserAuthNapiHelper::CallVoidNapiFunc(env_, callback_->Get(), ARGS_ONE, &resultVal);
159 }
160
OnAcquireInfo(int32_t module,uint32_t acquireInfo,const UserIam::UserAuth::Attributes & extraInfo)161 void UserAuthCallbackV6::OnAcquireInfo(int32_t module, uint32_t acquireInfo,
162 const UserIam::UserAuth::Attributes &extraInfo)
163 {
164 IAM_LOGI("start module:%{public}d acquireInfo:%{public}u", module, acquireInfo);
165 }
166
OnResult(int32_t result,const Attributes & extraInfo)167 void UserAuthCallbackV6::OnResult(int32_t result, const Attributes &extraInfo)
168 {
169 IAM_LOGI("start, result:%{public}d", result);
170 uv_loop_s *loop;
171 napi_status napiStatus = napi_get_uv_event_loop(env_, &loop);
172 if (napiStatus != napi_ok || loop == nullptr) {
173 IAM_LOGE("napi_get_uv_event_loop fail");
174 return;
175 }
176 uv_work_t *work = new (std::nothrow) uv_work_t;
177 if (work == nullptr) {
178 IAM_LOGE("work is null");
179 return;
180 }
181 ResultCallbackV6Holder *resultHolder = new (std::nothrow) ResultCallbackV6Holder();
182 if (resultHolder == nullptr) {
183 IAM_LOGE("resultHolder is null");
184 delete work;
185 return;
186 }
187 resultHolder->callback = shared_from_this();
188 auto res = g_result2ExecuteResult.find(result);
189 if (res == g_result2ExecuteResult.end()) {
190 resultHolder->result = static_cast<int32_t>(ResultCode::GENERAL_ERROR);
191 IAM_LOGE("result %{public}d not found, set execute result GENERAL_ERROR", result);
192 } else {
193 resultHolder->result = static_cast<int32_t>(res->second);
194 IAM_LOGI("convert result %{public}d to execute result %{public}d", result, resultHolder->result);
195 }
196 resultHolder->env = env_;
197 work->data = reinterpret_cast<void *>(resultHolder);
198 if (uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {}, OnCallbackV6Work, uv_qos_user_initiated) != 0) {
199 IAM_LOGE("uv_queue_work_with_qos fail");
200 DestoryWork(work);
201 }
202 }
203 } // namespace UserAuth
204 } // namespace UserIam
205 } // namespace OHOS
206