1 /*
2 * Copyright (c) 2024 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 <securec.h>
17 #include "vendor_helper.h"
18 #include "print_service_converter.h"
19 #include "print_log.h"
20
21 namespace {
22 const std::string VENDOR_MANAGER_PREFIX = "fwk.";
23 const std::string GLOBAL_ID_DELIMITER = ":";
24 const uint32_t ORIENTATION_OFFSET = 3;
25 const int NUMBER_BASE = 10;
26 const size_t MAX_STRING_COUNT = 1000;
27 }
28
29 namespace OHOS::Print {
30
CopyString(const std::string & source)31 char *CopyString(const std::string &source)
32 {
33 auto len = source.length();
34 char *dest = new (std::nothrow) char[len + 1];
35 if (dest == nullptr) {
36 PRINT_HILOGW("allocate failed");
37 return nullptr;
38 }
39 if (strcpy_s(dest, len + 1, source.c_str()) != 0) {
40 PRINT_HILOGW("CopyString strcpy_s failed");
41 }
42 dest[len] = '\0';
43 return dest;
44 }
45
46 template <typename T1, typename T2>
ConvertArrayToList(const T1 * array,uint32_t count,std::vector<T2> & list,bool (* convertType)(const T1 &,T2 &))47 bool ConvertArrayToList(const T1 *array, uint32_t count, std::vector<T2> &list, bool (*convertType)(const T1 &, T2 &))
48 {
49 if (convertType == nullptr) {
50 PRINT_HILOGW("convertType is null");
51 return false;
52 }
53 if (count == 0) {
54 return true;
55 }
56 if (array == nullptr) {
57 PRINT_HILOGW("array is null");
58 return false;
59 }
60 for (uint32_t i = 0; i < count; ++i) {
61 T2 data;
62 if (convertType(array[i], data)) {
63 if (std::find(list.begin(), list.end(), data) != list.end()) {
64 PRINT_HILOGW("ignore the same item");
65 continue;
66 }
67 list.push_back(data);
68 }
69 }
70 return true;
71 }
72
73 template <typename T>
ConvertArrayToJson(const T * array,uint32_t count,bool (* convertToJson)(const T &,nlohmann::json &))74 std::string ConvertArrayToJson(const T *array, uint32_t count, bool (*convertToJson)(const T &, nlohmann::json &))
75 {
76 if (array == nullptr || convertToJson == nullptr) {
77 PRINT_HILOGW("invalid params");
78 return "";
79 }
80 std::vector<T> list;
81 for (uint32_t i = 0; i < count; ++i) {
82 AddToUniqueList<T>(list, array[i]);
83 }
84 return ConvertListToJson<T>(list, convertToJson);
85 }
86
ConvertJsonToStringList(const std::string & jsonString,std::vector<std::string> & list)87 bool ConvertJsonToStringList(const std::string &jsonString, std::vector<std::string> &list)
88 {
89 if (!nlohmann::json::accept(jsonString)) {
90 PRINT_HILOGW("invalid jsonString");
91 return false;
92 }
93 nlohmann::json jsonObject = nlohmann::json::parse(jsonString, nullptr, false);
94 if (jsonObject.is_discarded()) {
95 PRINT_HILOGW("jsonString discarded");
96 return false;
97 }
98 if (!jsonObject.is_array()) {
99 PRINT_HILOGW("jsonObject is not array");
100 return false;
101 }
102 for (auto &element : jsonObject.items()) {
103 nlohmann::json object = element.value();
104 if (object.is_string()) {
105 list.push_back(object.get<std::string>());
106 }
107 }
108 return true;
109 }
110
GetStringValueFromJson(const nlohmann::json & jsonObject,const std::string & key)111 std::string GetStringValueFromJson(const nlohmann::json &jsonObject, const std::string &key)
112 {
113 if (!jsonObject.contains(key) || !jsonObject[key].is_string()) {
114 PRINT_HILOGW("can not find %{public}s", key.c_str());
115 return "";
116 }
117 return jsonObject[key].get<std::string>();
118 }
119
ConvertStringToLong(const char * src,long & dst)120 bool ConvertStringToLong(const char *src, long &dst)
121 {
122 if (src == nullptr) {
123 return false;
124 }
125 errno = 0;
126 char *endPtr = nullptr;
127 dst = strtol(src, &endPtr, NUMBER_BASE);
128 if (errno == ERANGE || endPtr == src) {
129 PRINT_HILOGW("ConvertStringToLong fail: %{public}s", src);
130 return false;
131 }
132 return true;
133 }
134
ConvertColorMode(const Print_ColorMode & code,uint32_t & dst)135 bool ConvertColorMode(const Print_ColorMode &code, uint32_t &dst)
136 {
137 dst = static_cast<uint32_t>(code);
138 if (dst > static_cast<uint32_t>(COLOR_MODE_AUTO)) {
139 return false;
140 }
141 return true;
142 }
ConvertColorModeToJson(const Print_ColorMode & code,nlohmann::json & jsonObject)143 bool ConvertColorModeToJson(const Print_ColorMode &code, nlohmann::json &jsonObject)
144 {
145 jsonObject["color"] = std::to_string(static_cast<int>(code));
146 return true;
147 }
148
ConvertDuplexMode(const Print_DuplexMode & code,uint32_t & dst)149 bool ConvertDuplexMode(const Print_DuplexMode &code, uint32_t &dst)
150 {
151 dst = static_cast<uint32_t>(code);
152 if (dst > static_cast<uint32_t>(DUPLEX_MODE_TWO_SIDED_SHORT_EDGE)) {
153 return false;
154 }
155 return true;
156 }
ConvertDuplexModeToJson(const Print_DuplexMode & code,nlohmann::json & jsonObject)157 bool ConvertDuplexModeToJson(const Print_DuplexMode &code, nlohmann::json &jsonObject)
158 {
159 jsonObject["duplex"] = std::to_string(static_cast<int>(code));
160 return true;
161 }
162
ConvertQuality(const Print_Quality & code,uint32_t & dst)163 bool ConvertQuality(const Print_Quality &code, uint32_t &dst)
164 {
165 dst = static_cast<uint32_t>(code);
166 if (dst < static_cast<uint32_t>(PRINT_QUALITY_DRAFT) || dst > static_cast<uint32_t>(PRINT_QUALITY_HIGH)) {
167 return false;
168 }
169 return true;
170 }
ConvertQualityToJson(const Print_Quality & code,nlohmann::json & jsonObject)171 bool ConvertQualityToJson(const Print_Quality &code, nlohmann::json &jsonObject)
172 {
173 jsonObject["quality"] = std::to_string(static_cast<int>(code));
174 return true;
175 }
176
ConvertStringToPrinterState(const std::string & stateData,Print_PrinterState & state)177 bool ConvertStringToPrinterState(const std::string &stateData, Print_PrinterState &state)
178 {
179 long result = 0;
180 if (!nlohmann::json::accept(stateData)) {
181 PRINT_HILOGW("invalid stateData");
182 return false;
183 }
184 nlohmann::json jsonObject = nlohmann::json::parse(stateData, nullptr, false);
185 if (jsonObject.is_discarded()) {
186 PRINT_HILOGW("stateData discarded");
187 return false;
188 }
189 std::string stateValue = GetStringValueFromJson(jsonObject, "state");
190 if (!ConvertStringToLong(stateValue.c_str(), result)) {
191 return false;
192 }
193 std::string reasonValue = GetStringValueFromJson(jsonObject, "reason");
194 if (reasonValue == "shutdown") {
195 PRINT_HILOGD("printer shutdown");
196 state = PRINTER_UNAVAILABLE;
197 return true;
198 }
199 if (result < 0 || result > PRINTER_UNAVAILABLE + 1) {
200 PRINT_HILOGW("invalid state");
201 return false;
202 }
203 if (result == PRINTER_UNAVAILABLE + 1) {
204 state = PRINTER_UNAVAILABLE;
205 } else if (result == 1) {
206 state = PRINTER_BUSY;
207 } else {
208 state = PRINTER_IDLE;
209 }
210 return true;
211 }
212
LogDiscoveryItem(const Print_DiscoveryItem * discoveryItem)213 void LogDiscoveryItem(const Print_DiscoveryItem *discoveryItem)
214 {
215 if (discoveryItem == nullptr) {
216 PRINT_HILOGW("discoveryItem is null");
217 return;
218 }
219 if (discoveryItem->printerId != nullptr) {
220 PRINT_HILOGD("printerId: %{public}s", discoveryItem->printerId);
221 } else {
222 PRINT_HILOGW("printerId is null");
223 }
224 if (discoveryItem->printerName != nullptr) {
225 PRINT_HILOGD("printerName: %{public}s", discoveryItem->printerName);
226 } else {
227 PRINT_HILOGW("printerName is null");
228 }
229 if (discoveryItem->description != nullptr) {
230 PRINT_HILOGD("description: %{public}s", discoveryItem->description);
231 }
232 if (discoveryItem->location != nullptr) {
233 PRINT_HILOGD("location: %{public}s", discoveryItem->location);
234 }
235 if (discoveryItem->makeAndModel != nullptr) {
236 PRINT_HILOGD("makeAndModel: %{public}s", discoveryItem->makeAndModel);
237 } else {
238 PRINT_HILOGW("makeAndModel is null");
239 }
240 if (discoveryItem->printerUri != nullptr) {
241 PRINT_HILOGD("printerUri: %{public}s", discoveryItem->printerUri);
242 } else {
243 PRINT_HILOGW("printerUri is null");
244 }
245 if (discoveryItem->printerUuid != nullptr) {
246 PRINT_HILOGD("printerUuid: %{public}s", discoveryItem->printerUuid);
247 }
248 }
249
LogPageCapability(const Print_PrinterCapability * capability)250 void LogPageCapability(const Print_PrinterCapability *capability)
251 {
252 if (capability == nullptr) {
253 PRINT_HILOGW("capability is null");
254 return;
255 }
256 if (capability->supportedPageSizes != nullptr && capability->supportedPageSizesCount > 0) {
257 for (uint32_t i = 0; i < capability->supportedPageSizesCount; ++i) {
258 if (capability->supportedPageSizes[i].id != nullptr) {
259 PRINT_HILOGD("page id = %{public}s", capability->supportedPageSizes[i].id);
260 }
261 if (capability->supportedPageSizes[i].name != nullptr) {
262 PRINT_HILOGD("page name = %{public}s", capability->supportedPageSizes[i].name);
263 }
264 PRINT_HILOGD("page size = %{public}u x %{public}u", capability->supportedPageSizes[i].width,
265 capability->supportedPageSizes[i].height);
266 }
267 }
268 if (capability->supportedMediaTypes != nullptr) {
269 PRINT_HILOGD("media types = %{public}s", capability->supportedMediaTypes);
270 }
271 if (capability->supportedPaperSources != nullptr) {
272 PRINT_HILOGD("Paper Sources = %{public}s", capability->supportedPaperSources);
273 }
274 }
275
LogOtherCapability(const Print_PrinterCapability * capability)276 void LogOtherCapability(const Print_PrinterCapability *capability)
277 {
278 if (capability == nullptr) {
279 PRINT_HILOGW("capability is null");
280 return;
281 }
282 if (capability->supportedColorModes != nullptr && capability->supportedColorModesCount > 0) {
283 for (uint32_t i = 0; i < capability->supportedColorModesCount; ++i) {
284 PRINT_HILOGD("color mode = %{public}u", static_cast<uint32_t>(capability->supportedColorModes[i]));
285 }
286 }
287 if (capability->supportedDuplexModes != nullptr && capability->supportedDuplexModesCount > 0) {
288 for (uint32_t i = 0; i < capability->supportedDuplexModesCount; ++i) {
289 PRINT_HILOGD("duplex mode = %{public}u", static_cast<uint32_t>(capability->supportedDuplexModes[i]));
290 }
291 }
292 if (capability->supportedQualities != nullptr && capability->supportedQualitiesCount > 0) {
293 for (uint32_t i = 0; i < capability->supportedQualitiesCount; ++i) {
294 PRINT_HILOGD("quality mode = %{public}u", static_cast<uint32_t>(capability->supportedQualities[i]));
295 }
296 }
297 PRINT_HILOGD("copy count = %{public}u", capability->supportedCopies);
298 if (capability->supportedResolutions != nullptr && capability->supportedResolutionsCount > 0) {
299 for (uint32_t i = 0; i < capability->supportedResolutionsCount; ++i) {
300 PRINT_HILOGD("dpi = %{public}u x %{public}u", capability->supportedResolutions[i].horizontalDpi,
301 capability->supportedResolutions[i].verticalDpi);
302 }
303 }
304 if (capability->supportedOrientations != nullptr && capability->supportedOrientationsCount > 0) {
305 for (uint32_t i = 0; i < capability->supportedOrientationsCount; ++i) {
306 PRINT_HILOGD("Orientation = %{public}u", static_cast<uint32_t>(capability->supportedOrientations[i]));
307 }
308 }
309 if (capability->advancedCapability != nullptr) {
310 PRINT_HILOGD("advancedCapability = %{public}s", capability->advancedCapability);
311 }
312 }
313
LogDefaultValue(const Print_DefaultValue * defaultValue)314 void LogDefaultValue(const Print_DefaultValue *defaultValue)
315 {
316 if (defaultValue == nullptr) {
317 PRINT_HILOGW("defaultValue is null");
318 return;
319 }
320 PRINT_HILOGD("default color mode = %{public}u", static_cast<uint32_t>(defaultValue->defaultColorMode));
321 PRINT_HILOGD("default duplex mode = %{public}u", static_cast<uint32_t>(defaultValue->defaultDuplexMode));
322 if (defaultValue->defaultMediaType != nullptr) {
323 PRINT_HILOGD("defaultMediaType = %{public}s", defaultValue->defaultMediaType);
324 }
325 if (defaultValue->defaultPageSizeId != nullptr) {
326 PRINT_HILOGD("defaultPageSizeId = %{public}s", defaultValue->defaultPageSizeId);
327 }
328 PRINT_HILOGD("defaultMargin = [%{public}u, %{public}u, %{public}u, %{public}u]",
329 defaultValue->defaultMargin.leftMargin, defaultValue->defaultMargin.topMargin,
330 defaultValue->defaultMargin.rightMargin, defaultValue->defaultMargin.bottomMargin);
331 if (defaultValue->defaultPaperSource != nullptr) {
332 PRINT_HILOGD("defaultPaperSource = %{public}s", defaultValue->defaultPaperSource);
333 }
334 PRINT_HILOGD("defaultPrintQuality = %{public}u", static_cast<uint32_t>(defaultValue->defaultPrintQuality));
335 PRINT_HILOGD("defaultCopies = %{public}u", defaultValue->defaultCopies);
336 PRINT_HILOGD("defaultResolution = %{public}u x %{public}u", defaultValue->defaultResolution.horizontalDpi,
337 defaultValue->defaultResolution.verticalDpi);
338 PRINT_HILOGD("defaultOrientation = %{public}u", static_cast<uint32_t>(defaultValue->defaultOrientation));
339 if (defaultValue->otherDefaultValues != nullptr) {
340 PRINT_HILOGD("otherDefaultValues = %{public}s", defaultValue->otherDefaultValues);
341 }
342 }
343
LogProperties(const Print_PropertyList * propertyList)344 void LogProperties(const Print_PropertyList *propertyList)
345 {
346 if (propertyList == nullptr) {
347 PRINT_HILOGW("propertyList is null");
348 return;
349 }
350 if (propertyList->count == 0 || propertyList->list == nullptr) {
351 PRINT_HILOGW("propertyList empty");
352 return;
353 }
354 for (uint32_t i = 0; i < propertyList->count; ++i) {
355 if (propertyList->list[i].key == nullptr) {
356 PRINT_HILOGW("propertyList item empty: %{public}u", i);
357 continue;
358 }
359 PRINT_HILOGD("LogProperties key: %{public}s", propertyList->list[i].key);
360 if (propertyList->list[i].value == nullptr) {
361 PRINT_HILOGW("propertyList value empty: %{public}u", i);
362 continue;
363 }
364 PRINT_HILOGD("LogProperties value: %{public}s", propertyList->list[i].value);
365 }
366 }
367
FindPropertyFromPropertyList(const Print_PropertyList * propertyList,const std::string & keyName)368 std::string FindPropertyFromPropertyList(const Print_PropertyList *propertyList, const std::string &keyName)
369 {
370 if (propertyList == nullptr) {
371 PRINT_HILOGW("propertyList is null");
372 return "";
373 }
374 if (propertyList->count == 0 || propertyList->list == nullptr) {
375 PRINT_HILOGW("propertyList empty");
376 return "";
377 }
378 for (uint32_t i = 0; i < propertyList->count; ++i) {
379 if (propertyList->list[i].key == nullptr) {
380 PRINT_HILOGW("propertyList key empty: %{public}u", i);
381 continue;
382 }
383 PRINT_HILOGD("FindPropertyFromPropertyList key: %{public}s", propertyList->list[i].key);
384 if (strcmp(keyName.c_str(), propertyList->list[i].key) != 0) {
385 continue;
386 }
387 if (propertyList->list[i].value == nullptr) {
388 PRINT_HILOGW("propertyList value empty, key: %{public}s", keyName.c_str());
389 break;
390 }
391 PRINT_HILOGD("FindPropertyFromPropertyList value: %{public}s", propertyList->list[i].value);
392 return std::string(propertyList->list[i].value);
393 }
394 return "";
395 }
UpdatePrinterInfoWithDiscovery(PrinterInfo & info,const Print_DiscoveryItem * discoveryItem)396 bool UpdatePrinterInfoWithDiscovery(PrinterInfo &info, const Print_DiscoveryItem *discoveryItem)
397 {
398 if (discoveryItem == nullptr) {
399 PRINT_HILOGW("discoveryItem is null");
400 return false;
401 }
402 if (discoveryItem->printerId == nullptr || discoveryItem->printerName == nullptr) {
403 PRINT_HILOGW("invalid discoveryItem");
404 return false;
405 }
406 info.SetPrinterId(std::string(discoveryItem->printerId));
407 std::string name(discoveryItem->printerName);
408 info.SetPrinterName(name);
409 if (discoveryItem->description != nullptr) {
410 info.SetDescription(std::string(discoveryItem->description));
411 }
412 if (discoveryItem->printerUri != nullptr) {
413 info.SetUri(std::string(discoveryItem->printerUri));
414 }
415 if (discoveryItem->makeAndModel != nullptr) {
416 info.SetPrinterMake(std::string(discoveryItem->makeAndModel));
417 }
418 if (discoveryItem->printerUri != nullptr && discoveryItem->makeAndModel != nullptr) {
419 PRINT_HILOGD("printerUri: %{public}s", discoveryItem->printerUri);
420 nlohmann::json option;
421 option["printerName"] = name;
422 option["printerUri"] = std::string(discoveryItem->printerUri);
423 option["make"] = std::string(discoveryItem->makeAndModel);
424 if (discoveryItem->printerUuid != nullptr) {
425 option["printer-uuid"] = std::string(discoveryItem->printerUuid);
426 }
427 if (discoveryItem->detailInfo != nullptr && nlohmann::json::accept(std::string(discoveryItem->detailInfo))) {
428 nlohmann::json detailInfo = nlohmann::json::parse(std::string(discoveryItem->detailInfo));
429 if (!detailInfo.is_null() && detailInfo.contains("bsunidriver_support") &&
430 detailInfo["bsunidriver_support"].is_string()) {
431 option["bsunidriverSupport"] = detailInfo["bsunidriver_support"].get<std::string>();
432 }
433 }
434 info.SetOption(option.dump());
435 }
436 return true;
437 }
438
AddUniquePageSize(std::vector<PrintPageSize> & pageSizeList,const PrintPageSize & printPageSize)439 void AddUniquePageSize(std::vector<PrintPageSize> &pageSizeList, const PrintPageSize &printPageSize)
440 {
441 for (auto const &item : pageSizeList) {
442 if (item.GetId() == printPageSize.GetId()) {
443 return;
444 }
445 }
446 pageSizeList.push_back(printPageSize);
447 }
448
UpdateDefaultPageSizeId(PrinterCapability & printerCap,const std::string & defaultPageId,const std::string & pageId,const Print_PageSize & page)449 bool UpdateDefaultPageSizeId(PrinterCapability &printerCap, const std::string &defaultPageId, const std::string &pageId,
450 const Print_PageSize &page)
451 {
452 if (page.id != nullptr && defaultPageId == std::string(page.id)) {
453 printerCap.SetPrinterAttrNameAndValue("defaultPageSizeId", pageId.c_str());
454 return true;
455 }
456 return false;
457 }
458
UpdatePageSizeCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)459 bool UpdatePageSizeCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability,
460 const Print_DefaultValue *defaultValue)
461 {
462 if (capability == nullptr || capability->supportedPageSizes == nullptr) {
463 PRINT_HILOGW("supportedPageSizes is null");
464 return false;
465 }
466 std::string defaultPageId;
467 if (defaultValue != nullptr && defaultValue->defaultPageSizeId != nullptr) {
468 defaultPageId = defaultValue->defaultPageSizeId;
469 }
470 std::vector<PrintPageSize> pageSizeList;
471 for (uint32_t i = 0; i < capability->supportedPageSizesCount; ++i) {
472 PrintPageSize printPageSize;
473 if (capability->supportedPageSizes[i].name != nullptr) {
474 std::string pageSizeName(capability->supportedPageSizes[i].name);
475 PAGE_SIZE_ID id = PrintPageSize::MatchPageSize(pageSizeName);
476 if (!id.empty() && PrintPageSize::FindPageSizeById(id, printPageSize)) {
477 AddUniquePageSize(pageSizeList, printPageSize);
478 UpdateDefaultPageSizeId(printerCap, defaultPageId, id, capability->supportedPageSizes[i]);
479 PRINT_HILOGD("page size matched = %{public}s", id.c_str());
480 continue;
481 }
482 }
483 if (capability->supportedPageSizes[i].id != nullptr) {
484 PAGE_SIZE_ID id = std::string(capability->supportedPageSizes[i].id);
485 if (!id.empty() && PrintPageSize::FindPageSizeById(id, printPageSize)) {
486 AddUniquePageSize(pageSizeList, printPageSize);
487 UpdateDefaultPageSizeId(printerCap, defaultPageId, id, capability->supportedPageSizes[i]);
488 PRINT_HILOGD("page size matched = %{public}s", id.c_str());
489 continue;
490 }
491 }
492 PRINT_HILOGD("page size = %{public}u x %{public}u", capability->supportedPageSizes[i].width,
493 capability->supportedPageSizes[i].height);
494 }
495 printerCap.SetSupportedPageSize(pageSizeList);
496 return true;
497 }
498
UpdateQualityCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability)499 bool UpdateQualityCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability)
500 {
501 if (capability == nullptr || capability->supportedQualities == nullptr) {
502 PRINT_HILOGW("supportedQualities is null");
503 return false;
504 }
505 std::vector<uint32_t> supportedQualityList;
506 if (ConvertArrayToList<Print_Quality, uint32_t>(capability->supportedQualities,
507 capability->supportedQualitiesCount, supportedQualityList, ConvertQuality)) {
508 printerCap.SetSupportedQuality(supportedQualityList);
509 }
510 std::string supportedQualities = ConvertArrayToJson<Print_Quality>(
511 capability->supportedQualities, capability->supportedQualitiesCount, ConvertQualityToJson);
512 PRINT_HILOGD("quality: %{public}s", supportedQualities.c_str());
513 if (!supportedQualities.empty()) {
514 printerCap.SetPrinterAttrNameAndValue("print-quality-supported", supportedQualities.c_str());
515 }
516 return true;
517 }
518
UpdateColorCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability)519 bool UpdateColorCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability)
520 {
521 if (capability == nullptr || capability->supportedColorModes == nullptr) {
522 PRINT_HILOGW("supportedColorModes is null");
523 return false;
524 }
525 std::vector<uint32_t> supportedColorModes;
526 if (ConvertArrayToList<Print_ColorMode, uint32_t>(capability->supportedColorModes,
527 capability->supportedColorModesCount, supportedColorModes, ConvertColorMode)) {
528 printerCap.SetSupportedColorMode(supportedColorModes);
529 }
530 std::string colorModeJson = ConvertArrayToJson<Print_ColorMode>(
531 capability->supportedColorModes, capability->supportedColorModesCount, ConvertColorModeToJson);
532 if (!colorModeJson.empty()) {
533 printerCap.SetPrinterAttrNameAndValue("print-color-mode-supported", colorModeJson.c_str());
534 }
535 for (uint32_t i = 0; i < capability->supportedColorModesCount; ++i) {
536 if (capability->supportedColorModes[i] == Print_ColorMode::COLOR_MODE_COLOR) {
537 printerCap.SetColorMode(ColorModeCode::COLOR_MODE_COLOR);
538 break;
539 }
540 }
541 return true;
542 }
543
UpdateDuplexCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability)544 bool UpdateDuplexCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability)
545 {
546 if (capability == nullptr || capability->supportedDuplexModes == nullptr) {
547 PRINT_HILOGW("supportedDuplexModes is null");
548 return false;
549 }
550 std::vector<uint32_t> supportedDuplexModes;
551 if (ConvertArrayToList<Print_DuplexMode, uint32_t>(capability->supportedDuplexModes,
552 capability->supportedDuplexModesCount, supportedDuplexModes, ConvertDuplexMode)) {
553 printerCap.SetSupportedDuplexMode(supportedDuplexModes);
554 }
555 std::string duplexModeJson = ConvertArrayToJson<Print_DuplexMode>(
556 capability->supportedDuplexModes, capability->supportedDuplexModesCount, ConvertDuplexModeToJson);
557 if (!duplexModeJson.empty()) {
558 printerCap.SetPrinterAttrNameAndValue("sides-supported", duplexModeJson.c_str());
559 }
560 if (capability->supportedDuplexModesCount > 1) {
561 printerCap.SetDuplexMode(static_cast<uint32_t>(Print_DuplexMode::DUPLEX_MODE_TWO_SIDED_LONG_EDGE));
562 }
563 return true;
564 }
UpdateResolutionCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability)565 bool UpdateResolutionCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability)
566 {
567 if (capability == nullptr || capability->supportedResolutions == nullptr) {
568 PRINT_HILOGW("supportedResolutions is null");
569 return false;
570 }
571 std::vector<PrintResolution> resolutionList;
572 nlohmann::json resolutionArray = nlohmann::json::array();
573 for (uint32_t i = 0; i < capability->supportedResolutionsCount; ++i) {
574 PrintResolution printResolution;
575 uint32_t xRes = capability->supportedResolutions[i].horizontalDpi;
576 uint32_t yRes = capability->supportedResolutions[i].verticalDpi;
577 printResolution.SetHorizontalDpi(xRes);
578 printResolution.SetVerticalDpi(yRes);
579 PRINT_HILOGD("resolution = %{public}u x %{public}u", xRes, yRes);
580 resolutionList.push_back(printResolution);
581 nlohmann::json object;
582 object["horizontalDpi"] = xRes;
583 object["verticalDpi"] = yRes;
584 resolutionArray.push_back(object);
585 }
586 printerCap.SetResolution(resolutionList);
587 printerCap.SetPrinterAttrNameAndValue("printer-resolution-supported", resolutionArray.dump().c_str());
588 return true;
589 }
590
UpdateResolutionDefaultValue(PrinterCapability & printerCap,const Print_DefaultValue * defaultValue)591 bool UpdateResolutionDefaultValue(PrinterCapability &printerCap, const Print_DefaultValue *defaultValue)
592 {
593 if (defaultValue == nullptr) {
594 PRINT_HILOGW("defaultValue is null");
595 return false;
596 }
597 nlohmann::json object;
598 object["horizontalDpi"] = defaultValue->defaultResolution.horizontalDpi;
599 object["verticalDpi"] = defaultValue->defaultResolution.verticalDpi;
600 printerCap.SetPrinterAttrNameAndValue("printer-resolution-default", object.dump().c_str());
601 return true;
602 }
603
UpdateCopiesCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)604 bool UpdateCopiesCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability,
605 const Print_DefaultValue *defaultValue)
606 {
607 if (capability == nullptr || defaultValue == nullptr) {
608 PRINT_HILOGW("capability or defaultValue is null");
609 return false;
610 }
611 printerCap.SetPrinterAttrNameAndValue("copies-supported", std::to_string(capability->supportedCopies).c_str());
612 printerCap.SetPrinterAttrNameAndValue("copies-default", std::to_string(defaultValue->defaultCopies).c_str());
613 return true;
614 }
615
UpdateOrientationCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)616 bool UpdateOrientationCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability,
617 const Print_DefaultValue *defaultValue)
618 {
619 if (capability == nullptr || defaultValue == nullptr) {
620 PRINT_HILOGW("capability or defaultValue is null");
621 return false;
622 }
623 printerCap.SetPrinterAttrNameAndValue("orientation-requested-default",
624 std::to_string(defaultValue->defaultOrientation).c_str());
625 if (capability->supportedOrientations != nullptr) {
626 nlohmann::json supportedOrientationArray = nlohmann::json::array();
627 std::vector<uint32_t> supportedOrientations;
628 for (uint32_t i = 0; i < capability->supportedOrientationsCount; ++i) {
629 int orientationEnum = static_cast<int>(capability->supportedOrientations[i]) + ORIENTATION_OFFSET;
630 supportedOrientationArray.push_back(orientationEnum);
631 supportedOrientations.push_back(static_cast<uint32_t>(orientationEnum));
632 }
633 printerCap.SetSupportedOrientation(supportedOrientations);
634 printerCap.SetPrinterAttrNameAndValue("orientation-requested-supported",
635 supportedOrientationArray.dump().c_str());
636 }
637 return true;
638 }
639
UpdateMediaCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)640 bool UpdateMediaCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability,
641 const Print_DefaultValue *defaultValue)
642 {
643 if (capability == nullptr || defaultValue == nullptr) {
644 PRINT_HILOGW("capability or defaultValue is null");
645 return false;
646 }
647 if (capability->supportedMediaTypes != nullptr) {
648 printerCap.SetPrinterAttrNameAndValue("media-type-supported", capability->supportedMediaTypes);
649 std::string mdiaTypeJson(capability->supportedMediaTypes);
650 std::vector<std::string> mediaTypeList;
651 if (ConvertJsonToStringList(mdiaTypeJson, mediaTypeList)) {
652 printerCap.SetSupportedMediaType(mediaTypeList);
653 } else {
654 PRINT_HILOGW("invalid media types");
655 }
656 }
657 if (defaultValue->defaultMediaType != nullptr) {
658 printerCap.SetPrinterAttrNameAndValue("media-type-default", defaultValue->defaultMediaType);
659 }
660 if (capability->supportedPaperSources != nullptr) {
661 printerCap.SetPrinterAttrNameAndValue("media-source-supported", capability->supportedPaperSources);
662 }
663 if (defaultValue->defaultPaperSource != nullptr) {
664 printerCap.SetPrinterAttrNameAndValue("media-source-default", defaultValue->defaultPaperSource);
665 }
666 return true;
667 }
UpdateMarginCapability(PrinterCapability & printerCap,const Print_DefaultValue * defaultValue)668 bool UpdateMarginCapability(PrinterCapability &printerCap, const Print_DefaultValue *defaultValue)
669 {
670 if (defaultValue == nullptr) {
671 PRINT_HILOGW("defaultValue is null");
672 return false;
673 }
674 PrintMargin printMargin;
675 printMargin.SetLeft(defaultValue->defaultMargin.leftMargin);
676 printMargin.SetTop(defaultValue->defaultMargin.topMargin);
677 printMargin.SetRight(defaultValue->defaultMargin.rightMargin);
678 printMargin.SetBottom(defaultValue->defaultMargin.bottomMargin);
679 PRINT_HILOGD("margin left = %{public}u, top = %{public}u, right = %{public}u, bottom = %{public}u",
680 defaultValue->defaultMargin.leftMargin, defaultValue->defaultMargin.topMargin,
681 defaultValue->defaultMargin.rightMargin, defaultValue->defaultMargin.bottomMargin);
682 printerCap.SetMinMargin(printMargin);
683 return true;
684 }
UpdatePrinterCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)685 bool UpdatePrinterCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability,
686 const Print_DefaultValue *defaultValue)
687 {
688 if (capability == nullptr || defaultValue == nullptr) {
689 PRINT_HILOGW("capability or defaultValue is null");
690 return false;
691 }
692 if (!UpdatePageSizeCapability(printerCap, capability, defaultValue)) {
693 return false;
694 }
695 UpdateColorCapability(printerCap, capability);
696 uint32_t defaultColorMode = static_cast<uint32_t>(defaultValue->defaultColorMode);
697 printerCap.SetPrinterAttrNameAndValue("defaultColorMode", std::to_string(defaultColorMode).c_str());
698 UpdateDuplexCapability(printerCap, capability);
699 uint32_t defaultDuplexMode = static_cast<uint32_t>(defaultValue->defaultDuplexMode);
700 printerCap.SetPrinterAttrNameAndValue("sides-default", std::to_string(defaultDuplexMode).c_str());
701 UpdateQualityCapability(printerCap, capability);
702 UpdateResolutionCapability(printerCap, capability);
703 UpdateResolutionDefaultValue(printerCap, defaultValue);
704 UpdateCopiesCapability(printerCap, capability, defaultValue);
705 UpdateOrientationCapability(printerCap, capability, defaultValue);
706 UpdateMediaCapability(printerCap, capability, defaultValue);
707 UpdateMarginCapability(printerCap, defaultValue);
708 return true;
709 }
710
UpdatePrinterInfoWithCapability(PrinterInfo & info,const Print_DiscoveryItem * discoveryItem,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)711 bool UpdatePrinterInfoWithCapability(PrinterInfo &info, const Print_DiscoveryItem *discoveryItem,
712 const Print_PrinterCapability *capability, const Print_DefaultValue *defaultValue)
713 {
714 PrinterCapability printerCap;
715 if (!UpdatePrinterCapability(printerCap, capability, defaultValue)) {
716 PRINT_HILOGW("update capability fail");
717 return false;
718 }
719 nlohmann::json options;
720 if (discoveryItem != nullptr) {
721 if (discoveryItem->makeAndModel != nullptr) {
722 options["make"] = std::string(discoveryItem->makeAndModel);
723 }
724 if (discoveryItem->printerName != nullptr) {
725 options["printerName"] = info.GetPrinterName();
726 }
727 if (discoveryItem->printerUuid != nullptr) {
728 options["printer-uuid"] = std::string(discoveryItem->printerUuid);
729 }
730 }
731 nlohmann::json cupsOptionsJson = printerCap.GetPrinterAttrGroupJson();
732 options["cupsOptions"] = cupsOptionsJson;
733 std::string optionStr = options.dump();
734 PRINT_HILOGD("SetOption: %{public}s", optionStr.c_str());
735 printerCap.SetOption(optionStr);
736 info.SetCapability(printerCap);
737 info.Dump();
738 return true;
739 }
740
ConvertVendorCapabilityToPrinterInfo(const Print_DiscoveryItem * printer,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)741 std::shared_ptr<PrinterInfo> ConvertVendorCapabilityToPrinterInfo(const Print_DiscoveryItem *printer,
742 const Print_PrinterCapability *capability,
743 const Print_DefaultValue *defaultValue)
744 {
745 if (printer == nullptr || printer->printerId == nullptr) {
746 PRINT_HILOGW("printer null");
747 return nullptr;
748 }
749 std::shared_ptr<PrinterInfo> info = std::make_shared<PrinterInfo>();
750 if (info == nullptr) {
751 return nullptr;
752 }
753 if (!UpdatePrinterInfoWithDiscovery(*info, printer)) {
754 PRINT_HILOGW("update printer info fail");
755 return nullptr;
756 }
757 UpdatePrinterInfoWithCapability(*info, printer, capability, defaultValue);
758 return info;
759 }
760
ConvertStringVectorToStringList(const std::vector<std::string> & stringVector,Print_StringList & stringList)761 bool ConvertStringVectorToStringList(const std::vector<std::string> &stringVector, Print_StringList &stringList)
762 {
763 size_t count = stringVector.size();
764 if (count == 0 || count > MAX_STRING_COUNT) {
765 return false;
766 }
767 stringList.count = 0;
768 stringList.list = new (std::nothrow) char *[count];
769 if (stringList.list == nullptr) {
770 PRINT_HILOGW("stringList list allocate fail");
771 return false;
772 }
773 if (memset_s(stringList.list, count * sizeof(char *), 0, count * sizeof(char *)) != 0) {
774 PRINT_HILOGW("memset_s fail");
775 delete[] stringList.list;
776 stringList.list = nullptr;
777 return false;
778 }
779 for (auto const &key : stringVector) {
780 stringList.list[stringList.count] = CopyString(key);
781 stringList.count++;
782 }
783 return true;
784 }
785
ReleaseStringList(Print_StringList & stringList)786 void ReleaseStringList(Print_StringList &stringList)
787 {
788 if (stringList.list != nullptr) {
789 for (uint32_t i = 0; i < stringList.count; i++) {
790 if (stringList.list[i] != nullptr) {
791 delete[] stringList.list[i];
792 stringList.list[i] = nullptr;
793 }
794 }
795 delete[] stringList.list;
796 stringList.list = nullptr;
797 }
798 stringList.count = 0;
799 }
800 }
801