• 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)
25 {
26 }
27 
PrintCallback(PrintDocumentAdapter * adapter)28 PrintCallback::PrintCallback(PrintDocumentAdapter* adapter) :adapter_(adapter)
29 {
30 }
31 
~PrintCallback()32 PrintCallback::~PrintCallback()
33 {
34     if (adapter_ != nullptr) {
35         adapter_ = nullptr;
36     } else {
37         std::lock_guard<std::mutex> autoLock(mutex_);
38         PRINT_HILOGD("callback has been destroyed");
39 
40         uv_loop_s *loop = nullptr;
41         napi_get_uv_event_loop(env_, &loop);
42         Param *param = new (std::nothrow) Param;
43         if (param == nullptr) {
44             return;
45         }
46         param->env = env_;
47         param->callbackRef = ref_;
48         uv_work_t *work = new (std::nothrow) uv_work_t;
49         if (work == nullptr) {
50             delete param;
51             return;
52         }
53         work->data = reinterpret_cast<void*>(param);
54         uv_queue_work(loop, work, [](uv_work_t *work) {}, [](uv_work_t *work, int _status) {
55             PRINT_HILOGD("uv_queue_work PrintCallback DeleteReference");
56             Param *param_ = reinterpret_cast<Param*>(work->data);
57             if (param_ == nullptr) {
58                 delete work;
59                 return;
60             }
61             napi_handle_scope scope = nullptr;
62             napi_open_handle_scope(param_->env, &scope);
63             if (scope == nullptr) {
64                 delete param_;
65                 delete work;
66                 return;
67             }
68             napi_ref callbackRef_ = param_->callbackRef;
69             NapiPrintUtils::DeleteReference(param_->env, callbackRef_);
70             napi_close_handle_scope(param_->env, scope);
71             delete param_;
72             delete work;
73         });
74     }
75 }
76 
InitUvWorkCallbackEnv(uv_work_t * work,napi_handle_scope & scope)77 static bool InitUvWorkCallbackEnv(uv_work_t *work, napi_handle_scope &scope)
78 {
79     if (work == nullptr) {
80         PRINT_HILOGE("work is nullptr");
81         return false;
82     }
83     if (work->data == nullptr) {
84         PRINT_HILOGE("data is nullptr");
85         return false;
86     }
87     CallbackParam *cbParam = reinterpret_cast<CallbackParam *>(work->data);
88     napi_open_handle_scope(cbParam->env, &scope);
89     if (scope == nullptr) {
90         PRINT_HILOGE("fail to open scope");
91         delete cbParam;
92         work->data = nullptr;
93         return false;
94     }
95     return true;
96 }
97 
PrintTaskAfterCallFun(uv_work_t * work,int status)98 static void PrintTaskAfterCallFun(uv_work_t *work, int status)
99 {
100     PRINT_HILOGI("OnCallback start run PrintTaskAfterCallFun");
101     napi_handle_scope scope = nullptr;
102     if (!InitUvWorkCallbackEnv(work, scope)) {
103         return;
104     }
105     CallbackParam *cbParam = static_cast<CallbackParam*>(work->data);
106     if (cbParam != nullptr) {
107         std::lock_guard<std::mutex> autoLock(*cbParam->mutexPtr);
108         napi_value callbackFunc = NapiPrintUtils::GetReference(cbParam->env, cbParam->ref);
109         napi_value callbackResult = nullptr;
110         napi_value callbackValues[NapiPrintUtils::ARGC_ONE] = { 0 };
111         callbackValues[0] = NapiPrintUtils::GetUndefined(cbParam->env);
112         napi_call_function(cbParam->env, nullptr, callbackFunc, NapiPrintUtils::ARGC_ZERO,
113             callbackValues, &callbackResult);
114         napi_close_handle_scope(cbParam->env, scope);
115         PRINT_HILOGI("OnCallback end run PrintTaskAfterCallFun success");
116         if (work != nullptr) {
117             delete work;
118             work = nullptr;
119         }
120         delete cbParam;
121         cbParam = nullptr;
122     }
123 }
124 
PrinterAfterCallFun(uv_work_t * work,int status)125 static void PrinterAfterCallFun(uv_work_t *work, int status)
126 {
127     PRINT_HILOGI("OnCallback start run PrinterAfterCallFun");
128     napi_handle_scope scope = nullptr;
129     if (!InitUvWorkCallbackEnv(work, scope)) {
130         return;
131     }
132     CallbackParam *cbParam = static_cast<CallbackParam*>(work->data);
133     if (cbParam != nullptr) {
134         std::lock_guard<std::mutex> autoLock(*cbParam->mutexPtr);
135         napi_value callbackFunc = NapiPrintUtils::GetReference(cbParam->env, cbParam->ref);
136         napi_value callbackResult = nullptr;
137         napi_value callbackValues[NapiPrintUtils::ARGC_TWO] = { 0 };
138         callbackValues[0] = NapiPrintUtils::CreateUint32(cbParam->env, cbParam->state);
139         callbackValues[1] = PrinterInfoHelper::MakeJsObject(cbParam->env, cbParam->printerInfo);
140         napi_call_function(cbParam->env, nullptr, callbackFunc, NapiPrintUtils::ARGC_TWO,
141             callbackValues, &callbackResult);
142         napi_close_handle_scope(cbParam->env, scope);
143         PRINT_HILOGI("OnCallback end run PrinterAfterCallFun success");
144         if (work != nullptr) {
145             delete work;
146             work = nullptr;
147         }
148         delete cbParam;
149         cbParam = nullptr;
150     }
151 }
152 
PrintJobAfterCallFun(uv_work_t * work,int status)153 static void PrintJobAfterCallFun(uv_work_t *work, int status)
154 {
155     PRINT_HILOGI("OnCallback start run PrintJobAfterCallFun");
156     napi_handle_scope scope = nullptr;
157     if (!InitUvWorkCallbackEnv(work, scope)) {
158         return;
159     }
160     CallbackParam *cbParam = static_cast<CallbackParam*>(work->data);
161     if (cbParam != nullptr) {
162         std::lock_guard<std::mutex> autoLock(*cbParam->mutexPtr);
163         napi_value callbackFunc = NapiPrintUtils::GetReference(cbParam->env, cbParam->ref);
164         napi_value callbackResult = nullptr;
165         napi_value callbackValues[NapiPrintUtils::ARGC_TWO] = { 0 };
166         callbackValues[0] = NapiPrintUtils::CreateUint32(cbParam->env, cbParam->state);
167         callbackValues[1] = cbParam->jobInfo.GetPrinterId().length() == 0
168             ? PrintJobHelper::MakeJsSimpleObject(cbParam->env, cbParam->jobInfo)
169             : PrintJobHelper::MakeJsObject(cbParam->env, cbParam->jobInfo);
170         napi_call_function(cbParam->env, nullptr, callbackFunc, NapiPrintUtils::ARGC_TWO,
171             callbackValues, &callbackResult);
172         napi_close_handle_scope(cbParam->env, scope);
173         PRINT_HILOGI("OnCallback end run PrintJobAfterCallFun success");
174         if (work != nullptr) {
175             delete work;
176             work = nullptr;
177         }
178         delete cbParam;
179         cbParam = nullptr;
180     }
181 }
182 
ExtensionAfterCallFun(uv_work_t * work,int status)183 static void ExtensionAfterCallFun(uv_work_t *work, int status)
184 {
185     PRINT_HILOGI("OnCallback start run ExtensionAfterCallFun");
186     napi_handle_scope scope = nullptr;
187     if (!InitUvWorkCallbackEnv(work, scope)) {
188         return;
189     }
190     CallbackParam *cbParam = static_cast<CallbackParam*>(work->data);
191     if (cbParam != nullptr) {
192         std::lock_guard<std::mutex> autoLock(*cbParam->mutexPtr);
193         napi_value callbackFunc = NapiPrintUtils::GetReference(cbParam->env, cbParam->ref);
194         napi_value callbackResult = nullptr;
195         napi_value callbackValues[NapiPrintUtils::ARGC_TWO] = { 0 };
196         callbackValues[0] =
197             NapiPrintUtils::CreateStringUtf8(cbParam->env, cbParam->extensionId);
198         callbackValues[1] =
199             NapiPrintUtils::CreateStringUtf8(cbParam->env, cbParam->info);
200         napi_call_function(cbParam->env, nullptr, callbackFunc, NapiPrintUtils::ARGC_TWO,
201             callbackValues, &callbackResult);
202         napi_close_handle_scope(cbParam->env, scope);
203         PRINT_HILOGI("OnCallback end run ExtensionAfterCallFun success");
204         if (work != nullptr) {
205             delete work;
206             work = nullptr;
207         }
208         delete cbParam;
209         cbParam = nullptr;
210     }
211 }
212 
PrintAdapterAfterCallFun(uv_work_t * work,int status)213 static void PrintAdapterAfterCallFun(uv_work_t *work, int status)
214 {
215     PRINT_HILOGI("OnCallback start run PrintAdapterAfterCallFun");
216     napi_handle_scope scope = nullptr;
217     if (!InitUvWorkCallbackEnv(work, scope)) {
218         return;
219     }
220     CallbackParam *cbParam = static_cast<CallbackParam*>(work->data);
221     if (cbParam != nullptr) {
222         std::lock_guard<std::mutex> autoLock(*cbParam->mutexPtr);
223         napi_value adapterObj = NapiPrintUtils::GetReference(cbParam->env, cbParam->ref);
224 
225         napi_value layoutWriteFunc = NapiPrintUtils::GetNamedProperty(cbParam->env, adapterObj, "onStartLayoutWrite");
226         auto successCallback = [](napi_env env, napi_callback_info info) -> napi_value {
227             PRINT_HILOGI("parse from js callback data start");
228             size_t argc = NapiPrintUtils::ARGC_TWO;
229             napi_value args[NapiPrintUtils::ARGC_TWO] = {nullptr};
230 
231             napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
232             std::string jobId = NapiPrintUtils::GetStringFromValueUtf8(env, args[0]);
233             uint32_t replyState = NapiPrintUtils::GetUint32FromValue(env, args[1]);
234 
235             PrintManagerClient::GetInstance()->UpdatePrintJobState(jobId, PRINT_JOB_CREATE_FILE_COMPLETED, replyState);
236             PRINT_HILOGI("from js return jobId:%{public}s, replyState:%{public}d", jobId.c_str(), replyState);
237             return nullptr;
238         };
239 
240         napi_value callbackResult = nullptr;
241         napi_value callbackValues[NapiPrintUtils::ARGC_FIVE] = { 0 };
242         callbackValues[0] = NapiPrintUtils::CreateStringUtf8(cbParam->env, cbParam->jobId);
243         callbackValues[1] = PrintAttributesHelper::MakeJsObject(cbParam->env, cbParam->oldAttrs);
244         callbackValues[NapiPrintUtils::ARGC_TWO] =
245             PrintAttributesHelper::MakeJsObject(cbParam->env, cbParam->newAttrs);
246         callbackValues[NapiPrintUtils::ARGC_THREE] =
247             NapiPrintUtils::CreateUint32(cbParam->env, cbParam->fd);
248         callbackValues[NapiPrintUtils::ARGC_FOUR] =
249             NapiPrintUtils::CreateFunction(cbParam->env, "writeResultCallback", successCallback, nullptr);
250 
251         napi_call_function(cbParam->env, adapterObj, layoutWriteFunc, NapiPrintUtils::ARGC_FIVE,
252             callbackValues, &callbackResult);
253 
254         napi_close_handle_scope(cbParam->env, scope);
255         PRINT_HILOGI("OnCallback end run PrintAdapterAfterCallFun success");
256         if (work != nullptr) {
257             delete work;
258             work = nullptr;
259         }
260         delete cbParam;
261         cbParam = nullptr;
262     }
263 }
264 
PrintAdapterJobStateChangedAfterCallFun(uv_work_t * work,int status)265 static void PrintAdapterJobStateChangedAfterCallFun(uv_work_t *work, int status)
266 {
267     PRINT_HILOGI("OnCallback start run PrintAdapterJobStateChangedAfterCallFun");
268     napi_handle_scope scope = nullptr;
269     if (!InitUvWorkCallbackEnv(work, scope)) {
270         return;
271     }
272     CallbackParam *cbParam = static_cast<CallbackParam*>(work->data);
273     if (cbParam != nullptr) {
274         std::lock_guard<std::mutex> autoLock(*cbParam->mutexPtr);
275         napi_value adapterObj = NapiPrintUtils::GetReference(cbParam->env, cbParam->ref);
276 
277         napi_value jobStateChangedFunc = NapiPrintUtils::GetNamedProperty(cbParam->env, adapterObj,
278             "onJobStateChanged");
279 
280         napi_value callbackResult = nullptr;
281         napi_value callbackValues[NapiPrintUtils::ARGC_TWO] = { 0 };
282         callbackValues[0] = NapiPrintUtils::CreateStringUtf8(cbParam->env, cbParam->jobId);
283         callbackValues[1] = NapiPrintUtils::CreateUint32(cbParam->env, cbParam->state);
284 
285         napi_call_function(cbParam->env, adapterObj, jobStateChangedFunc, NapiPrintUtils::ARGC_TWO,
286             callbackValues, &callbackResult);
287 
288         napi_close_handle_scope(cbParam->env, scope);
289         PRINT_HILOGI("OnCallback end run PrintAdapterJobStateChangedAfterCallFun success");
290         if (work != nullptr) {
291             delete work;
292             work = nullptr;
293         }
294         delete cbParam;
295         cbParam = nullptr;
296     }
297 }
298 
PrintAdapterGetFileAfterCallFun(uv_work_t * work,int status)299 static void PrintAdapterGetFileAfterCallFun(uv_work_t *work, int status)
300 {
301     PRINT_HILOGI("OnCallback start run PrintAdapterGetFileAfterCallFun");
302     napi_handle_scope scope = nullptr;
303     if (!InitUvWorkCallbackEnv(work, scope)) {
304         return;
305     }
306     CallbackParam *cbParam = static_cast<CallbackParam*>(work->data);
307     if (cbParam != nullptr) {
308         std::lock_guard<std::mutex> autoLock(*cbParam->mutexPtr);
309         napi_value callbackFunc = NapiPrintUtils::GetReference(cbParam->env, cbParam->ref);
310         napi_value callbackResult = nullptr;
311         napi_value callbackValues[1] = { 0 };
312         callbackValues[0] = NapiPrintUtils::CreateUint32(cbParam->env, cbParam->state);
313         napi_call_function(cbParam->env, nullptr, callbackFunc, 1,
314             callbackValues, &callbackResult);
315         napi_close_handle_scope(cbParam->env, scope);
316         PRINT_HILOGI("OnCallback end run PrintAdapterGetFileAfterCallFun success");
317         if (work != nullptr) {
318             delete work;
319             work = nullptr;
320         }
321         delete cbParam;
322         cbParam = nullptr;
323     }
324 }
325 
onBaseCallback(std::function<void (CallbackParam *)> paramFun,uv_after_work_cb after_work_cb)326 bool PrintCallback::onBaseCallback(std::function<void(CallbackParam*)> paramFun, uv_after_work_cb after_work_cb)
327 {
328     uv_loop_s *loop = nullptr;
329     napi_get_uv_event_loop(env_, &loop);
330     if (loop == nullptr) {
331         PRINT_HILOGE("Failed to get uv event loop");
332         return false;
333     }
334 
335     uv_work_t *work = new (std::nothrow) uv_work_t;
336     if (work == nullptr) {
337         PRINT_HILOGE("Failed to create uv work");
338         return false;
339     }
340     CallbackParam *param = new (std::nothrow) CallbackParam;
341     if (param == nullptr) {
342         PRINT_HILOGE("Failed to create callback parameter");
343         return false;
344     } else {
345         std::lock_guard<std::mutex> lock(mutex_);
346 
347         param->env = env_;
348         param->ref = ref_;
349         param->mutexPtr = &mutex_;
350 
351         paramFun(param);
352     }
353 
354     work->data = param;
355     uv_queue_work(loop, work, [](uv_work_t *work) {}, after_work_cb);
356     return true;
357 }
358 
OnCallback()359 bool PrintCallback::OnCallback()
360 {
361     PRINT_HILOGI("PrintTask Notification in");
362     return onBaseCallback([](CallbackParam* param) {}, PrintTaskAfterCallFun);
363 }
364 
OnCallback(uint32_t state,const PrinterInfo & info)365 bool PrintCallback::OnCallback(uint32_t state, const PrinterInfo &info)
366 {
367     PRINT_HILOGI("Printer Notification in");
368     return onBaseCallback(
369         [state, info](CallbackParam* param) {
370             param->state = state;
371             param->printerInfo = info;
372         }, PrinterAfterCallFun);
373 }
374 
OnCallback(uint32_t state,const PrintJob & info)375 bool PrintCallback::OnCallback(uint32_t state, const PrintJob &info)
376 {
377     PRINT_HILOGI("PrintJob Notification in");
378     return onBaseCallback(
379         [state, info](CallbackParam* param) {
380             param->state = state;
381             param->jobInfo = info;
382         }, PrintJobAfterCallFun);
383 }
384 
OnCallback(const std::string & extensionId,const std::string & info)385 bool PrintCallback::OnCallback(const std::string &extensionId, const std::string &info)
386 {
387     PRINT_HILOGI("ExtensionInfo Notification in");
388     return onBaseCallback(
389         [extensionId, info](CallbackParam* param) {
390             param->extensionId = extensionId;
391             param->info = info;
392         }, ExtensionAfterCallFun);
393 }
394 
OnCallbackAdapterLayout(const std::string & jobId,const PrintAttributes & oldAttrs,const PrintAttributes & newAttrs,uint32_t fd)395 bool PrintCallback::OnCallbackAdapterLayout(const std::string &jobId, const PrintAttributes &oldAttrs,
396     const PrintAttributes &newAttrs, uint32_t fd)
397 {
398     PRINT_HILOGI("PrintCallback OnCallbackAdapterLayout Notification in, jobId:%{public}s newAttrs copyNum:%{public}d",
399         jobId.c_str(), newAttrs.GetCopyNumber());
400     if (adapter_ != nullptr) {
401         PRINT_HILOGI("OnCallbackAdapterLayout run c++");
402         adapter_->onStartLayoutWrite(jobId, oldAttrs, newAttrs, fd, [](std::string jobId, uint32_t state) {
403             PRINT_HILOGI("onStartLayoutWrite write over, jobId:%{public}s state: %{public}d", jobId.c_str(), state);
404             PrintManagerClient::GetInstance()->UpdatePrintJobState(jobId, PRINT_JOB_CREATE_FILE_COMPLETED, state);
405         });
406         return true;
407     } else {
408         PRINT_HILOGI("OnCallbackAdapterLayout run ets");
409         return onBaseCallback(
410             [jobId, oldAttrs, newAttrs, fd](CallbackParam* param) {
411                 param->jobId = jobId;
412                 param->oldAttrs = oldAttrs;
413                 param->newAttrs = newAttrs;
414                 param->fd = fd;
415             }, PrintAdapterAfterCallFun);
416     }
417 }
418 
onCallbackAdapterJobStateChanged(const std::string jobId,const uint32_t state,const uint32_t subState)419 bool PrintCallback::onCallbackAdapterJobStateChanged(const std::string jobId, const uint32_t state,
420     const uint32_t subState)
421 {
422     PRINT_HILOGI("PrintCallback onCallbackAdapterJobStateChanged Notification in, jobId:%{public}s subState:%{public}d",
423         jobId.c_str(), subState);
424     if (adapter_ != nullptr) {
425         PRINT_HILOGI("onCallbackAdapterJobStateChanged run c++");
426         adapter_->onJobStateChanged(jobId, subState);
427         return true;
428     } else {
429         PRINT_HILOGI("onCallbackAdapterJobStateChanged run ets");
430         return onBaseCallback(
431             [jobId, subState](CallbackParam* param) {
432                 param->jobId = jobId;
433                 param->state = subState;
434             }, PrintAdapterJobStateChangedAfterCallFun);
435     }
436 }
437 
OnCallbackAdapterGetFile(uint32_t state)438 bool PrintCallback::OnCallbackAdapterGetFile(uint32_t state)
439 {
440     PRINT_HILOGI("OnCallbackAdapterGetFile in");
441     return onBaseCallback(
442         [state](CallbackParam* param) {
443             param->state = state;
444         }, PrintAdapterGetFileAfterCallFun);
445 }
446 }  // namespace OHOS::Print
447