• 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 
16 #include "print_callback.h"
17 #include "napi_print_utils.h"
18 #include "print_job_helper.h"
19 #include "printer_info_helper.h"
20 #include "print_attributes_helper.h"
21 #include "print_log.h"
22 
23 namespace OHOS::Print {
PrintCallback(napi_env env,napi_ref ref)24 PrintCallback::PrintCallback(napi_env env, napi_ref ref) : env_(env), ref_(ref), adapter_(nullptr)
25 {
26 }
27 
PrintCallback(PrintDocumentAdapter * adapter)28 PrintCallback::PrintCallback(PrintDocumentAdapter* adapter) : env_(nullptr), ref_(nullptr), adapter_(adapter)
29 {
30 }
31 
~PrintCallback()32 PrintCallback::~PrintCallback()
33 {
34     if (adapter_ != nullptr) {
35         delete adapter_;
36         adapter_ = nullptr;
37     } else if (nativePrinterChange_cb != nullptr) {
38         nativePrinterChange_cb = nullptr;
39     } else {
40         std::lock_guard<std::mutex> autoLock(mutex_);
41         Param *param = new (std::nothrow) Param;
42         if (param == nullptr) {
43             return;
44         }
45         param->env = env_;
46         param->callbackRef = ref_;
47         auto task = [param]() {
48             if (param == nullptr) {
49                 PRINT_HILOGE("param is a nullptr");
50                 return;
51             }
52             napi_handle_scope scope = nullptr;
53             napi_open_handle_scope(param->env, &scope);
54             if (scope == nullptr) {
55                 PRINT_HILOGE("scope is a nullptr");
56                 delete param;
57                 return;
58             }
59             napi_ref callbackRef_ = param->callbackRef;
60             NapiPrintUtils::DeleteReference(param->env, callbackRef_);
61             napi_close_handle_scope(param->env, scope);
62             delete param;
63         };
64         napi_status ret = napi_send_event(env_, task, napi_eprio_immediate);
65         if (ret != napi_ok) {
66             PRINT_HILOGE("napi_send_event fail");
67             delete param;
68         }
69     }
70 }
71 
NapiCallFunction(CallbackParam * cbParam,size_t argcCount,napi_value * callbackValues)72 static void NapiCallFunction(CallbackParam* cbParam, size_t argcCount, napi_value* callbackValues)
73 {
74     if (cbParam == nullptr) {
75         PRINT_HILOGE("cbParam is nullptr");
76         return;
77     }
78     napi_handle_scope scope = nullptr;
79     napi_open_handle_scope(cbParam->env, &scope);
80     if (scope == nullptr) {
81         PRINT_HILOGE("fail to open scope");
82         return;
83     }
84 
85     napi_value callbackFunc = NapiPrintUtils::GetReference(cbParam->env, cbParam->ref);
86     if (callbackFunc != nullptr) {
87         napi_call_function(cbParam->env, nullptr, callbackFunc, argcCount,
88             callbackValues, nullptr);
89         PRINT_HILOGI("NapiCallFunction run napi_call_function success");
90     } else {
91         PRINT_HILOGE("NapiCallFunction get reference failed");
92     }
93     napi_close_handle_scope(cbParam->env, scope);
94 }
95 
PrintAdapterWorkCb(CallbackParam * cbParam)96 static void PrintAdapterWorkCb(CallbackParam *cbParam)
97 {
98     PRINT_HILOGI("OnCallback start run PrintAdapterWorkCb");
99     if (cbParam == nullptr) {
100         PRINT_HILOGE("cbParam is nullptr");
101         return;
102     }
103     napi_handle_scope scope = nullptr;
104     napi_open_handle_scope(cbParam->env, &scope);
105     if (scope == nullptr) {
106         PRINT_HILOGE("fail to open scope");
107         close(cbParam->fd);
108         return;
109     }
110     napi_value adapterObj = NapiPrintUtils::GetReference(cbParam->env, cbParam->ref);
111     if (adapterObj != nullptr) {
112         napi_value layoutWriteFunc =
113             NapiPrintUtils::GetNamedProperty(cbParam->env, adapterObj, "onStartLayoutWrite");
114         auto successCallback = [](napi_env env, napi_callback_info info) -> napi_value {
115             PRINT_HILOGI("parse from js callback data start");
116             size_t argc = NapiPrintUtils::ARGC_TWO;
117             napi_value args[NapiPrintUtils::ARGC_TWO] = {nullptr};
118 
119             napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
120             std::string jobId = NapiPrintUtils::GetStringFromValueUtf8(env, args[0]);
121             uint32_t replyState = NapiPrintUtils::GetUint32FromValue(env, args[1]);
122 
123             PrintManagerClient::GetInstance()->UpdatePrintJobStateForNormalApp(
124                 jobId, PRINT_JOB_CREATE_FILE_COMPLETED, replyState);
125             PRINT_HILOGI("from js return jobId:%{public}s, replyState:%{public}d", jobId.c_str(), replyState);
126             return nullptr;
127         };
128         napi_value callbackResult = nullptr;
129         napi_value callbackValues[NapiPrintUtils::ARGC_FIVE] = { 0 };
130         callbackValues[0] = NapiPrintUtils::CreateStringUtf8(cbParam->env, cbParam->jobId);
131         callbackValues[1] = PrintAttributesHelper::MakeJsObject(cbParam->env, cbParam->oldAttrs);
132         callbackValues[NapiPrintUtils::ARGC_TWO] =
133             PrintAttributesHelper::MakeJsObject(cbParam->env, cbParam->newAttrs);
134         callbackValues[NapiPrintUtils::ARGC_THREE] =
135             NapiPrintUtils::CreateUint32(cbParam->env, cbParam->fd);
136         callbackValues[NapiPrintUtils::ARGC_FOUR] =
137             NapiPrintUtils::CreateFunction(cbParam->env, "writeResultCallback", successCallback, nullptr);
138 
139         napi_call_function(cbParam->env, adapterObj, layoutWriteFunc, NapiPrintUtils::ARGC_FIVE,
140             callbackValues, &callbackResult);
141         PRINT_HILOGI("OnCallback end run PrintAdapterWorkCb success");
142     }
143     if (napi_close_handle_scope(cbParam->env, scope) != napi_ok) {
144         close(cbParam->fd);
145     }
146 }
147 
OnBaseCallback(std::function<void (CallbackParam *)> paramFun,std::function<void (CallbackParam *)> workCb)148 bool PrintCallback::OnBaseCallback(std::function<void(CallbackParam*)> paramFun,
149     std::function<void(CallbackParam*)> workCb)
150 {
151     CallbackParam *param = new (std::nothrow) CallbackParam;
152     if (param == nullptr) {
153         PRINT_HILOGE("Failed to create callback parameter");
154         return false;
155     }
156 
157     {
158         std::lock_guard<std::mutex> lock(mutex_);
159         param->env = env_;
160         param->ref = ref_;
161         param->mutexPtr = &mutex_;
162         paramFun(param);
163     }
164 
165     auto task = [param, workCb]() {
166         if (param == nullptr) {
167             PRINT_HILOGE("param is a nullptr");
168             return;
169         }
170         std::lock_guard<std::mutex> autoLock(*param->mutexPtr);
171         workCb(param);
172         delete param;
173     };
174 
175     napi_status ret = napi_send_event(env_, task, napi_eprio_immediate);
176     if (ret != napi_ok) {
177         PRINT_HILOGE("napi_send_event fail");
178         delete param;
179         return false;
180     }
181     return true;
182 }
183 
OnCallback()184 bool PrintCallback::OnCallback()
185 {
186     PRINT_HILOGI("PrintTask Notification in");
187     return OnBaseCallback([](CallbackParam* param) {},
188         [](CallbackParam *cbParam) {
189             PRINT_HILOGI("OnCallback start run OnCallback");
190             napi_value callbackValues[NapiPrintUtils::ARGC_ONE] = { 0 };
191             callbackValues[0] = NapiPrintUtils::GetUndefined(cbParam->env);
192             NapiCallFunction(cbParam, NapiPrintUtils::ARGC_ZERO, callbackValues);
193         });
194 }
195 
OnCallback(uint32_t state,const PrinterInfo & info)196 bool PrintCallback::OnCallback(uint32_t state, const PrinterInfo &info)
197 {
198     PRINT_HILOGI("Printer Notification in");
199     if (nativePrinterChange_cb != nullptr) {
200         return nativePrinterChange_cb(state, info);
201     }
202     return OnBaseCallback(
203         [state, info](CallbackParam* param) {
204             param->state = state;
205             param->printerInfo = info;
206         },
207         [](CallbackParam *cbParam) {
208             PRINT_HILOGI("OnCallback start run PrinterInfoWorkCb");
209             napi_value callbackValues[NapiPrintUtils::ARGC_TWO] = { 0 };
210             callbackValues[0] = NapiPrintUtils::CreateUint32(cbParam->env, cbParam->state);
211             callbackValues[1] = PrinterInfoHelper::MakeJsObject(cbParam->env, cbParam->printerInfo);
212             NapiCallFunction(cbParam, NapiPrintUtils::ARGC_TWO, callbackValues);
213         });
214 }
215 
OnCallback(uint32_t state,const PrintJob & info)216 bool PrintCallback::OnCallback(uint32_t state, const PrintJob &info)
217 {
218     PRINT_HILOGI("PrintJob Notification in");
219     return OnBaseCallback(
220         [state, info](CallbackParam* param) {
221             param->state = state;
222             param->jobInfo = info;
223         },
224         [](CallbackParam *cbParam) {
225             PRINT_HILOGI("OnCallback start run PrinterInfoWorkCb");
226             napi_value callbackValues[NapiPrintUtils::ARGC_TWO] = { 0 };
227             callbackValues[0] = NapiPrintUtils::CreateUint32(cbParam->env, cbParam->state);
228             callbackValues[1] = cbParam->jobInfo.GetPrinterId().length() == 0
229                 ? PrintJobHelper::MakeJsSimpleObject(cbParam->env, cbParam->jobInfo)
230                 : PrintJobHelper::MakeJsObject(cbParam->env, cbParam->jobInfo);
231             NapiCallFunction(cbParam, NapiPrintUtils::ARGC_TWO, callbackValues);
232         });
233 }
234 
OnCallback(const std::string & extensionId,const std::string & info)235 bool PrintCallback::OnCallback(const std::string &extensionId, const std::string &info)
236 {
237     PRINT_HILOGI("ExtensionInfo Notification in");
238     return OnBaseCallback(
239         [extensionId, info](CallbackParam* param) {
240             param->extensionId = extensionId;
241             param->info = info;
242         },
243         [](CallbackParam *cbParam) {
244             PRINT_HILOGI("OnCallback start run PrinterInfoWorkCb");
245             napi_value callbackValues[NapiPrintUtils::ARGC_TWO] = { 0 };
246             callbackValues[0] =
247                 NapiPrintUtils::CreateStringUtf8(cbParam->env, cbParam->extensionId);
248             callbackValues[1] =
249                 NapiPrintUtils::CreateStringUtf8(cbParam->env, cbParam->info);
250             NapiCallFunction(cbParam, NapiPrintUtils::ARGC_TWO, callbackValues);
251         });
252 }
253 
OnCallbackAdapterLayout(const std::string & jobId,const PrintAttributes & oldAttrs,const PrintAttributes & newAttrs,uint32_t fd)254 bool PrintCallback::OnCallbackAdapterLayout(
255     const std::string &jobId, const PrintAttributes &oldAttrs, const PrintAttributes &newAttrs, uint32_t fd)
256 {
257     PRINT_HILOGI("PrintCallback OnCallbackAdapterLayout Notification in, jobId:%{public}s newAttrs copyNum:%{public}d",
258         jobId.c_str(),
259         newAttrs.GetCopyNumber());
260     if (adapter_ != nullptr) {
261         PRINT_HILOGI("OnCallbackAdapterLayout run c++");
262         adapter_->onStartLayoutWrite(jobId, oldAttrs, newAttrs, fd, [](std::string jobId, uint32_t state) {
263             PRINT_HILOGI("onStartLayoutWrite write over, jobId:%{public}s state: %{public}d", jobId.c_str(), state);
264             PrintManagerClient::GetInstance()->UpdatePrintJobStateForNormalApp(
265                 jobId, PRINT_JOB_CREATE_FILE_COMPLETED, state);
266         });
267         return true;
268     } else {
269         PRINT_HILOGI("OnCallbackAdapterLayout run ets");
270         return OnBaseCallback(
271             [jobId, oldAttrs, newAttrs, fd](CallbackParam *param) {
272                 param->jobId = jobId;
273                 param->oldAttrs = oldAttrs;
274                 param->newAttrs = newAttrs;
275                 param->fd = fd;
276             },
277             PrintAdapterWorkCb);
278     }
279 }
280 
OnCallbackAdapterJobStateChanged(const std::string jobId,const uint32_t state,const uint32_t subState)281 bool PrintCallback::OnCallbackAdapterJobStateChanged(const std::string jobId, const uint32_t state,
282     const uint32_t subState)
283 {
284     PRINT_HILOGI("PrintCallback OnCallbackAdapterJobStateChanged Notification in, jobId:%{public}s subState:%{public}d",
285         jobId.c_str(), subState);
286     if (adapter_ != nullptr) {
287         PRINT_HILOGI("OnCallbackAdapterJobStateChanged run c++");
288         adapter_->onJobStateChanged(jobId, subState);
289         return true;
290     } else {
291         PRINT_HILOGI("OnCallbackAdapterJobStateChanged run ets");
292         return OnBaseCallback(
293             [jobId, subState](CallbackParam* param) {
294                 param->jobId = jobId;
295                 param->state = subState;
296             },
297             [](CallbackParam *cbParam) {
298                 PRINT_HILOGI("OnCallback start run PrinterInfoWorkCb");
299                 napi_value callbackValues[NapiPrintUtils::ARGC_TWO] = { 0 };
300                 callbackValues[0] = NapiPrintUtils::CreateStringUtf8(cbParam->env, cbParam->jobId);
301                 callbackValues[1] = NapiPrintUtils::CreateUint32(cbParam->env, cbParam->state);
302                     NapiCallFunction(cbParam, NapiPrintUtils::ARGC_TWO, callbackValues);
303             });
304     }
305 }
306 
OnCallbackAdapterGetFile(uint32_t state)307 bool PrintCallback::OnCallbackAdapterGetFile(uint32_t state)
308 {
309     PRINT_HILOGI("OnCallbackAdapterGetFile in");
310     return OnBaseCallback(
311         [state](CallbackParam* param) {
312             param->state = state;
313         },
314         [](CallbackParam *cbParam) {
315             PRINT_HILOGI("OnCallback start run PrinterInfoWorkCb");
316             napi_value callbackValues[1] = { 0 };
317             callbackValues[0] = NapiPrintUtils::CreateUint32(cbParam->env, cbParam->state);
318             NapiCallFunction(cbParam, NapiPrintUtils::ARGC_TWO, callbackValues);
319         });
320 }
321 } // namespace OHOS::Print