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 "napi_print_ext.h"
17 
18 #include "napi_print_utils.h"
19 #include "print_log.h"
20 #include "print_manager_client.h"
21 #include "printer_info_helper.h"
22 #include "printer_capability_helper.h"
23 
24 namespace OHOS::Print {
AddPrinters(napi_env env,napi_callback_info info)25 napi_value NapiPrintExt::AddPrinters(napi_env env, napi_callback_info info)
26 {
27     auto context = std::make_shared<NapiPrintExtContext>();
28     auto input = [context](
29         napi_env env, size_t argc, napi_value *argv, napi_value self, napi_callback_info info) -> napi_status {
30         PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_ONE, " should 1 parameter!", napi_invalid_arg);
31         bool isArray = false;
32         napi_is_array(env, argv[NapiPrintUtils::INDEX_ZERO], &isArray);
33         PRINT_ASSERT_BASE(env, isArray, " is not array!", napi_array_expected);
34         uint32_t len = 0;
35         napi_get_array_length(env, argv[NapiPrintUtils::INDEX_ZERO], &len);
36         for (uint32_t index = 0; index < len; index++) {
37             napi_value value;
38             napi_get_element(env, argv[NapiPrintUtils::INDEX_ZERO], index, &value);
39             auto printerInfoPtr = PrinterInfoHelper::BuildFromJs(env, value);
40             if (printerInfoPtr == nullptr) {
41                 context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
42                 PRINT_HILOGE("PrinterInfo format error!");
43                 return napi_invalid_arg;
44             }
45             printerInfoPtr->SetPrinterId(printerInfoPtr->GetPrinterId());
46             context->printerInfos.emplace_back(*printerInfoPtr);
47         }
48         if (context->printerInfos.empty()) {
49             context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
50             PRINT_HILOGE("no valid printer info exists!");
51             return napi_invalid_arg;
52         }
53         return napi_ok;
54     };
55     auto output = [context](napi_env env, napi_value *result) -> napi_status {
56         napi_status status = napi_get_boolean(env, context->result, result);
57         return status;
58     };
59     auto exec = [context](PrintAsyncCall::Context *ctx) {
60         if (!NapiPrintUtils::CheckCallerIsSystemApp()) {
61             PRINT_HILOGE("Non-system applications use system APIS!");
62             context->result = false;
63             context->SetErrorIndex(E_PRINT_ILLEGAL_USE_OF_SYSTEM_API);
64             return;
65         }
66         int32_t ret = PrintManagerClient::GetInstance()->AddPrinters(context->printerInfos);
67         context->result = ret == E_PRINT_NONE;
68         if (ret != E_PRINT_NONE) {
69             context->SetErrorIndex(ret);
70         }
71     };
72     context->SetAction(std::move(input), std::move(output));
73     PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
74     return asyncCall.Call(env, exec);
75 }
76 
RemovePrinters(napi_env env,napi_callback_info info)77 napi_value NapiPrintExt::RemovePrinters(napi_env env, napi_callback_info info)
78 {
79     PRINT_HILOGD("Enter ---->");
80     auto context = std::make_shared<NapiPrintExtContext>();
81     auto input =
82         [context](
83             napi_env env, size_t argc, napi_value *argv, napi_value self, napi_callback_info info) -> napi_status {
84         PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_ONE, " should 1 parameter!", napi_invalid_arg);
85 
86         bool isArray = false;
87         napi_is_array(env, argv[NapiPrintUtils::INDEX_ZERO], &isArray);
88         PRINT_ASSERT_BASE(env, isArray, " is not array!", napi_array_expected);
89 
90         uint32_t len = 0;
91         napi_get_array_length(env, argv[NapiPrintUtils::INDEX_ZERO], &len);
92 
93         for (uint32_t index = 0; index < len; index++) {
94             napi_value value;
95             napi_get_element(env, argv[NapiPrintUtils::INDEX_ZERO], index, &value);
96             std::string printerId = NapiPrintUtils::GetStringFromValueUtf8(env, value);
97             if (printerId != "") {
98                 context->printerIds.emplace_back(printerId);
99             }
100         }
101         if (context->printerIds.empty()) {
102             context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
103             PRINT_HILOGE("no valid printer info exists!");
104             return napi_invalid_arg;
105         }
106         return napi_ok;
107     };
108     auto output = [context](napi_env env, napi_value *result) -> napi_status {
109         napi_status status = napi_get_boolean(env, context->result, result);
110         PRINT_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status);
111         return status;
112     };
113     auto exec = [context](PrintAsyncCall::Context *ctx) {
114         if (!NapiPrintUtils::CheckCallerIsSystemApp()) {
115             PRINT_HILOGE("Non-system applications use system APIS!");
116             context->result = false;
117             context->SetErrorIndex(E_PRINT_ILLEGAL_USE_OF_SYSTEM_API);
118             return;
119         }
120         int32_t ret = PrintManagerClient::GetInstance()->RemovePrinters(context->printerIds);
121         context->result = ret == E_PRINT_NONE;
122         if (ret != E_PRINT_NONE) {
123             PRINT_HILOGE("Failed to remove printers");
124             context->SetErrorIndex(ret);
125         }
126     };
127     context->SetAction(std::move(input), std::move(output));
128     PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
129     return asyncCall.Call(env, exec);
130 }
131 
UpdatePrinters(napi_env env,napi_callback_info info)132 napi_value NapiPrintExt::UpdatePrinters(napi_env env, napi_callback_info info)
133 {
134     auto context = std::make_shared<NapiPrintExtContext>();
135     auto input = [context](
136             napi_env env, size_t argc, napi_value *argv, napi_value self, napi_callback_info info) -> napi_status {
137         PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_ONE, " should 1 parameter!", napi_invalid_arg);
138         bool isArray = false;
139         napi_is_array(env, argv[NapiPrintUtils::INDEX_ZERO], &isArray);
140         PRINT_ASSERT_BASE(env, isArray, " is not array!", napi_array_expected);
141         uint32_t len = 0;
142         napi_get_array_length(env, argv[NapiPrintUtils::INDEX_ZERO], &len);
143         for (uint32_t index = 0; index < len; index++) {
144             napi_value value;
145             napi_get_element(env, argv[NapiPrintUtils::INDEX_ZERO], index, &value);
146             auto printerInfoPtr = PrinterInfoHelper::BuildFromJs(env, value);
147             if (printerInfoPtr == nullptr) {
148                 context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
149                 PRINT_HILOGE("PrinterInfo format error!");
150                 return napi_invalid_arg;
151             }
152             context->printerInfos.emplace_back(*printerInfoPtr);
153         }
154         if (context->printerInfos.empty()) {
155             context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
156             PRINT_HILOGE("no valid printer info exists!");
157             return napi_invalid_arg;
158         }
159         return napi_ok;
160     };
161     auto output = [context](napi_env env, napi_value *result) -> napi_status {
162         napi_status status = napi_get_boolean(env, context->result, result);
163         return status;
164     };
165     auto exec = [context](PrintAsyncCall::Context *ctx) {
166         if (!NapiPrintUtils::CheckCallerIsSystemApp()) {
167             PRINT_HILOGE("Non-system applications use system APIS!");
168             context->result = false;
169             context->SetErrorIndex(E_PRINT_ILLEGAL_USE_OF_SYSTEM_API);
170             return;
171         }
172         int32_t ret = PrintManagerClient::GetInstance()->UpdatePrinters(context->printerInfos);
173         context->result = ret == E_PRINT_NONE;
174         if (ret != E_PRINT_NONE) {
175             PRINT_HILOGE("Failed to update printers");
176             context->SetErrorIndex(ret);
177         }
178     };
179     context->SetAction(std::move(input), std::move(output));
180     PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
181     return asyncCall.Call(env, exec);
182 }
183 
UpdatePrinterState(napi_env env,napi_callback_info info)184 napi_value NapiPrintExt::UpdatePrinterState(napi_env env, napi_callback_info info)
185 {
186     PRINT_HILOGD("Enter ---->");
187     auto context = std::make_shared<NapiPrintExtContext>();
188     auto input =
189         [context](
190             napi_env env, size_t argc, napi_value *argv, napi_value self, napi_callback_info info) -> napi_status {
191         PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_TWO, " should 2 parameter!", napi_invalid_arg);
192         napi_valuetype valuetype;
193         PRINT_CALL_BASE(env, napi_typeof(env, argv[NapiPrintUtils::INDEX_ZERO], &valuetype), napi_invalid_arg);
194         PRINT_ASSERT_BASE(env, valuetype == napi_string, "printerId is not a string", napi_string_expected);
195 
196         PRINT_CALL_BASE(env, napi_typeof(env, argv[1], &valuetype), napi_invalid_arg);
197         PRINT_ASSERT_BASE(env, valuetype == napi_number, "printerStateis not a number", napi_number_expected);
198 
199         std::string printerId = NapiPrintUtils::GetStringFromValueUtf8(env, argv[NapiPrintUtils::INDEX_ZERO]);
200         PRINT_HILOGD("printerId : %{public}s", printerId.c_str());
201 
202         uint32_t printerState = NapiPrintUtils::GetUint32FromValue(env, argv[1]);
203         PRINT_HILOGD("printerState : %{public}d", printerState);
204 
205         if (printerId == "" || !IsValidPrinterState(printerState)) {
206             PRINT_HILOGE("invalid printer id or printer state");
207             context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
208             return napi_invalid_arg;
209         }
210 
211         context->printerId = printerId;
212         PRINT_HILOGD("context->printerId : %{private}s", context->printerId.c_str());
213         context->printerState = printerState;
214         return napi_ok;
215     };
216     auto output = [context](napi_env env, napi_value *result) -> napi_status {
217         napi_status status = napi_get_boolean(env, context->result, result);
218         PRINT_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status);
219         return status;
220     };
221     auto exec = [context](PrintAsyncCall::Context *ctx) {
222         if (!NapiPrintUtils::CheckCallerIsSystemApp()) {
223             PRINT_HILOGE("Non-system applications use system APIS!");
224             context->result = false;
225             context->SetErrorIndex(E_PRINT_ILLEGAL_USE_OF_SYSTEM_API);
226             return;
227         }
228         int32_t ret = PrintManagerClient::GetInstance()->UpdatePrinterState(context->printerId, context->printerState);
229         context->result = ret == E_PRINT_NONE;
230         if (ret != E_PRINT_NONE) {
231             PRINT_HILOGE("Failed to update state of printer");
232             context->SetErrorIndex(ret);
233         }
234     };
235     context->SetAction(std::move(input), std::move(output));
236     PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
237     return asyncCall.Call(env, exec);
238 }
239 
UpdatePrintJobStateOnlyForSystemApp(napi_env env,napi_callback_info info)240 napi_value NapiPrintExt::UpdatePrintJobStateOnlyForSystemApp(napi_env env, napi_callback_info info)
241 {
242     auto context = std::make_shared<NapiPrintExtContext>();
243     auto input = [context](
244             napi_env env, size_t argc, napi_value *argv, napi_value self, napi_callback_info info) -> napi_status {
245         PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_THREE, " should 3 parameter!", napi_invalid_arg);
246         napi_valuetype valuetype;
247         PRINT_CALL_BASE(env, napi_typeof(env, argv[NapiPrintUtils::INDEX_ZERO], &valuetype), napi_invalid_arg);
248         PRINT_ASSERT_BASE(env, valuetype == napi_string, "printJobId is not a string", napi_string_expected);
249         PRINT_CALL_BASE(env, napi_typeof(env, argv[1], &valuetype), napi_invalid_arg);
250         PRINT_ASSERT_BASE(env, valuetype == napi_number, "printJobState is not a number", napi_number_expected);
251         PRINT_CALL_BASE(env, napi_typeof(env, argv[NapiPrintUtils::INDEX_TWO], &valuetype), napi_invalid_arg);
252         PRINT_ASSERT_BASE(env, valuetype == napi_number, "reason is not a number", napi_number_expected);
253         std::string printJobId = NapiPrintUtils::GetStringFromValueUtf8(env, argv[NapiPrintUtils::INDEX_ZERO]);
254         uint32_t printJobState = NapiPrintUtils::GetUint32FromValue(env, argv[1]);
255         uint32_t jobSubState = NapiPrintUtils::GetUint32FromValue(env, argv[NapiPrintUtils::INDEX_TWO]);
256         PRINT_HILOGD("printJobId : %{public}s, printerJobState : %{public}d", printJobId.c_str(), printJobState);
257         PRINT_HILOGD("jobSubState : %{public}d", jobSubState);
258         if (printJobId == "" || !IsValidPrintJobState(printJobState) || !IsValidPrintJobSubState(jobSubState)) {
259             PRINT_HILOGE("invalid job id, job state or job substate");
260             context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
261             return napi_invalid_arg;
262         }
263         context->printJobId = printJobId;
264         context->printJobState = printJobState;
265         context->jobSubState = jobSubState;
266         return napi_ok;
267     };
268     auto output = [context](napi_env env, napi_value *result) -> napi_status {
269         napi_status status = napi_get_boolean(env, context->result, result);
270         return status;
271     };
272     auto exec = [context](PrintAsyncCall::Context *ctx) {
273         if (!NapiPrintUtils::CheckCallerIsSystemApp()) {
274             PRINT_HILOGE("Non-system applications use system APIS!");
275             context->result = false;
276             context->SetErrorIndex(E_PRINT_ILLEGAL_USE_OF_SYSTEM_API);
277             return;
278         }
279         int32_t ret = PrintManagerClient::GetInstance()->UpdatePrintJobStateOnlyForSystemApp(context->printJobId,
280             context->printJobState, context->jobSubState);
281         context->result = ret == E_PRINT_NONE;
282         if (ret != E_PRINT_NONE) {
283             PRINT_HILOGE("Failed to update state of print job");
284             context->SetErrorIndex(ret);
285         }
286     };
287     context->SetAction(std::move(input), std::move(output));
288     PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
289     return asyncCall.Call(env, exec);
290 }
291 
UpdateExtensionInfo(napi_env env,napi_callback_info info)292 napi_value NapiPrintExt::UpdateExtensionInfo(napi_env env, napi_callback_info info)
293 {
294     PRINT_HILOGD("Enter ---->");
295     auto context = std::make_shared<NapiPrintExtContext>();
296     auto input =
297         [context](
298             napi_env env, size_t argc, napi_value *argv, napi_value self, napi_callback_info info) -> napi_status {
299         PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_ONE, " should 1 parameter!", napi_invalid_arg);
300         napi_valuetype valuetype;
301         PRINT_CALL_BASE(env, napi_typeof(env, argv[NapiPrintUtils::INDEX_ZERO], &valuetype), napi_invalid_arg);
302         PRINT_ASSERT_BASE(env, valuetype == napi_string, "extInfo is not a string", napi_string_expected);
303 
304         std::string extInfo = NapiPrintUtils::GetStringFromValueUtf8(env, argv[0]);
305         PRINT_HILOGD("extInfo : %{public}s", extInfo.c_str());
306 
307         if (extInfo == "") {
308             PRINT_HILOGE("invalid extension id or extension information");
309             context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
310             return napi_invalid_arg;
311         }
312         context->extInfo = extInfo;
313         return napi_ok;
314     };
315     auto output = [context](napi_env env, napi_value *result) -> napi_status {
316         napi_status status = napi_get_boolean(env, context->result, result);
317         PRINT_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status);
318         return status;
319     };
320     auto exec = [context](PrintAsyncCall::Context *ctx) {
321         if (!NapiPrintUtils::CheckCallerIsSystemApp()) {
322             PRINT_HILOGE("Non-system applications use system APIS!");
323             context->result = false;
324             context->SetErrorIndex(E_PRINT_ILLEGAL_USE_OF_SYSTEM_API);
325             return;
326         }
327         int32_t ret = PrintManagerClient::GetInstance()->UpdateExtensionInfo(context->extInfo);
328         context->result = ret == E_PRINT_NONE;
329         if (ret != E_PRINT_NONE) {
330             PRINT_HILOGE("Failed to update extension information");
331             context->SetErrorIndex(ret);
332         }
333     };
334     context->SetAction(std::move(input), std::move(output));
335     PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
336     return asyncCall.Call(env, exec);
337 }
338 
AddPrinterToCups(napi_env env,napi_callback_info info)339 napi_value NapiPrintExt::AddPrinterToCups(napi_env env, napi_callback_info info)
340 {
341     PRINT_HILOGD("Enter AddPrinterToCups---->");
342     auto context = std::make_shared<NapiPrintExtContext>();
343     auto input =
344         [context](
345             napi_env env, size_t argc, napi_value *argv, napi_value self, napi_callback_info info) -> napi_status {
346         PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_THREE, " should 3 parameter!", napi_invalid_arg);
347         napi_valuetype valuetype;
348         PRINT_CALL_BASE(env, napi_typeof(env, argv[NapiPrintUtils::INDEX_ZERO], &valuetype), napi_invalid_arg);
349         PRINT_ASSERT_BASE(env, valuetype == napi_string, "printerUri is not a string", napi_string_expected);
350 
351         PRINT_CALL_BASE(env, napi_typeof(env, argv[NapiPrintUtils::INDEX_ONE], &valuetype), napi_invalid_arg);
352         PRINT_ASSERT_BASE(env, valuetype == napi_string, "printerName is not a string", napi_string_expected);
353 
354         std::string printerUri = NapiPrintUtils::GetStringFromValueUtf8(env, argv[NapiPrintUtils::INDEX_ZERO]);
355         PRINT_HILOGD("printerUri : %{private}s", printerUri.c_str());
356         context->printerUri = printerUri;
357 
358         std::string printerName = NapiPrintUtils::GetStringFromValueUtf8(env, argv[NapiPrintUtils::INDEX_ONE]);
359         PRINT_HILOGD("printerName : %{private}s", printerName.c_str());
360         context->printerName = printerName;
361 
362         PRINT_CALL_BASE(env, napi_typeof(env, argv[NapiPrintUtils::INDEX_TWO], &valuetype), napi_invalid_arg);
363         PRINT_ASSERT_BASE(env, valuetype == napi_string, "printerMake is not a string", napi_string_expected);
364         std::string printerMake = NapiPrintUtils::GetStringFromValueUtf8(env, argv[NapiPrintUtils::INDEX_TWO]);
365         PRINT_HILOGD("printerMake : %{private}s", printerMake.c_str());
366         context->printerMake = printerMake;
367         return napi_ok;
368     };
369     auto output = [context](napi_env env, napi_value *result) -> napi_status {
370         napi_status status = napi_get_boolean(env, context->result, result);
371         PRINT_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status);
372         return status;
373     };
374     auto exec = [context](PrintAsyncCall::Context *ctx) {
375         int32_t ret = PrintManagerClient::GetInstance()->AddPrinterToCups(context->printerUri, context->printerName,
376             context->printerMake);
377         PRINT_HILOGD("ret: %{public}d", ret);
378         context->result = (ret == E_PRINT_NONE);
379         if (ret != E_PRINT_NONE) {
380             PRINT_HILOGE("Failed to set cups printer");
381             context->SetErrorIndex(ret);
382         }
383     };
384     context->SetAction(std::move(input), std::move(output));
385     PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
386     return asyncCall.Call(env, exec);
387 }
388 
QueryPrinterCapabilityByUri(napi_env env,napi_callback_info info)389 napi_value NapiPrintExt::QueryPrinterCapabilityByUri(napi_env env, napi_callback_info info)
390 {
391     PRINT_HILOGD("Enter QueryPrinterCapabilityByUri---->");
392     auto context = std::make_shared<NapiPrintExtContext>();
393     auto input =
394         [context](
395             napi_env env, size_t argc, napi_value *argv, napi_value self, napi_callback_info info) -> napi_status {
396         PRINT_ASSERT_BASE(env,
397             argc == NapiPrintUtils::ARGC_ONE || argc == NapiPrintUtils::ARGC_TWO,
398             " should 1 or 2 parameter!",
399             napi_invalid_arg);
400 
401         napi_valuetype valuetype;
402         PRINT_CALL_BASE(env, napi_typeof(env, argv[NapiPrintUtils::INDEX_ZERO], &valuetype), napi_invalid_arg);
403         PRINT_ASSERT_BASE(env, valuetype == napi_string, "printerUri is not a string", napi_string_expected);
404 
405         std::string printerUri = NapiPrintUtils::GetStringFromValueUtf8(env, argv[NapiPrintUtils::INDEX_ZERO]);
406         PRINT_HILOGD("printerUri : %{private}s", printerUri.c_str());
407         context->printerUri = printerUri;
408 
409         if (argc == NapiPrintUtils::ARGC_TWO) {
410             PRINT_CALL_BASE(env, napi_typeof(env, argv[NapiPrintUtils::INDEX_ONE], &valuetype), napi_invalid_arg);
411             PRINT_ASSERT_BASE(env, valuetype == napi_string, "printerId is not a string", napi_string_expected);
412 
413             std::string printerId = NapiPrintUtils::GetStringFromValueUtf8(env, argv[NapiPrintUtils::INDEX_ONE]);
414             PRINT_HILOGD("printerId : %{private}s", printerId.c_str());
415             context->printerId = printerId;
416         }
417         return napi_ok;
418     };
419     // promise return
420     auto output = [context](napi_env env, napi_value *result) -> napi_status {
421         PRINT_HILOGD("output enter ---->");
422         *result = PrinterCapabilityHelper::MakeJsObject(env, context->printerCaps);
423         return napi_ok;
424     };
425 
426     auto exec = [context](PrintAsyncCall::Context *ctx) {
427         int32_t ret = PrintManagerClient::GetInstance()->QueryPrinterCapabilityByUri(context->printerUri,
428             context->printerId, context->printerCaps);
429         context->result = (ret == E_PRINT_NONE);
430         PRINT_HILOGD("ret: %d", ret);
431         if (ret != E_PRINT_NONE) {
432             PRINT_HILOGE("Failed to get printers caps");
433             context->SetErrorIndex(ret);
434         }
435     };
436     context->SetAction(std::move(input), std::move(output));
437     PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
438     return asyncCall.Call(env, exec);
439 }
440 
DeletePrinterFromCups(napi_env env,napi_callback_info info)441 napi_value NapiPrintExt::DeletePrinterFromCups(napi_env env, napi_callback_info info)
442 {
443     PRINT_HILOGD("Enter DeletePrinterFromCups---->");
444     auto context = std::make_shared<NapiPrintExtContext>();
445     auto input =
446         [context](
447             napi_env env, size_t argc, napi_value *argv, napi_value self, napi_callback_info info) -> napi_status {
448         PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_ONE, " should 1 parameter!", napi_invalid_arg);
449         napi_valuetype valuetype;
450 
451         PRINT_CALL_BASE(env, napi_typeof(env, argv[NapiPrintUtils::INDEX_ZERO], &valuetype), napi_invalid_arg);
452         PRINT_ASSERT_BASE(env, valuetype == napi_string, "printerName is not a string", napi_string_expected);
453 
454         std::string printerName = NapiPrintUtils::GetStringFromValueUtf8(env, argv[NapiPrintUtils::INDEX_ZERO]);
455         PRINT_HILOGD("printerName : %{private}s", printerName.c_str());
456         context->printerName = printerName;
457 
458         return napi_ok;
459     };
460     auto output = [context](napi_env env, napi_value *result) -> napi_status {
461         napi_status status = napi_get_boolean(env, context->result, result);
462         PRINT_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status);
463         return status;
464     };
465     auto exec = [context](PrintAsyncCall::Context *ctx) {
466         int32_t ret =
467             PrintManagerClient::GetInstance()->DeletePrinterFromCups(context->printerName);
468         PRINT_HILOGD("ret: %d", ret);
469         context->result = (ret == E_PRINT_NONE);
470         if (ret != E_PRINT_NONE) {
471             PRINT_HILOGE("Failed to delete cups printer");
472             context->SetErrorIndex(ret);
473         }
474     };
475     context->SetAction(std::move(input), std::move(output));
476     PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
477     return asyncCall.Call(env, exec);
478 }
479 
DiscoverUsbPrinters(napi_env env,napi_callback_info info)480 napi_value NapiPrintExt::DiscoverUsbPrinters(napi_env env, napi_callback_info info)
481 {
482     PRINT_HILOGD("Enter DiscoverUsbPrinters---->");
483     auto context = std::make_shared<NapiPrintExtContext>();
484     auto input =
485         [context](
486             napi_env env, size_t argc, napi_value *argv, napi_value self, napi_callback_info info) -> napi_status {
487         PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_ZERO, " should 0 parameter!", napi_invalid_arg);
488         return napi_ok;
489     };
490     auto output = [context](napi_env env, napi_value *result) -> napi_status {
491         PRINT_HILOGD("ouput enter---->");
492         napi_status status = napi_create_array(env, result);
493         uint32_t index = 0;
494         for (auto info : context->printerInfos) {
495             PRINT_HILOGD("PrinterId = %{public}s", info.GetPrinterId().c_str());
496             PRINT_HILOGD("PrinterName = %{private}s", info.GetPrinterName().c_str());
497             status = napi_set_element(env, *result, index++, PrinterInfoHelper::MakeJsObject(env, info));
498         }
499         return napi_ok;
500     };
501     auto exec = [context](PrintAsyncCall::Context *ctx) {
502         int32_t ret = PrintManagerClient::GetInstance()->DiscoverUsbPrinters(context->printerInfos);
503         context->result = (ret == E_PRINT_NONE);
504         if (ret != E_PRINT_NONE) {
505             PRINT_HILOGE("Failed to discover usb printers");
506             context->SetErrorIndex(ret);
507         }
508     };
509     context->SetAction(std::move(input), std::move(output));
510     PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
511     return asyncCall.Call(env, exec);
512 }
513 
AddPrinterToDiscovery(napi_env env,napi_callback_info info)514 napi_value NapiPrintExt::AddPrinterToDiscovery(napi_env env, napi_callback_info info)
515 {
516     PRINT_HILOGD("Enter AddPrinterToDiscovery---->");
517     auto context = std::make_shared<NapiPrintExtContext>();
518 
519     auto input =
520         [context](
521             napi_env env, size_t argc, napi_value* argv, napi_value self, napi_callback_info info) -> napi_status {
522         PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_ONE, " should have 1 parameter!", napi_invalid_arg);
523         napi_valuetype valuetype;
524         napi_typeof(env, argv[NapiPrintUtils::INDEX_ZERO], &valuetype);
525         PRINT_ASSERT_BASE(env, valuetype == napi_object, " parameter is not an object!", napi_invalid_arg);
526 
527         auto printerInfoPtr = PrinterInfoHelper::BuildFromJs(env, argv[NapiPrintUtils::INDEX_ZERO]);
528         if (printerInfoPtr == nullptr) {
529             context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
530             PRINT_HILOGE("PrinterInfo format error!");
531             return napi_invalid_arg;
532         }
533 
534         context->printerInfos.emplace_back(*printerInfoPtr);
535         PRINT_HILOGD("printerInfoPtr->GetPrinterId() = %{public}s", printerInfoPtr->GetPrinterId().c_str());
536 
537         return napi_ok;
538     };
539 
540     auto output = [context](napi_env env, napi_value *result) -> napi_status {
541         napi_status status = napi_get_boolean(env, context->result, result);
542         PRINT_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status);
543         return status;
544     };
545 
546     auto exec = [context](PrintAsyncCall::Context *ctx) {
547         if (context->printerInfos.empty()) {
548             context->result = false;
549             PRINT_HILOGE("printerInfos is empty!");
550             return;
551         }
552         int32_t ret = PrintManagerClient::GetInstance()->AddPrinterToDiscovery(context->printerInfos.front());
553         context->result = ret == E_PRINT_NONE;
554         if (ret != E_PRINT_NONE) {
555             PRINT_HILOGE("Failed to add printer");
556             context->SetErrorIndex(ret);
557         }
558     };
559 
560     context->SetAction(std::move(input), std::move(output));
561     PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
562     return asyncCall.Call(env, exec);
563 }
564 
UpdatePrinterInDiscovery(napi_env env,napi_callback_info info)565 napi_value NapiPrintExt::UpdatePrinterInDiscovery(napi_env env, napi_callback_info info)
566 {
567     PRINT_HILOGD("Enter UpdatePrinterInDiscovery---->");
568     auto context = std::make_shared<NapiPrintExtContext>();
569 
570     auto input =
571         [context](
572             napi_env env, size_t argc, napi_value* argv, napi_value self, napi_callback_info info) -> napi_status {
573         PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_ONE, " should have 1 parameter!", napi_invalid_arg);
574         napi_valuetype valuetype;
575         napi_typeof(env, argv[NapiPrintUtils::INDEX_ZERO], &valuetype);
576         PRINT_ASSERT_BASE(env, valuetype == napi_object, " parameter is not an object!", napi_invalid_arg);
577 
578         auto printerInfoPtr = PrinterInfoHelper::BuildFromJs(env, argv[NapiPrintUtils::INDEX_ZERO]);
579         if (printerInfoPtr == nullptr) {
580             context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
581             PRINT_HILOGE("PrinterInfo format error!");
582             return napi_invalid_arg;
583         }
584 
585         context->printerInfos.emplace_back(*printerInfoPtr);
586         PRINT_HILOGD("printerInfoPtr->GetPrinterId() = %{public}s", printerInfoPtr->GetPrinterId().c_str());
587 
588         return napi_ok;
589     };
590 
591     auto output = [context](napi_env env, napi_value *result) -> napi_status {
592         napi_status status = napi_get_boolean(env, context->result, result);
593         PRINT_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status);
594         return status;
595     };
596 
597     auto exec = [context](PrintAsyncCall::Context *ctx) {
598         if (context->printerInfos.empty()) {
599             context->result = false;
600             PRINT_HILOGE("printerInfos is empty!");
601             return;
602         }
603         int32_t ret = PrintManagerClient::GetInstance()->UpdatePrinterInDiscovery(context->printerInfos.front());
604         context->result = ret == E_PRINT_NONE;
605         if (ret != E_PRINT_NONE) {
606             PRINT_HILOGE("Failed to update printer");
607         }
608     };
609 
610     context->SetAction(std::move(input), std::move(output));
611     PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
612     return asyncCall.Call(env, exec);
613 }
614 
RemovePrinterFromDiscovery(napi_env env,napi_callback_info info)615 napi_value NapiPrintExt::RemovePrinterFromDiscovery(napi_env env, napi_callback_info info)
616 {
617     PRINT_HILOGD("Enter RemovePrinterFromDiscovery---->");
618     auto context = std::make_shared<NapiPrintExtContext>();
619 
620     auto input =
621         [context](
622             napi_env env, size_t argc, napi_value* argv, napi_value self, napi_callback_info info) -> napi_status {
623         PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_ONE, " should have 1 parameter!", napi_invalid_arg);
624         napi_valuetype valuetype;
625         PRINT_CALL_BASE(env, napi_typeof(env, argv[NapiPrintUtils::INDEX_ZERO], &valuetype), napi_invalid_arg);
626         PRINT_ASSERT_BASE(env, valuetype == napi_string, "printerId is not a string", napi_string_expected);
627 
628         std::string printerId = NapiPrintUtils::GetStringFromValueUtf8(env, argv[NapiPrintUtils::INDEX_ZERO]);
629         PRINT_HILOGD("printerId : %{private}s", printerId.c_str());
630         context->printerId = printerId;
631 
632         return napi_ok;
633     };
634 
635     auto output = [context](napi_env env, napi_value *result) -> napi_status {
636         napi_status status = napi_get_boolean(env, context->result, result);
637         PRINT_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status);
638         return status;
639     };
640 
641     auto exec = [context](PrintAsyncCall::Context *ctx) {
642         int32_t ret = PrintManagerClient::GetInstance()->RemovePrinterFromDiscovery(context->printerId);
643         context->result = ret == E_PRINT_NONE;
644         if (ret != E_PRINT_NONE) {
645             PRINT_HILOGE("Failed to add printer");
646             context->SetErrorIndex(ret);
647         }
648     };
649 
650     context->SetAction(std::move(input), std::move(output));
651     PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
652     return asyncCall.Call(env, exec);
653 }
654 
UpdatePrinterInSystem(napi_env env,napi_callback_info info)655 napi_value NapiPrintExt::UpdatePrinterInSystem(napi_env env, napi_callback_info info)
656 {
657     PRINT_HILOGD("Enter UpdatePrinterInSystem---->");
658     auto context = std::make_shared<NapiPrintExtContext>();
659 
660     auto input =
661         [context](
662             napi_env env, size_t argc, napi_value* argv, napi_value self, napi_callback_info info) -> napi_status {
663         PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_ONE, " should have 1 parameter!", napi_invalid_arg);
664         napi_valuetype valuetype;
665         napi_typeof(env, argv[NapiPrintUtils::INDEX_ZERO], &valuetype);
666         PRINT_ASSERT_BASE(env, valuetype == napi_object, " parameter is not an object!", napi_invalid_arg);
667 
668         auto printerInfoPtr = PrinterInfoHelper::BuildFromJs(env, argv[NapiPrintUtils::INDEX_ZERO]);
669         if (printerInfoPtr == nullptr) {
670             context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
671             PRINT_HILOGE("UpdatePrinterInSystem PrinterInfo format error!");
672             return napi_invalid_arg;
673         }
674 
675         context->printerInfos.emplace_back(*printerInfoPtr);
676         PRINT_HILOGD("UpdatePrinterInSystem printerId = %{public}s", printerInfoPtr->GetPrinterId().c_str());
677 
678         return napi_ok;
679     };
680 
681     auto output = [context](napi_env env, napi_value *result) -> napi_status {
682         napi_status status = napi_get_boolean(env, context->result, result);
683         PRINT_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status);
684         return status;
685     };
686 
687     auto exec = [context](PrintAsyncCall::Context *ctx) {
688         if (context->printerInfos.empty()) {
689             context->result = false;
690             PRINT_HILOGE("UpdatePrinterInSystem printerInfos is empty!");
691             return;
692         }
693         int32_t ret = PrintManagerClient::GetInstance()->UpdatePrinterInSystem(context->printerInfos.front());
694         context->result = ret == E_PRINT_NONE;
695         if (ret != E_PRINT_NONE) {
696             PRINT_HILOGE("UpdatePrinterInSystem Failed to update printer");
697         }
698     };
699 
700     context->SetAction(std::move(input), std::move(output));
701     PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
702     return asyncCall.Call(env, exec);
703 }
704 
IsValidPrinterState(uint32_t state)705 bool NapiPrintExt::IsValidPrinterState(uint32_t state)
706 {
707     if (state >= PRINTER_ADDED && state < PRINTER_UNKNOWN) {
708         return true;
709     }
710     return false;
711 }
712 
IsValidPrintJobState(uint32_t state)713 bool NapiPrintExt::IsValidPrintJobState(uint32_t state)
714 {
715     if (state >= PRINT_JOB_PREPARED && state <= PRINT_JOB_UNKNOWN) {
716         return true;
717     }
718     return false;
719 }
720 
IsValidPrintJobSubState(uint32_t subState)721 bool NapiPrintExt::IsValidPrintJobSubState(uint32_t subState)
722 {
723     if (subState >= PRINT_JOB_COMPLETED_SUCCESS && subState <= PRINT_JOB_BLOCKED_UNKNOWN) {
724         return true;
725     }
726     return false;
727 }
728 
NapiThrowError(napi_env env,const int32_t errCode)729 void NapiPrintExt::NapiThrowError(napi_env env, const int32_t errCode)
730 {
731     napi_value result = nullptr;
732     napi_create_error(env, NapiPrintUtils::CreateInt32(env, errCode),
733         NapiPrintUtils::CreateStringUtf8(env, NapiPrintUtils::GetPrintErrorMsg(errCode)), &result);
734     napi_throw(env, result);
735 }
736 }  // namespace OHOS::Print
737