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 PRINT_HILOGD("Enter ---->");
28 auto context = std::make_shared<NapiPrintExtContext>();
29 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> 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
35 uint32_t len = 0;
36 napi_get_array_length(env, argv[NapiPrintUtils::INDEX_ZERO], &len);
37
38 for (uint32_t index = 0; index < len; index++) {
39 napi_value value;
40 napi_get_element(env, argv[NapiPrintUtils::INDEX_ZERO], index, &value);
41 auto printerInfoPtr = PrinterInfoHelper::BuildFromJs(env, value);
42 if (printerInfoPtr == nullptr) {
43 context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
44 PRINT_HILOGE("PrinterInfo format error!");
45 return napi_invalid_arg;
46 }
47 printerInfoPtr->SetPrinterId(printerInfoPtr->GetPrinterId());
48 PRINT_HILOGD("printerInfoPtr->GetPrinterId() = %{public}s", printerInfoPtr->GetPrinterId().c_str());
49 context->printerInfos.emplace_back(*printerInfoPtr);
50 }
51 if (context->printerInfos.empty()) {
52 context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
53 PRINT_HILOGE("no valid printer info exists!");
54 return napi_invalid_arg;
55 }
56 return napi_ok;
57 };
58 auto output = [context](napi_env env, napi_value *result) -> napi_status {
59 napi_status status = napi_get_boolean(env, context->result, result);
60 PRINT_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status);
61 return status;
62 };
63 auto exec = [context](PrintAsyncCall::Context *ctx) {
64 int32_t ret = PrintManagerClient::GetInstance()->AddPrinters(context->printerInfos);
65 context->result = ret == E_PRINT_NONE;
66 if (ret != E_PRINT_NONE) {
67 PRINT_HILOGE("Failed to add printers");
68 context->SetErrorIndex(ret);
69 }
70 };
71 context->SetAction(std::move(input), std::move(output));
72 PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
73 return asyncCall.Call(env, exec);
74 }
75
RemovePrinters(napi_env env,napi_callback_info info)76 napi_value NapiPrintExt::RemovePrinters(napi_env env, napi_callback_info info)
77 {
78 PRINT_HILOGD("Enter ---->");
79 auto context = std::make_shared<NapiPrintExtContext>();
80 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
81 PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_ONE, " should 1 parameter!", napi_invalid_arg);
82
83 bool isArray = false;
84 napi_is_array(env, argv[NapiPrintUtils::INDEX_ZERO], &isArray);
85 PRINT_ASSERT_BASE(env, isArray, " is not array!", napi_array_expected);
86
87 uint32_t len = 0;
88 napi_get_array_length(env, argv[NapiPrintUtils::INDEX_ZERO], &len);
89
90 for (uint32_t index = 0; index < len; index++) {
91 napi_value value;
92 napi_get_element(env, argv[NapiPrintUtils::INDEX_ZERO], index, &value);
93 std::string printerId = NapiPrintUtils::GetStringFromValueUtf8(env, value);
94 if (printerId != "") {
95 context->printerIds.emplace_back(printerId);
96 }
97 }
98 if (context->printerIds.empty()) {
99 context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
100 PRINT_HILOGE("no valid printer info exists!");
101 return napi_invalid_arg;
102 }
103 return napi_ok;
104 };
105 auto output = [context](napi_env env, napi_value *result) -> napi_status {
106 napi_status status = napi_get_boolean(env, context->result, result);
107 PRINT_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status);
108 return status;
109 };
110 auto exec = [context](PrintAsyncCall::Context *ctx) {
111 int32_t ret = PrintManagerClient::GetInstance()->RemovePrinters(context->printerIds);
112 context->result = ret == E_PRINT_NONE;
113 if (ret != E_PRINT_NONE) {
114 PRINT_HILOGE("Failed to remove printers");
115 context->SetErrorIndex(ret);
116 }
117 };
118 context->SetAction(std::move(input), std::move(output));
119 PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
120 return asyncCall.Call(env, exec);
121 }
122
UpdatePrinters(napi_env env,napi_callback_info info)123 napi_value NapiPrintExt::UpdatePrinters(napi_env env, napi_callback_info info)
124 {
125 PRINT_HILOGD("Enter ---->");
126 auto context = std::make_shared<NapiPrintExtContext>();
127 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
128 PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_ONE, " should 1 parameter!", napi_invalid_arg);
129 bool isArray = false;
130 napi_is_array(env, argv[NapiPrintUtils::INDEX_ZERO], &isArray);
131 PRINT_ASSERT_BASE(env, isArray, " is not array!", napi_array_expected);
132
133 uint32_t len = 0;
134 napi_get_array_length(env, argv[NapiPrintUtils::INDEX_ZERO], &len);
135
136 for (uint32_t index = 0; index < len; index++) {
137 napi_value value;
138 napi_get_element(env, argv[NapiPrintUtils::INDEX_ZERO], index, &value);
139 auto printerInfoPtr = PrinterInfoHelper::BuildFromJs(env, value);
140 if (printerInfoPtr == nullptr) {
141 context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
142 PRINT_HILOGE("PrinterInfo format error!");
143 return napi_invalid_arg;
144 }
145 context->printerInfos.emplace_back(*printerInfoPtr);
146 }
147 if (context->printerInfos.empty()) {
148 context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
149 PRINT_HILOGE("no valid printer info exists!");
150 return napi_invalid_arg;
151 }
152 return napi_ok;
153 };
154 auto output = [context](napi_env env, napi_value *result) -> napi_status {
155 napi_status status = napi_get_boolean(env, context->result, result);
156 PRINT_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status);
157 return status;
158 };
159 auto exec = [context](PrintAsyncCall::Context *ctx) {
160 int32_t ret = PrintManagerClient::GetInstance()->UpdatePrinters(context->printerInfos);
161 context->result = ret == E_PRINT_NONE;
162 if (ret != E_PRINT_NONE) {
163 PRINT_HILOGE("Failed to update printers");
164 context->SetErrorIndex(ret);
165 }
166 };
167 context->SetAction(std::move(input), std::move(output));
168 PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
169 return asyncCall.Call(env, exec);
170 }
171
UpdatePrinterState(napi_env env,napi_callback_info info)172 napi_value NapiPrintExt::UpdatePrinterState(napi_env env, napi_callback_info info)
173 {
174 PRINT_HILOGD("Enter ---->");
175 auto context = std::make_shared<NapiPrintExtContext>();
176 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
177 PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_TWO, " should 2 parameter!", napi_invalid_arg);
178 napi_valuetype valuetype;
179 PRINT_CALL_BASE(env, napi_typeof(env, argv[NapiPrintUtils::INDEX_ZERO], &valuetype), napi_invalid_arg);
180 PRINT_ASSERT_BASE(env, valuetype == napi_string, "printerId is not a string", napi_string_expected);
181
182 PRINT_CALL_BASE(env, napi_typeof(env, argv[1], &valuetype), napi_invalid_arg);
183 PRINT_ASSERT_BASE(env, valuetype == napi_number, "printerStateis not a number", napi_number_expected);
184
185 std::string printerId = NapiPrintUtils::GetStringFromValueUtf8(env, argv[NapiPrintUtils::INDEX_ZERO]);
186 PRINT_HILOGD("printerId : %{public}s", printerId.c_str());
187
188 uint32_t printerState = NapiPrintUtils::GetUint32FromValue(env, argv[1]);
189 PRINT_HILOGD("printerState : %{public}d", printerState);
190
191 if (printerId == "" || !IsValidPrinterState(printerState)) {
192 PRINT_HILOGE("invalid printer id or printer state");
193 context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
194 return napi_invalid_arg;
195 }
196
197 context->printerId = printerId;
198 PRINT_HILOGD("context->printerId : %{private}s", context->printerId.c_str());
199 context->printerState = printerState;
200 return napi_ok;
201 };
202 auto output = [context](napi_env env, napi_value *result) -> napi_status {
203 napi_status status = napi_get_boolean(env, context->result, result);
204 PRINT_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status);
205 return status;
206 };
207 auto exec = [context](PrintAsyncCall::Context *ctx) {
208 int32_t ret = PrintManagerClient::GetInstance()->UpdatePrinterState(context->printerId, context->printerState);
209 context->result = ret == E_PRINT_NONE;
210 if (ret != E_PRINT_NONE) {
211 PRINT_HILOGE("Failed to update state of printer");
212 context->SetErrorIndex(ret);
213 }
214 };
215 context->SetAction(std::move(input), std::move(output));
216 PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
217 return asyncCall.Call(env, exec);
218 }
219
UpdatePrintJobState(napi_env env,napi_callback_info info)220 napi_value NapiPrintExt::UpdatePrintJobState(napi_env env, napi_callback_info info)
221 {
222 PRINT_HILOGD("Enter ---->");
223 auto context = std::make_shared<NapiPrintExtContext>();
224 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
225 PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_THREE, " should 3 parameter!", napi_invalid_arg);
226 napi_valuetype valuetype;
227 PRINT_CALL_BASE(env, napi_typeof(env, argv[NapiPrintUtils::INDEX_ZERO], &valuetype), napi_invalid_arg);
228 PRINT_ASSERT_BASE(env, valuetype == napi_string, "printJobId is not a string", napi_string_expected);
229
230 PRINT_CALL_BASE(env, napi_typeof(env, argv[1], &valuetype), napi_invalid_arg);
231 PRINT_ASSERT_BASE(env, valuetype == napi_number, "printJobState is not a number", napi_number_expected);
232
233 PRINT_CALL_BASE(env, napi_typeof(env, argv[NapiPrintUtils::INDEX_TWO], &valuetype), napi_invalid_arg);
234 PRINT_ASSERT_BASE(env, valuetype == napi_number, "reason is not a number", napi_number_expected);
235
236 std::string printJobId = NapiPrintUtils::GetStringFromValueUtf8(env, argv[NapiPrintUtils::INDEX_ZERO]);
237 PRINT_HILOGD("printJobId : %{public}s", printJobId.c_str());
238
239 uint32_t printJobState = NapiPrintUtils::GetUint32FromValue(env, argv[1]);
240 PRINT_HILOGD("printerJobState : %{public}d", printJobState);
241
242 uint32_t jobSubState = NapiPrintUtils::GetUint32FromValue(env, argv[NapiPrintUtils::INDEX_TWO]);
243 PRINT_HILOGD("jobSubState : %{public}d", jobSubState);
244
245 if (printJobId == "" || !IsValidPrintJobState(printJobState) || !IsValidPrintJobSubState(jobSubState)) {
246 PRINT_HILOGE("invalid job id, job state or job substate");
247 context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
248 return napi_invalid_arg;
249 }
250
251 context->printJobId = printJobId;
252 context->printJobState = printJobState;
253 context->jobSubState = jobSubState;
254 return napi_ok;
255 };
256 auto output = [context](napi_env env, napi_value *result) -> napi_status {
257 napi_status status = napi_get_boolean(env, context->result, result);
258 PRINT_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status);
259 return status;
260 };
261 auto exec = [context](PrintAsyncCall::Context *ctx) {
262 int32_t ret = PrintManagerClient::GetInstance()->UpdatePrintJobState(context->printJobId,
263 context->printJobState, context->jobSubState);
264 context->result = ret == E_PRINT_NONE;
265 if (ret != E_PRINT_NONE) {
266 PRINT_HILOGE("Failed to update state of print job");
267 context->SetErrorIndex(ret);
268 }
269 };
270 context->SetAction(std::move(input), std::move(output));
271 PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
272 return asyncCall.Call(env, exec);
273 }
274
UpdateExtensionInfo(napi_env env,napi_callback_info info)275 napi_value NapiPrintExt::UpdateExtensionInfo(napi_env env, napi_callback_info info)
276 {
277 PRINT_HILOGD("Enter ---->");
278 auto context = std::make_shared<NapiPrintExtContext>();
279 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
280 PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_ONE, " should 1 parameter!", napi_invalid_arg);
281 napi_valuetype valuetype;
282 PRINT_CALL_BASE(env, napi_typeof(env, argv[NapiPrintUtils::INDEX_ZERO], &valuetype), napi_invalid_arg);
283 PRINT_ASSERT_BASE(env, valuetype == napi_string, "extInfo is not a string", napi_string_expected);
284
285 std::string extInfo = NapiPrintUtils::GetStringFromValueUtf8(env, argv[0]);
286 PRINT_HILOGD("extInfo : %{public}s", extInfo.c_str());
287
288 if (extInfo == "") {
289 PRINT_HILOGE("invalid extension id or extension information");
290 context->SetErrorIndex(E_PRINT_INVALID_PARAMETER);
291 return napi_invalid_arg;
292 }
293 context->extInfo = extInfo;
294 return napi_ok;
295 };
296 auto output = [context](napi_env env, napi_value *result) -> napi_status {
297 napi_status status = napi_get_boolean(env, context->result, result);
298 PRINT_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status);
299 return status;
300 };
301 auto exec = [context](PrintAsyncCall::Context *ctx) {
302 int32_t ret = PrintManagerClient::GetInstance()->UpdateExtensionInfo(context->extInfo);
303 context->result = ret == E_PRINT_NONE;
304 if (ret != E_PRINT_NONE) {
305 PRINT_HILOGE("Failed to update extension information");
306 context->SetErrorIndex(ret);
307 }
308 };
309 context->SetAction(std::move(input), std::move(output));
310 PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
311 return asyncCall.Call(env, exec);
312 }
313
AddPrinterToCups(napi_env env,napi_callback_info info)314 napi_value NapiPrintExt::AddPrinterToCups(napi_env env, napi_callback_info info)
315 {
316 PRINT_HILOGD("Enter AddPrinterToCups---->");
317 auto context = std::make_shared<NapiPrintExtContext>();
318 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
319 PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_TWO, " should 2 parameter!", napi_invalid_arg);
320
321 napi_valuetype valuetype;
322 PRINT_CALL_BASE(env, napi_typeof(env, argv[NapiPrintUtils::INDEX_ZERO], &valuetype), napi_invalid_arg);
323 PRINT_ASSERT_BASE(env, valuetype == napi_string, "printerUri is not a string", napi_string_expected);
324
325 PRINT_CALL_BASE(env, napi_typeof(env, argv[NapiPrintUtils::INDEX_ONE], &valuetype), napi_invalid_arg);
326 PRINT_ASSERT_BASE(env, valuetype == napi_string, "printerName is not a string", napi_string_expected);
327
328 std::string printerUri = NapiPrintUtils::GetStringFromValueUtf8(env, argv[NapiPrintUtils::INDEX_ZERO]);
329 PRINT_HILOGD("printerUri : %{private}s", printerUri.c_str());
330 context->printerUri = printerUri;
331
332 std::string printerName = NapiPrintUtils::GetStringFromValueUtf8(env, argv[NapiPrintUtils::INDEX_ONE]);
333 PRINT_HILOGD("printerName : %{private}s", printerName.c_str());
334 context->printerName = printerName;
335
336 return napi_ok;
337 };
338 auto output = [context](napi_env env, napi_value *result) -> napi_status {
339 napi_status status = napi_get_boolean(env, context->result, result);
340 PRINT_HILOGD("output ---- [%{public}s], status[%{public}d]", context->result ? "true" : "false", status);
341 return status;
342 };
343 auto exec = [context](PrintAsyncCall::Context *ctx) {
344 int32_t ret = PrintManagerClient::GetInstance()->AddPrinterToCups(context->printerUri, context->printerName);
345 PRINT_HILOGD("ret: %d", ret);
346 context->result = ret == E_PRINT_NONE;
347 if (ret != E_PRINT_NONE) {
348 PRINT_HILOGE("Failed to set cups printer");
349 context->SetErrorIndex(ret);
350 }
351 };
352 context->SetAction(std::move(input), std::move(output));
353 PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
354 return asyncCall.Call(env, exec);
355 }
356
QueryPrinterCapabilityByUri(napi_env env,napi_callback_info info)357 napi_value NapiPrintExt::QueryPrinterCapabilityByUri(napi_env env, napi_callback_info info)
358 {
359 PRINT_HILOGD("Enter QueryPrinterCapabilityByUri---->");
360 auto context = std::make_shared<NapiPrintExtContext>();
361 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
362 PRINT_ASSERT_BASE(env, argc == NapiPrintUtils::ARGC_ONE, " should 1 parameter!", napi_invalid_arg);
363
364 napi_valuetype valuetype;
365 PRINT_CALL_BASE(env, napi_typeof(env, argv[NapiPrintUtils::INDEX_ZERO], &valuetype), napi_invalid_arg);
366 PRINT_ASSERT_BASE(env, valuetype == napi_string, "printerUri is not a string", napi_string_expected);
367
368 std::string printerUri = NapiPrintUtils::GetStringFromValueUtf8(env, argv[NapiPrintUtils::INDEX_ZERO]);
369 PRINT_HILOGD("printerUri : %{private}s", printerUri.c_str());
370 context->printerUri = printerUri;
371 return napi_ok;
372 };
373 // promise return
374 auto output = [context](napi_env env, napi_value *result) -> napi_status {
375 PRINT_HILOGD("output enter ---->");
376 *result = PrinterCapabilityHelper::MakeJsObject(env, context->printerCaps);
377 return napi_ok;
378 };
379
380 auto exec = [context](PrintAsyncCall::Context *ctx) {
381 int32_t ret = PrintManagerClient::GetInstance()->QueryPrinterCapabilityByUri(context->printerUri,
382 context->printerCaps);
383 context->result = ret == E_PRINT_NONE;
384 PRINT_HILOGD("ret: %d", ret);
385 if (ret != E_PRINT_NONE) {
386 PRINT_HILOGE("Failed to get printers caps");
387 context->SetErrorIndex(ret);
388 }
389 };
390 context->SetAction(std::move(input), std::move(output));
391 PrintAsyncCall asyncCall(env, info, std::dynamic_pointer_cast<PrintAsyncCall::Context>(context));
392 return asyncCall.Call(env, exec);
393 }
394
IsValidPrinterState(uint32_t state)395 bool NapiPrintExt::IsValidPrinterState(uint32_t state)
396 {
397 if (state >= PRINTER_ADDED && state < PRINTER_UNKNOWN) {
398 return true;
399 }
400 return false;
401 }
402
IsValidPrintJobState(uint32_t state)403 bool NapiPrintExt::IsValidPrintJobState(uint32_t state)
404 {
405 if (state >= PRINT_JOB_PREPARED && state <= PRINT_JOB_UNKNOWN) {
406 return true;
407 }
408 return false;
409 }
410
IsValidPrintJobSubState(uint32_t subState)411 bool NapiPrintExt::IsValidPrintJobSubState(uint32_t subState)
412 {
413 if (subState >= PRINT_JOB_COMPLETED_SUCCESS && subState <= PRINT_JOB_BLOCKED_UNKNOWN) {
414 return true;
415 }
416 return false;
417 }
418 } // namespace OHOS::Print
419