1 /*
2 * Copyright (c) 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_widget_callback_v10.h"
17
18 #include <uv.h>
19
20 #include "iam_logger.h"
21
22 #define LOG_TAG "USER_AUTH_NAPI"
23
24 namespace OHOS {
25 namespace UserIam {
26 namespace UserAuth {
27 namespace {
28 struct CallbackHolder {
29 std::shared_ptr<UserAuthWidgetCallback> callback {nullptr};
30 std::string cmdData;
31 napi_env env;
32 };
33
DestoryWork(uv_work_t * work)34 void DestoryWork(uv_work_t *work)
35 {
36 if (work == nullptr) {
37 return;
38 }
39 if (work->data != nullptr) {
40 delete (reinterpret_cast<CallbackHolder *>(work->data));
41 }
42 delete work;
43 }
44
OnWork(uv_work_t * work,int status)45 void OnWork(uv_work_t *work, int status)
46 {
47 IAM_LOGI("start");
48 if (work == nullptr) {
49 IAM_LOGE("work is null");
50 return;
51 }
52 CallbackHolder *holder = reinterpret_cast<CallbackHolder *>(work->data);
53 if (holder == nullptr || holder->callback == nullptr) {
54 IAM_LOGE("holder is invalid");
55 DestoryWork(work);
56 return;
57 }
58 napi_handle_scope scope = nullptr;
59 napi_open_handle_scope(holder->env, &scope);
60 if (scope == nullptr) {
61 IAM_LOGE("scope is invalid");
62 DestoryWork(work);
63 return;
64 }
65 napi_status ret = holder->callback->DoCommandCallback(holder->cmdData);
66 if (ret != napi_ok) {
67 IAM_LOGE("DoResultCallback fail %{public}d", ret);
68 napi_close_handle_scope(holder->env, scope);
69 DestoryWork(work);
70 return;
71 }
72 napi_close_handle_scope(holder->env, scope);
73 DestoryWork(work);
74 }
75 }
76
UserAuthWidgetCallback(napi_env env)77 UserAuthWidgetCallback::UserAuthWidgetCallback(napi_env env) : env_(env)
78 {
79 if (env_ == nullptr) {
80 IAM_LOGE("UserAuthWidgetCallback get null env");
81 }
82 }
83
~UserAuthWidgetCallback()84 UserAuthWidgetCallback::~UserAuthWidgetCallback()
85 {
86 }
87
SetCommandCallback(const std::shared_ptr<JsRefHolder> & callback)88 void UserAuthWidgetCallback::SetCommandCallback(const std::shared_ptr<JsRefHolder> &callback)
89 {
90 std::lock_guard<std::mutex> guard(mutex_);
91 commandCallback_ = callback;
92 }
93
ClearCommandCallback()94 void UserAuthWidgetCallback::ClearCommandCallback()
95 {
96 std::lock_guard<std::mutex> guard(mutex_);
97 commandCallback_ = nullptr;
98 }
99
HasCommandCallback()100 bool UserAuthWidgetCallback::HasCommandCallback()
101 {
102 std::lock_guard<std::mutex> guard(mutex_);
103 return commandCallback_ != nullptr;
104 }
105
GetCommandCallback()106 std::shared_ptr<JsRefHolder> UserAuthWidgetCallback::GetCommandCallback()
107 {
108 std::lock_guard<std::mutex> guard(mutex_);
109 return commandCallback_;
110 }
111
DoCommandCallback(const std::string & cmdData)112 napi_status UserAuthWidgetCallback::DoCommandCallback(const std::string &cmdData)
113 {
114 auto commandCallback = GetCommandCallback();
115 if (commandCallback == nullptr) {
116 return napi_ok;
117 }
118 IAM_LOGI("start");
119 napi_value eventInfo = nullptr;
120 napi_status ret = napi_create_string_utf8(env_, cmdData.c_str(), cmdData.size(), &eventInfo);
121 if (ret != napi_ok) {
122 IAM_LOGE("napi_create_object failed %{public}d", ret);
123 return ret;
124 }
125 return UserAuthNapiHelper::CallVoidNapiFunc(env_, commandCallback->Get(), ARGS_ONE, &eventInfo);
126 }
127
SendCommand(const std::string & cmdData)128 void UserAuthWidgetCallback::SendCommand(const std::string &cmdData)
129 {
130 IAM_LOGI("start");
131 uv_loop_s *loop;
132 napi_status napiStatus = napi_get_uv_event_loop(env_, &loop);
133 if (napiStatus != napi_ok || loop == nullptr) {
134 IAM_LOGE("napi_get_uv_event_loop fail");
135 return;
136 }
137 uv_work_t *work = new (std::nothrow) uv_work_t;
138 if (work == nullptr) {
139 IAM_LOGE("work is null");
140 return;
141 }
142 CallbackHolder *holder = new (std::nothrow) CallbackHolder();
143 if (holder == nullptr) {
144 IAM_LOGE("holder is null");
145 delete work;
146 return;
147 }
148 holder->callback = shared_from_this();
149 holder->cmdData = cmdData;
150 holder->env = env_;
151
152 work->data = reinterpret_cast<void *>(holder);
153 if (uv_queue_work_with_qos(loop, work, [](uv_work_t *work) {}, OnWork, uv_qos_user_initiated) != 0) {
154 IAM_LOGE("uv_queue_work_with_qos fail");
155 DestoryWork(work);
156 }
157 }
158 } // namespace UserAuth
159 } // namespace UserIam
160 } // namespace OHOS
161