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