• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <json/json.h>
21 #include "print_json_util.h"
22 
23 namespace {
24 const std::string VENDOR_MANAGER_PREFIX = "fwk.";
25 const std::string GLOBAL_ID_DELIMITER = ":";
26 const uint32_t ORIENTATION_OFFSET = 3;
27 const int NUMBER_BASE = 10;
28 const size_t MAX_STRING_COUNT = 1000;
29 const uint32_t MAX_MEDIA_TYPE_SIZE = 200;
30 }
31 
32 namespace OHOS::Print {
33 
CopyString(const std::string & source)34 char *CopyString(const std::string &source)
35 {
36     auto len = source.length();
37     char *dest = new (std::nothrow) char[len + 1];
38     if (dest == nullptr) {
39         PRINT_HILOGW("allocate failed");
40         return nullptr;
41     }
42     if (strcpy_s(dest, len + 1, source.c_str()) != 0) {
43         PRINT_HILOGW("CopyString strcpy_s failed");
44     }
45     dest[len] = '\0';
46     return dest;
47 }
48 
49 template <typename T1, typename T2>
ConvertArrayToList(const T1 * array,uint32_t count,std::vector<T2> & list,bool (* convertType)(const T1 &,T2 &))50 bool ConvertArrayToList(const T1 *array, uint32_t count, std::vector<T2> &list, bool (*convertType)(const T1 &, T2 &))
51 {
52     if (convertType == nullptr) {
53         PRINT_HILOGW("convertType is null");
54         return false;
55     }
56     if (count == 0) {
57         return true;
58     }
59     if (array == nullptr) {
60         PRINT_HILOGW("array is null");
61         return false;
62     }
63     for (uint32_t i = 0; i < count; ++i) {
64         T2 data;
65         if (convertType(array[i], data)) {
66             if (std::find(list.begin(), list.end(), data) != list.end()) {
67                 PRINT_HILOGW("ignore the same item");
68                 continue;
69             }
70             list.push_back(data);
71         }
72     }
73     return true;
74 }
75 
76 template <typename T>
ConvertArrayToJson(const T * array,uint32_t count,bool (* convertToJson)(const T &,Json::Value &))77 std::string ConvertArrayToJson(const T *array, uint32_t count, bool (*convertToJson)(const T &, Json::Value &))
78 {
79     if (array == nullptr || convertToJson == nullptr) {
80         PRINT_HILOGW("invalid params");
81         return "";
82     }
83     std::vector<T> list;
84     for (uint32_t i = 0; i < count; ++i) {
85         AddToUniqueList<T>(list, array[i]);
86     }
87     return ConvertListToJson<T>(list, convertToJson);
88 }
89 
ConvertJsonToStringList(const std::string & jsonString,std::vector<std::string> & list)90 bool ConvertJsonToStringList(const std::string &jsonString, std::vector<std::string> &list)
91 {
92     Json::Value jsonObject;
93     if (!PrintJsonUtil::Parse(jsonString, jsonObject)) {
94         PRINT_HILOGW("invalid jsonString");
95         return false;
96     }
97     if (!jsonObject.isArray()) {
98         PRINT_HILOGW("jsonObject is not array");
99         return false;
100     }
101     uint32_t jsonSize = jsonObject.size();
102     if (jsonSize > MAX_MEDIA_TYPE_SIZE) {
103         PRINT_HILOGE("jsonObject size is illegal.");
104         return false;
105     }
106     for (uint32_t i = 0; i < jsonSize; i++) {
107         if (jsonObject[i].isString()) {
108             list.push_back(jsonObject[i].asString());
109         }
110     }
111     return true;
112 }
113 
GetStringValueFromJson(const Json::Value & jsonObject,const std::string & key)114 std::string GetStringValueFromJson(const Json::Value &jsonObject, const std::string &key)
115 {
116     if (!PrintJsonUtil::IsMember(jsonObject, key) || !jsonObject[key].isString()) {
117         PRINT_HILOGW("can not find %{public}s", key.c_str());
118         return "";
119     }
120     return jsonObject[key].asString();
121 }
122 
ConvertStringToLong(const char * src,long & dst)123 bool ConvertStringToLong(const char *src, long &dst)
124 {
125     if (src == nullptr) {
126         return false;
127     }
128     errno = 0;
129     char *endPtr = nullptr;
130     dst = strtol(src, &endPtr, NUMBER_BASE);
131     if (errno == ERANGE || endPtr == src) {
132         PRINT_HILOGW("ConvertStringToLong fail: %{public}s", src);
133         return false;
134     }
135     return true;
136 }
137 
ConvertColorMode(const Print_ColorMode & code,uint32_t & dst)138 bool ConvertColorMode(const Print_ColorMode &code, uint32_t &dst)
139 {
140     dst = static_cast<uint32_t>(code);
141     if (dst > static_cast<uint32_t>(COLOR_MODE_AUTO)) {
142         return false;
143     }
144     return true;
145 }
ConvertColorModeToJson(const Print_ColorMode & code,Json::Value & jsonObject)146 bool ConvertColorModeToJson(const Print_ColorMode &code, Json::Value &jsonObject)
147 {
148     jsonObject["color"] = std::to_string(static_cast<int>(code));
149     return true;
150 }
151 
ConvertDuplexMode(const Print_DuplexMode & code,uint32_t & dst)152 bool ConvertDuplexMode(const Print_DuplexMode &code, uint32_t &dst)
153 {
154     dst = static_cast<uint32_t>(code);
155     if (dst > static_cast<uint32_t>(DUPLEX_MODE_TWO_SIDED_SHORT_EDGE)) {
156         return false;
157     }
158     return true;
159 }
ConvertDuplexModeToJson(const Print_DuplexMode & code,Json::Value & jsonObject)160 bool ConvertDuplexModeToJson(const Print_DuplexMode &code, Json::Value &jsonObject)
161 {
162     jsonObject["duplex"] = std::to_string(static_cast<int>(code));
163     return true;
164 }
165 
ConvertQuality(const Print_Quality & code,uint32_t & dst)166 bool ConvertQuality(const Print_Quality &code, uint32_t &dst)
167 {
168     dst = static_cast<uint32_t>(code);
169     if (dst < static_cast<uint32_t>(PRINT_QUALITY_DRAFT) || dst > static_cast<uint32_t>(PRINT_QUALITY_HIGH)) {
170         return false;
171     }
172     return true;
173 }
ConvertQualityToJson(const Print_Quality & code,Json::Value & jsonObject)174 bool ConvertQualityToJson(const Print_Quality &code, Json::Value &jsonObject)
175 {
176     jsonObject["quality"] = std::to_string(static_cast<int>(code));
177     return true;
178 }
179 
ConvertStringToPrinterState(const std::string & stateData,Print_PrinterState & state)180 bool ConvertStringToPrinterState(const std::string &stateData, Print_PrinterState &state)
181 {
182     long result = 0;
183     Json::Value jsonObject;
184     if (!PrintJsonUtil::Parse(stateData, jsonObject)) {
185         PRINT_HILOGW("invalid stateData");
186         return false;
187     }
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->printerUuid != nullptr) {
419         info.SetPrinterUuid(std::string(discoveryItem->printerUuid));
420     }
421     if (discoveryItem->printerUri != nullptr && discoveryItem->makeAndModel != nullptr) {
422         PRINT_HILOGD("printerUri: %{public}s", discoveryItem->printerUri);
423         Json::Value option;
424         option["printerName"] = name;
425         option["printerUri"] = std::string(discoveryItem->printerUri);
426         option["make"] = std::string(discoveryItem->makeAndModel);
427         if (discoveryItem->printerUuid != nullptr) {
428             option["printer-uuid"] = std::string(discoveryItem->printerUuid);
429         }
430         if (discoveryItem->detailInfo != nullptr) {
431             Json::Value detailInfo;
432             std::istringstream iss(std::string(discoveryItem->detailInfo));
433             if (PrintJsonUtil::ParseFromStream(iss, detailInfo) && !detailInfo.isNull()
434                 && PrintJsonUtil::IsMember(detailInfo, "bsunidriver_support") &&
435                 detailInfo["bsunidriver_support"].isString()) {
436                 option["bsunidriverSupport"] = detailInfo["bsunidriver_support"].asString();
437             }
438         } else {
439             PRINT_HILOGW("DetailInfo is null");
440         }
441         info.SetOption(PrintJsonUtil::WriteString(option));
442     }
443     return true;
444 }
445 
AddUniquePageSize(std::vector<PrintPageSize> & pageSizeList,const PrintPageSize & printPageSize)446 void AddUniquePageSize(std::vector<PrintPageSize> &pageSizeList, const PrintPageSize &printPageSize)
447 {
448     for (auto const &item : pageSizeList) {
449         if (item.GetId() == printPageSize.GetId()) {
450             return;
451         }
452     }
453     pageSizeList.push_back(printPageSize);
454 }
455 
UpdateDefaultPageSizeId(PrinterCapability & printerCap,const std::string & defaultPageId,const std::string & pageId,const Print_PageSize & page)456 bool UpdateDefaultPageSizeId(PrinterCapability &printerCap, const std::string &defaultPageId, const std::string &pageId,
457                              const Print_PageSize &page)
458 {
459     if (page.id != nullptr && defaultPageId == std::string(page.id)) {
460         printerCap.SetPrinterAttrNameAndValue("defaultPageSizeId", pageId.c_str());
461         return true;
462     }
463     return false;
464 }
465 
UpdatePageSizeCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)466 bool UpdatePageSizeCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability,
467                               const Print_DefaultValue *defaultValue)
468 {
469     if (capability == nullptr || capability->supportedPageSizes == nullptr) {
470         PRINT_HILOGW("supportedPageSizes is null");
471         return false;
472     }
473     std::string defaultPageId;
474     if (defaultValue != nullptr && defaultValue->defaultPageSizeId != nullptr) {
475         defaultPageId = defaultValue->defaultPageSizeId;
476     }
477     std::vector<PrintPageSize> pageSizeList;
478     for (uint32_t i = 0; i < capability->supportedPageSizesCount; ++i) {
479         PrintPageSize printPageSize;
480         if (capability->supportedPageSizes[i].name != nullptr) {
481             std::string pageSizeName(capability->supportedPageSizes[i].name);
482             PAGE_SIZE_ID id = PrintPageSize::MatchPageSize(pageSizeName);
483             if (!id.empty() && PrintPageSize::FindPageSizeById(id, printPageSize)) {
484                 AddUniquePageSize(pageSizeList, printPageSize);
485                 UpdateDefaultPageSizeId(printerCap, defaultPageId, id, capability->supportedPageSizes[i]);
486                 PRINT_HILOGD("page size matched = %{public}s", id.c_str());
487                 continue;
488             }
489         }
490         if (capability->supportedPageSizes[i].id != nullptr) {
491             PAGE_SIZE_ID id = std::string(capability->supportedPageSizes[i].id);
492             if (!id.empty() && PrintPageSize::FindPageSizeById(id, printPageSize)) {
493                 AddUniquePageSize(pageSizeList, printPageSize);
494                 UpdateDefaultPageSizeId(printerCap, defaultPageId, id, capability->supportedPageSizes[i]);
495                 PRINT_HILOGD("page size matched = %{public}s", id.c_str());
496                 continue;
497             }
498         }
499         if (capability->supportedPageSizes[i].name != nullptr) {
500             if (ConvertCustomPageSizeFromPwgName(capability->supportedPageSizes[i].name, printPageSize)) {
501                 AddUniquePageSize(pageSizeList, printPageSize);
502                 PRINT_HILOGD("custom page size matched = %{public}s", printPageSize.GetId().c_str());
503                 continue;
504             }
505         }
506         PRINT_HILOGD("page size = %{public}u x %{public}u", capability->supportedPageSizes[i].width,
507                      capability->supportedPageSizes[i].height);
508     }
509     printerCap.SetSupportedPageSize(pageSizeList);
510     return true;
511 }
512 
UpdateQualityCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability)513 bool UpdateQualityCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability)
514 {
515     if (capability == nullptr || capability->supportedQualities == nullptr) {
516         PRINT_HILOGW("supportedQualities is null");
517         return false;
518     }
519     std::vector<uint32_t> supportedQualityList;
520     if (ConvertArrayToList<Print_Quality, uint32_t>(capability->supportedQualities,
521         capability->supportedQualitiesCount, supportedQualityList, ConvertQuality)) {
522         printerCap.SetSupportedQuality(supportedQualityList);
523     }
524     std::string supportedQualities = ConvertArrayToJson<Print_Quality>(
525         capability->supportedQualities, capability->supportedQualitiesCount, ConvertQualityToJson);
526     PRINT_HILOGD("quality: %{public}s", supportedQualities.c_str());
527     if (!supportedQualities.empty()) {
528         printerCap.SetPrinterAttrNameAndValue("print-quality-supported", supportedQualities.c_str());
529     }
530     return true;
531 }
532 
UpdateColorCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability)533 bool UpdateColorCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability)
534 {
535     if (capability == nullptr || capability->supportedColorModes == nullptr) {
536         PRINT_HILOGW("supportedColorModes is null");
537         return false;
538     }
539     std::vector<uint32_t> supportedColorModes;
540     if (ConvertArrayToList<Print_ColorMode, uint32_t>(capability->supportedColorModes,
541         capability->supportedColorModesCount, supportedColorModes, ConvertColorMode)) {
542         printerCap.SetSupportedColorMode(supportedColorModes);
543     }
544     std::string colorModeJson = ConvertArrayToJson<Print_ColorMode>(
545         capability->supportedColorModes, capability->supportedColorModesCount, ConvertColorModeToJson);
546     if (!colorModeJson.empty()) {
547         printerCap.SetPrinterAttrNameAndValue("print-color-mode-supported", colorModeJson.c_str());
548     }
549     for (uint32_t i = 0; i < capability->supportedColorModesCount; ++i) {
550         if (capability->supportedColorModes[i] == Print_ColorMode::COLOR_MODE_COLOR) {
551             printerCap.SetColorMode(ColorModeCode::COLOR_MODE_COLOR);
552             break;
553         }
554     }
555     return true;
556 }
557 
UpdateDuplexCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability)558 bool UpdateDuplexCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability)
559 {
560     if (capability == nullptr || capability->supportedDuplexModes == nullptr) {
561         PRINT_HILOGW("supportedDuplexModes is null");
562         return false;
563     }
564     std::vector<uint32_t> supportedDuplexModes;
565     if (ConvertArrayToList<Print_DuplexMode, uint32_t>(capability->supportedDuplexModes,
566         capability->supportedDuplexModesCount, supportedDuplexModes, ConvertDuplexMode)) {
567         printerCap.SetSupportedDuplexMode(supportedDuplexModes);
568     }
569     std::string duplexModeJson = ConvertArrayToJson<Print_DuplexMode>(
570         capability->supportedDuplexModes, capability->supportedDuplexModesCount, ConvertDuplexModeToJson);
571     if (!duplexModeJson.empty()) {
572         printerCap.SetPrinterAttrNameAndValue("sides-supported", duplexModeJson.c_str());
573     }
574     if (capability->supportedDuplexModesCount > 1) {
575         printerCap.SetDuplexMode(static_cast<uint32_t>(Print_DuplexMode::DUPLEX_MODE_TWO_SIDED_LONG_EDGE));
576     }
577     return true;
578 }
UpdateResolutionCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability)579 bool UpdateResolutionCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability)
580 {
581     if (capability == nullptr || capability->supportedResolutions == nullptr) {
582         PRINT_HILOGW("supportedResolutions is null");
583         return false;
584     }
585     std::vector<PrintResolution> resolutionList;
586     Json::Value resolutionArray;
587     for (uint32_t i = 0; i < capability->supportedResolutionsCount; ++i) {
588         PrintResolution printResolution;
589         uint32_t xRes = capability->supportedResolutions[i].horizontalDpi;
590         uint32_t yRes = capability->supportedResolutions[i].verticalDpi;
591         printResolution.SetHorizontalDpi(xRes);
592         printResolution.SetVerticalDpi(yRes);
593         PRINT_HILOGD("resolution = %{public}u x %{public}u", xRes, yRes);
594         resolutionList.push_back(printResolution);
595         Json::Value object;
596         object["horizontalDpi"] = xRes;
597         object["verticalDpi"] = yRes;
598         resolutionArray.append(object);
599     }
600     printerCap.SetResolution(resolutionList);
601     printerCap.SetPrinterAttrNameAndValue("printer-resolution-supported",
602         (PrintJsonUtil::WriteString(resolutionArray)).c_str());
603     return true;
604 }
605 
UpdateResolutionDefaultValue(PrinterCapability & printerCap,const Print_DefaultValue * defaultValue)606 bool UpdateResolutionDefaultValue(PrinterCapability &printerCap, const Print_DefaultValue *defaultValue)
607 {
608     if (defaultValue == nullptr) {
609         PRINT_HILOGW("defaultValue is null");
610         return false;
611     }
612     Json::Value object;
613     object["horizontalDpi"] = defaultValue->defaultResolution.horizontalDpi;
614     object["verticalDpi"] = defaultValue->defaultResolution.verticalDpi;
615     printerCap.SetPrinterAttrNameAndValue("printer-resolution-default", (PrintJsonUtil::WriteString(object)).c_str());
616     return true;
617 }
618 
UpdateCopiesCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)619 bool UpdateCopiesCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability,
620                             const Print_DefaultValue *defaultValue)
621 {
622     if (capability == nullptr || defaultValue == nullptr) {
623         PRINT_HILOGW("capability or defaultValue is null");
624         return false;
625     }
626     printerCap.SetPrinterAttrNameAndValue("copies-supported", std::to_string(capability->supportedCopies).c_str());
627     printerCap.SetPrinterAttrNameAndValue("copies-default", std::to_string(defaultValue->defaultCopies).c_str());
628     return true;
629 }
630 
UpdateOrientationCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)631 bool UpdateOrientationCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability,
632                                  const Print_DefaultValue *defaultValue)
633 {
634     if (capability == nullptr || defaultValue == nullptr) {
635         PRINT_HILOGW("capability or defaultValue is null");
636         return false;
637     }
638     printerCap.SetPrinterAttrNameAndValue("orientation-requested-default",
639                                           std::to_string(defaultValue->defaultOrientation).c_str());
640     if (capability->supportedOrientations != nullptr) {
641         Json::Value supportedOrientationArray;
642         std::vector<uint32_t> supportedOrientations;
643         for (uint32_t i = 0; i < capability->supportedOrientationsCount; ++i) {
644             int orientationEnum = static_cast<int>(capability->supportedOrientations[i]) + ORIENTATION_OFFSET;
645             supportedOrientationArray.append(orientationEnum);
646             supportedOrientations.push_back(static_cast<uint32_t>(orientationEnum));
647         }
648         printerCap.SetSupportedOrientation(supportedOrientations);
649         printerCap.SetPrinterAttrNameAndValue("orientation-requested-supported",
650                                               (PrintJsonUtil::WriteString(supportedOrientationArray)).c_str());
651     }
652     return true;
653 }
654 
UpdateMediaCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)655 bool UpdateMediaCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability,
656                            const Print_DefaultValue *defaultValue)
657 {
658     if (capability == nullptr || defaultValue == nullptr) {
659         PRINT_HILOGW("capability or defaultValue is null");
660         return false;
661     }
662     if (capability->supportedMediaTypes != nullptr) {
663         printerCap.SetPrinterAttrNameAndValue("media-type-supported", capability->supportedMediaTypes);
664         std::string mediaTypeJson(capability->supportedMediaTypes);
665         std::vector<std::string> mediaTypeList;
666         if (ConvertJsonToStringList(mediaTypeJson, mediaTypeList)) {
667             printerCap.SetSupportedMediaType(mediaTypeList);
668         } else {
669             PRINT_HILOGW("invalid media types");
670         }
671     }
672     if (defaultValue->defaultMediaType != nullptr) {
673         printerCap.SetPrinterAttrNameAndValue("media-type-default", defaultValue->defaultMediaType);
674     }
675     if (capability->supportedPaperSources != nullptr) {
676         printerCap.SetPrinterAttrNameAndValue("media-source-supported", capability->supportedPaperSources);
677     }
678     if (defaultValue->defaultPaperSource != nullptr) {
679         printerCap.SetPrinterAttrNameAndValue("media-source-default", defaultValue->defaultPaperSource);
680     }
681     return true;
682 }
UpdateMarginCapability(PrinterCapability & printerCap,const Print_DefaultValue * defaultValue)683 bool UpdateMarginCapability(PrinterCapability &printerCap, const Print_DefaultValue *defaultValue)
684 {
685     if (defaultValue == nullptr) {
686         PRINT_HILOGW("defaultValue is null");
687         return false;
688     }
689     PrintMargin printMargin;
690     printMargin.SetLeft(defaultValue->defaultMargin.leftMargin);
691     printMargin.SetTop(defaultValue->defaultMargin.topMargin);
692     printMargin.SetRight(defaultValue->defaultMargin.rightMargin);
693     printMargin.SetBottom(defaultValue->defaultMargin.bottomMargin);
694     PRINT_HILOGD("margin left = %{public}u, top =  %{public}u, right = %{public}u, bottom =  %{public}u",
695                  defaultValue->defaultMargin.leftMargin, defaultValue->defaultMargin.topMargin,
696                  defaultValue->defaultMargin.rightMargin, defaultValue->defaultMargin.bottomMargin);
697     printerCap.SetMinMargin(printMargin);
698     return true;
699 }
UpdatePrinterCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)700 bool UpdatePrinterCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability,
701                              const Print_DefaultValue *defaultValue)
702 {
703     if (capability == nullptr || defaultValue == nullptr) {
704         PRINT_HILOGW("capability or defaultValue is null");
705         return false;
706     }
707     if (!UpdatePageSizeCapability(printerCap, capability, defaultValue)) {
708         return false;
709     }
710     UpdateColorCapability(printerCap, capability);
711     uint32_t defaultColorMode = static_cast<uint32_t>(defaultValue->defaultColorMode);
712     printerCap.SetPrinterAttrNameAndValue("defaultColorMode", std::to_string(defaultColorMode).c_str());
713     UpdateDuplexCapability(printerCap, capability);
714     uint32_t defaultDuplexMode = static_cast<uint32_t>(defaultValue->defaultDuplexMode);
715     printerCap.SetPrinterAttrNameAndValue("sides-default", std::to_string(defaultDuplexMode).c_str());
716     UpdateQualityCapability(printerCap, capability);
717     UpdateResolutionCapability(printerCap, capability);
718     UpdateResolutionDefaultValue(printerCap, defaultValue);
719     UpdateCopiesCapability(printerCap, capability, defaultValue);
720     UpdateOrientationCapability(printerCap, capability, defaultValue);
721     UpdateMediaCapability(printerCap, capability, defaultValue);
722     UpdateMarginCapability(printerCap, defaultValue);
723     return true;
724 }
725 
UpdatePrinterInfoWithCapability(PrinterInfo & info,const Print_DiscoveryItem * discoveryItem,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)726 bool UpdatePrinterInfoWithCapability(PrinterInfo &info, const Print_DiscoveryItem *discoveryItem,
727                                      const Print_PrinterCapability *capability, const Print_DefaultValue *defaultValue)
728 {
729     PrinterCapability printerCap;
730     if (!UpdatePrinterCapability(printerCap, capability, defaultValue)) {
731         PRINT_HILOGW("update capability fail");
732         return false;
733     }
734     Json::Value options;
735     if (discoveryItem != nullptr) {
736         if (discoveryItem->makeAndModel != nullptr) {
737             options["make"] = std::string(discoveryItem->makeAndModel);
738         }
739         if (discoveryItem->printerName != nullptr) {
740             options["printerName"] = info.GetPrinterName();
741         }
742         if (discoveryItem->printerUuid != nullptr) {
743             options["printer-uuid"] = std::string(discoveryItem->printerUuid);
744         }
745     }
746     Json::Value cupsOptionsJson = printerCap.GetPrinterAttrGroupJson();
747     options["cupsOptions"] = cupsOptionsJson;
748     std::string optionStr = PrintJsonUtil::WriteString(options);
749     PRINT_HILOGD("SetOption: %{public}s", optionStr.c_str());
750     printerCap.SetOption(optionStr);
751     info.SetCapability(printerCap);
752     info.Dump();
753     return true;
754 }
755 
ConvertVendorCapabilityToPrinterInfo(const Print_DiscoveryItem * printer,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)756 std::shared_ptr<PrinterInfo> ConvertVendorCapabilityToPrinterInfo(const Print_DiscoveryItem *printer,
757                                                                   const Print_PrinterCapability *capability,
758                                                                   const Print_DefaultValue *defaultValue)
759 {
760     if (printer == nullptr || printer->printerId == nullptr) {
761         PRINT_HILOGW("printer null");
762         return nullptr;
763     }
764     std::shared_ptr<PrinterInfo> info = std::make_shared<PrinterInfo>();
765     if (info == nullptr) {
766         return nullptr;
767     }
768     if (!UpdatePrinterInfoWithDiscovery(*info, printer)) {
769         PRINT_HILOGW("update printer info fail");
770         return nullptr;
771     }
772     UpdatePrinterInfoWithCapability(*info, printer, capability, defaultValue);
773     return info;
774 }
775 
ConvertStringVectorToStringList(const std::vector<std::string> & stringVector,Print_StringList & stringList)776 bool ConvertStringVectorToStringList(const std::vector<std::string> &stringVector, Print_StringList &stringList)
777 {
778     size_t count = stringVector.size();
779     if (count == 0 || count > MAX_STRING_COUNT) {
780         return false;
781     }
782     stringList.count = 0;
783     stringList.list = new (std::nothrow) char *[count];
784     if (stringList.list == nullptr) {
785         PRINT_HILOGW("stringList list allocate fail");
786         return false;
787     }
788     if (memset_s(stringList.list, count * sizeof(char *), 0, count * sizeof(char *)) != 0) {
789         PRINT_HILOGW("memset_s fail");
790         delete[] stringList.list;
791         stringList.list = nullptr;
792         return false;
793     }
794     for (auto const &key : stringVector) {
795         stringList.list[stringList.count] = CopyString(key);
796         stringList.count++;
797     }
798     return true;
799 }
800 
ReleaseStringList(Print_StringList & stringList)801 void ReleaseStringList(Print_StringList &stringList)
802 {
803     if (stringList.list != nullptr) {
804         for (uint32_t i = 0; i < stringList.count; i++) {
805             if (stringList.list[i] != nullptr) {
806                 delete[] stringList.list[i];
807                 stringList.list[i] = nullptr;
808             }
809         }
810         delete[] stringList.list;
811         stringList.list = nullptr;
812     }
813     stringList.count = 0;
814 }
815 }
816