• 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::shared_ptr<std::string> FindPropertyFromPropertyList(const Print_PropertyList *propertyList,
369     const std::string &keyName)
370 {
371     if (propertyList == nullptr) {
372         PRINT_HILOGW("propertyList is null");
373         return nullptr;
374     }
375     if (propertyList->count == 0 || propertyList->list == nullptr) {
376         PRINT_HILOGW("propertyList empty");
377         return nullptr;
378     }
379     for (uint32_t i = 0; i < propertyList->count; ++i) {
380         if (propertyList->list[i].key == nullptr) {
381             PRINT_HILOGW("propertyList key empty: %{public}u", i);
382             continue;
383         }
384         PRINT_HILOGD("FindPropertyFromPropertyList key: %{public}s", propertyList->list[i].key);
385         if (strcmp(keyName.c_str(), propertyList->list[i].key) != 0) {
386             continue;
387         }
388         if (propertyList->list[i].value == nullptr) {
389             PRINT_HILOGW("propertyList value empty, key: %{public}s", keyName.c_str());
390             break;
391         }
392         PRINT_HILOGD("FindPropertyFromPropertyList value: %{public}s", propertyList->list[i].value);
393         return std::make_shared<std::string>(propertyList->list[i].value);
394     }
395     return nullptr;
396 }
UpdatePrinterInfoWithDiscovery(PrinterInfo & info,const Print_DiscoveryItem * discoveryItem)397 bool UpdatePrinterInfoWithDiscovery(PrinterInfo &info, const Print_DiscoveryItem *discoveryItem)
398 {
399     if (discoveryItem == nullptr) {
400         PRINT_HILOGW("discoveryItem is null");
401         return false;
402     }
403     if (discoveryItem->printerId == nullptr || discoveryItem->printerName == nullptr) {
404         PRINT_HILOGW("invalid discoveryItem");
405         return false;
406     }
407     info.SetPrinterId(std::string(discoveryItem->printerId));
408     std::string name(discoveryItem->printerName);
409     info.SetPrinterName(name);
410     if (discoveryItem->description != nullptr) {
411         info.SetDescription(std::string(discoveryItem->description));
412     }
413     if (discoveryItem->printerUri != nullptr) {
414         info.SetUri(std::string(discoveryItem->printerUri));
415     }
416     if (discoveryItem->makeAndModel != nullptr) {
417         info.SetPrinterMake(std::string(discoveryItem->makeAndModel));
418     }
419     if (discoveryItem->printerUuid != nullptr) {
420         info.SetPrinterUuid(std::string(discoveryItem->printerUuid));
421     }
422     if (discoveryItem->printerUri != nullptr && discoveryItem->makeAndModel != nullptr) {
423         PRINT_HILOGD("printerUri: %{public}s", discoveryItem->printerUri);
424         Json::Value option;
425         option["printerName"] = name;
426         option["printerUri"] = std::string(discoveryItem->printerUri);
427         option["make"] = std::string(discoveryItem->makeAndModel);
428         if (discoveryItem->printerUuid != nullptr) {
429             option["printer-uuid"] = std::string(discoveryItem->printerUuid);
430         }
431         if (discoveryItem->detailInfo != nullptr) {
432             Json::Value detailInfo;
433             std::istringstream iss(std::string(discoveryItem->detailInfo));
434             if (PrintJsonUtil::ParseFromStream(iss, detailInfo) && !detailInfo.isNull()
435                 && PrintJsonUtil::IsMember(detailInfo, "bsunidriver_support") &&
436                 detailInfo["bsunidriver_support"].isString()) {
437                 option["bsunidriverSupport"] = detailInfo["bsunidriver_support"].asString();
438             }
439         } else {
440             PRINT_HILOGW("DetailInfo is null");
441         }
442         info.SetOption(PrintJsonUtil::WriteString(option));
443     }
444     return true;
445 }
446 
AddUniquePageSize(std::vector<PrintPageSize> & pageSizeList,const PrintPageSize & printPageSize)447 void AddUniquePageSize(std::vector<PrintPageSize> &pageSizeList, const PrintPageSize &printPageSize)
448 {
449     for (auto const &item : pageSizeList) {
450         if (item.GetId() == printPageSize.GetId()) {
451             return;
452         }
453     }
454     pageSizeList.push_back(printPageSize);
455 }
456 
UpdateDefaultPageSizeId(PrinterCapability & printerCap,const std::string & defaultPageId,const std::string & pageId,const Print_PageSize & page)457 bool UpdateDefaultPageSizeId(PrinterCapability &printerCap, const std::string &defaultPageId, const std::string &pageId,
458                              const Print_PageSize &page)
459 {
460     if (page.id != nullptr && defaultPageId == std::string(page.id)) {
461         printerCap.SetPrinterAttrNameAndValue("defaultPageSizeId", pageId.c_str());
462         return true;
463     }
464     return false;
465 }
466 
UpdatePageSizeCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)467 bool UpdatePageSizeCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability,
468                               const Print_DefaultValue *defaultValue)
469 {
470     if (capability == nullptr || capability->supportedPageSizes == nullptr) {
471         PRINT_HILOGW("supportedPageSizes is null");
472         return false;
473     }
474     std::string defaultPageId;
475     if (defaultValue != nullptr && defaultValue->defaultPageSizeId != nullptr) {
476         defaultPageId = defaultValue->defaultPageSizeId;
477     }
478     std::vector<PrintPageSize> pageSizeList;
479     for (uint32_t i = 0; i < capability->supportedPageSizesCount; ++i) {
480         PrintPageSize printPageSize;
481         if (capability->supportedPageSizes[i].name != nullptr) {
482             std::string pageSizeName(capability->supportedPageSizes[i].name);
483             PAGE_SIZE_ID id = PrintPageSize::MatchPageSize(pageSizeName);
484             if (!id.empty() && PrintPageSize::FindPageSizeById(id, printPageSize)) {
485                 AddUniquePageSize(pageSizeList, printPageSize);
486                 UpdateDefaultPageSizeId(printerCap, defaultPageId, id, capability->supportedPageSizes[i]);
487                 PRINT_HILOGD("page size matched = %{public}s", id.c_str());
488                 continue;
489             }
490         }
491         if (capability->supportedPageSizes[i].id != nullptr) {
492             PAGE_SIZE_ID id = std::string(capability->supportedPageSizes[i].id);
493             if (!id.empty() && PrintPageSize::FindPageSizeById(id, printPageSize)) {
494                 AddUniquePageSize(pageSizeList, printPageSize);
495                 UpdateDefaultPageSizeId(printerCap, defaultPageId, id, capability->supportedPageSizes[i]);
496                 PRINT_HILOGD("page size matched = %{public}s", id.c_str());
497                 continue;
498             }
499         }
500         if (capability->supportedPageSizes[i].name != nullptr && capability->supportedPageSizes[i].id != nullptr) {
501             if (strstr(capability->supportedPageSizes[i].id, "CUSTOM_MIN") ||
502                 strstr(capability->supportedPageSizes[i].id, "CUSTOM_MAX")) {
503                 PRINT_HILOGW("skip pageSize: %{public}s", capability->supportedPageSizes[i].name);
504                 continue;
505             }
506             printPageSize.SetWidth(capability->supportedPageSizes[i].width);
507             printPageSize.SetHeight(capability->supportedPageSizes[i].height);
508             if (printPageSize.ConvertToPwgStyle()) {
509                 AddUniquePageSize(pageSizeList, printPageSize);
510                 PRINT_HILOGD("custom page size matched = %{public}s", printPageSize.GetId().c_str());
511                 continue;
512             }
513         }
514     }
515     printerCap.SetSupportedPageSize(pageSizeList);
516     return true;
517 }
518 
UpdateQualityCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability)519 bool UpdateQualityCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability)
520 {
521     if (capability == nullptr || capability->supportedQualities == nullptr) {
522         PRINT_HILOGW("supportedQualities is null");
523         return false;
524     }
525     std::vector<uint32_t> supportedQualityList;
526     if (ConvertArrayToList<Print_Quality, uint32_t>(capability->supportedQualities,
527         capability->supportedQualitiesCount, supportedQualityList, ConvertQuality)) {
528         printerCap.SetSupportedQuality(supportedQualityList);
529     }
530     std::string supportedQualities = ConvertArrayToJson<Print_Quality>(
531         capability->supportedQualities, capability->supportedQualitiesCount, ConvertQualityToJson);
532     PRINT_HILOGD("quality: %{public}s", supportedQualities.c_str());
533     if (!supportedQualities.empty()) {
534         printerCap.SetPrinterAttrNameAndValue("print-quality-supported", supportedQualities.c_str());
535     }
536     return true;
537 }
538 
UpdateColorCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability)539 bool UpdateColorCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability)
540 {
541     if (capability == nullptr || capability->supportedColorModes == nullptr) {
542         PRINT_HILOGW("supportedColorModes is null");
543         return false;
544     }
545     std::vector<uint32_t> supportedColorModes;
546     if (ConvertArrayToList<Print_ColorMode, uint32_t>(capability->supportedColorModes,
547         capability->supportedColorModesCount, supportedColorModes, ConvertColorMode)) {
548         printerCap.SetSupportedColorMode(supportedColorModes);
549     }
550     std::string colorModeJson = ConvertArrayToJson<Print_ColorMode>(
551         capability->supportedColorModes, capability->supportedColorModesCount, ConvertColorModeToJson);
552     if (!colorModeJson.empty()) {
553         printerCap.SetPrinterAttrNameAndValue("print-color-mode-supported", colorModeJson.c_str());
554     }
555     for (uint32_t i = 0; i < capability->supportedColorModesCount; ++i) {
556         if (capability->supportedColorModes[i] == Print_ColorMode::COLOR_MODE_COLOR) {
557             printerCap.SetColorMode(ColorModeCode::COLOR_MODE_COLOR);
558             break;
559         }
560     }
561     return true;
562 }
563 
UpdateDuplexCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability)564 bool UpdateDuplexCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability)
565 {
566     if (capability == nullptr || capability->supportedDuplexModes == nullptr) {
567         PRINT_HILOGW("supportedDuplexModes is null");
568         return false;
569     }
570     std::vector<uint32_t> supportedDuplexModes;
571     if (ConvertArrayToList<Print_DuplexMode, uint32_t>(capability->supportedDuplexModes,
572         capability->supportedDuplexModesCount, supportedDuplexModes, ConvertDuplexMode)) {
573         printerCap.SetSupportedDuplexMode(supportedDuplexModes);
574     }
575     std::string duplexModeJson = ConvertArrayToJson<Print_DuplexMode>(
576         capability->supportedDuplexModes, capability->supportedDuplexModesCount, ConvertDuplexModeToJson);
577     if (!duplexModeJson.empty()) {
578         printerCap.SetPrinterAttrNameAndValue("sides-supported", duplexModeJson.c_str());
579     }
580     if (capability->supportedDuplexModesCount > 1) {
581         printerCap.SetDuplexMode(static_cast<uint32_t>(Print_DuplexMode::DUPLEX_MODE_TWO_SIDED_LONG_EDGE));
582     }
583     return true;
584 }
UpdateResolutionCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability)585 bool UpdateResolutionCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability)
586 {
587     if (capability == nullptr || capability->supportedResolutions == nullptr) {
588         PRINT_HILOGW("supportedResolutions is null");
589         return false;
590     }
591     std::vector<PrintResolution> resolutionList;
592     Json::Value resolutionArray;
593     for (uint32_t i = 0; i < capability->supportedResolutionsCount; ++i) {
594         PrintResolution printResolution;
595         uint32_t xRes = capability->supportedResolutions[i].horizontalDpi;
596         uint32_t yRes = capability->supportedResolutions[i].verticalDpi;
597         printResolution.SetHorizontalDpi(xRes);
598         printResolution.SetVerticalDpi(yRes);
599         PRINT_HILOGD("resolution = %{public}u x %{public}u", xRes, yRes);
600         resolutionList.push_back(printResolution);
601         Json::Value object;
602         object["horizontalDpi"] = xRes;
603         object["verticalDpi"] = yRes;
604         resolutionArray.append(object);
605     }
606     printerCap.SetResolution(resolutionList);
607     printerCap.SetPrinterAttrNameAndValue("printer-resolution-supported",
608         (PrintJsonUtil::WriteString(resolutionArray)).c_str());
609     return true;
610 }
611 
UpdateResolutionDefaultValue(PrinterCapability & printerCap,const Print_DefaultValue * defaultValue)612 bool UpdateResolutionDefaultValue(PrinterCapability &printerCap, const Print_DefaultValue *defaultValue)
613 {
614     if (defaultValue == nullptr) {
615         PRINT_HILOGW("defaultValue is null");
616         return false;
617     }
618     Json::Value object;
619     object["horizontalDpi"] = defaultValue->defaultResolution.horizontalDpi;
620     object["verticalDpi"] = defaultValue->defaultResolution.verticalDpi;
621     printerCap.SetPrinterAttrNameAndValue("printer-resolution-default", (PrintJsonUtil::WriteString(object)).c_str());
622     return true;
623 }
624 
UpdateCopiesCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)625 bool UpdateCopiesCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability,
626                             const Print_DefaultValue *defaultValue)
627 {
628     if (capability == nullptr || defaultValue == nullptr) {
629         PRINT_HILOGW("capability or defaultValue is null");
630         return false;
631     }
632     printerCap.SetPrinterAttrNameAndValue("copies-supported", std::to_string(capability->supportedCopies).c_str());
633     printerCap.SetPrinterAttrNameAndValue("copies-default", std::to_string(defaultValue->defaultCopies).c_str());
634     return true;
635 }
636 
UpdateOrientationCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)637 bool UpdateOrientationCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability,
638                                  const Print_DefaultValue *defaultValue)
639 {
640     if (capability == nullptr || defaultValue == nullptr) {
641         PRINT_HILOGW("capability or defaultValue is null");
642         return false;
643     }
644     printerCap.SetPrinterAttrNameAndValue("orientation-requested-default",
645                                           std::to_string(defaultValue->defaultOrientation).c_str());
646     if (capability->supportedOrientations != nullptr) {
647         Json::Value supportedOrientationArray;
648         std::vector<uint32_t> supportedOrientations;
649         for (uint32_t i = 0; i < capability->supportedOrientationsCount; ++i) {
650             int orientationEnum = static_cast<int>(capability->supportedOrientations[i]) + ORIENTATION_OFFSET;
651             supportedOrientationArray.append(orientationEnum);
652             supportedOrientations.push_back(static_cast<uint32_t>(orientationEnum));
653         }
654         printerCap.SetSupportedOrientation(supportedOrientations);
655         printerCap.SetPrinterAttrNameAndValue("orientation-requested-supported",
656                                               (PrintJsonUtil::WriteString(supportedOrientationArray)).c_str());
657     }
658     return true;
659 }
660 
UpdateMediaCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)661 bool UpdateMediaCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability,
662                            const Print_DefaultValue *defaultValue)
663 {
664     if (capability == nullptr || defaultValue == nullptr) {
665         PRINT_HILOGW("capability or defaultValue is null");
666         return false;
667     }
668     if (capability->supportedMediaTypes != nullptr) {
669         printerCap.SetPrinterAttrNameAndValue("media-type-supported", capability->supportedMediaTypes);
670         std::string mediaTypeJson(capability->supportedMediaTypes);
671         std::vector<std::string> mediaTypeList;
672         if (ConvertJsonToStringList(mediaTypeJson, mediaTypeList)) {
673             printerCap.SetSupportedMediaType(mediaTypeList);
674         } else {
675             PRINT_HILOGW("invalid media types");
676         }
677     }
678     if (defaultValue->defaultMediaType != nullptr) {
679         printerCap.SetPrinterAttrNameAndValue("media-type-default", defaultValue->defaultMediaType);
680     }
681     if (capability->supportedPaperSources != nullptr) {
682         printerCap.SetPrinterAttrNameAndValue("media-source-supported", capability->supportedPaperSources);
683     }
684     if (defaultValue->defaultPaperSource != nullptr) {
685         printerCap.SetPrinterAttrNameAndValue("media-source-default", defaultValue->defaultPaperSource);
686     }
687     return true;
688 }
UpdateMarginCapability(PrinterCapability & printerCap,const Print_DefaultValue * defaultValue)689 bool UpdateMarginCapability(PrinterCapability &printerCap, const Print_DefaultValue *defaultValue)
690 {
691     if (defaultValue == nullptr) {
692         PRINT_HILOGW("defaultValue is null");
693         return false;
694     }
695     PrintMargin printMargin;
696     printMargin.SetLeft(defaultValue->defaultMargin.leftMargin);
697     printMargin.SetTop(defaultValue->defaultMargin.topMargin);
698     printMargin.SetRight(defaultValue->defaultMargin.rightMargin);
699     printMargin.SetBottom(defaultValue->defaultMargin.bottomMargin);
700     PRINT_HILOGD("margin left = %{public}u, top =  %{public}u, right = %{public}u, bottom =  %{public}u",
701                  defaultValue->defaultMargin.leftMargin, defaultValue->defaultMargin.topMargin,
702                  defaultValue->defaultMargin.rightMargin, defaultValue->defaultMargin.bottomMargin);
703     printerCap.SetMinMargin(printMargin);
704     return true;
705 }
UpdatePrinterCapability(PrinterCapability & printerCap,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)706 bool UpdatePrinterCapability(PrinterCapability &printerCap, const Print_PrinterCapability *capability,
707                              const Print_DefaultValue *defaultValue)
708 {
709     if (capability == nullptr || defaultValue == nullptr) {
710         PRINT_HILOGW("capability or defaultValue is null");
711         return false;
712     }
713     if (!UpdatePageSizeCapability(printerCap, capability, defaultValue)) {
714         return false;
715     }
716     UpdateColorCapability(printerCap, capability);
717     uint32_t defaultColorMode = static_cast<uint32_t>(defaultValue->defaultColorMode);
718     printerCap.SetPrinterAttrNameAndValue("defaultColorMode", std::to_string(defaultColorMode).c_str());
719     UpdateDuplexCapability(printerCap, capability);
720     uint32_t defaultDuplexMode = static_cast<uint32_t>(defaultValue->defaultDuplexMode);
721     printerCap.SetPrinterAttrNameAndValue("sides-default", std::to_string(defaultDuplexMode).c_str());
722     UpdateQualityCapability(printerCap, capability);
723     UpdateResolutionCapability(printerCap, capability);
724     UpdateResolutionDefaultValue(printerCap, defaultValue);
725     UpdateCopiesCapability(printerCap, capability, defaultValue);
726     UpdateOrientationCapability(printerCap, capability, defaultValue);
727     UpdateMediaCapability(printerCap, capability, defaultValue);
728     UpdateMarginCapability(printerCap, defaultValue);
729     return true;
730 }
731 
UpdatePrinterInfoWithCapability(PrinterInfo & info,const Print_DiscoveryItem * discoveryItem,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)732 bool UpdatePrinterInfoWithCapability(PrinterInfo &info, const Print_DiscoveryItem *discoveryItem,
733                                      const Print_PrinterCapability *capability, const Print_DefaultValue *defaultValue)
734 {
735     PrinterCapability printerCap;
736     if (!UpdatePrinterCapability(printerCap, capability, defaultValue)) {
737         PRINT_HILOGW("update capability fail");
738         return false;
739     }
740     Json::Value options;
741     if (discoveryItem != nullptr) {
742         if (discoveryItem->makeAndModel != nullptr) {
743             options["make"] = std::string(discoveryItem->makeAndModel);
744         }
745         if (discoveryItem->printerName != nullptr) {
746             options["printerName"] = info.GetPrinterName();
747         }
748         if (discoveryItem->printerUuid != nullptr) {
749             options["printer-uuid"] = std::string(discoveryItem->printerUuid);
750         }
751     }
752     Json::Value cupsOptionsJson = printerCap.GetPrinterAttrGroupJson();
753     options["cupsOptions"] = cupsOptionsJson;
754     std::string optionStr = PrintJsonUtil::WriteString(options);
755     PRINT_HILOGD("SetOption: %{public}s", optionStr.c_str());
756     printerCap.SetOption(optionStr);
757     info.SetCapability(printerCap);
758     info.Dump();
759     return true;
760 }
761 
ConvertVendorCapabilityToPrinterInfo(const Print_DiscoveryItem * printer,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)762 std::shared_ptr<PrinterInfo> ConvertVendorCapabilityToPrinterInfo(const Print_DiscoveryItem *printer,
763                                                                   const Print_PrinterCapability *capability,
764                                                                   const Print_DefaultValue *defaultValue)
765 {
766     if (printer == nullptr || printer->printerId == nullptr) {
767         PRINT_HILOGW("printer null");
768         return nullptr;
769     }
770     std::shared_ptr<PrinterInfo> info = std::make_shared<PrinterInfo>();
771     if (info == nullptr) {
772         return nullptr;
773     }
774     if (!UpdatePrinterInfoWithDiscovery(*info, printer)) {
775         PRINT_HILOGW("update printer info fail");
776         return nullptr;
777     }
778     UpdatePrinterInfoWithCapability(*info, printer, capability, defaultValue);
779     return info;
780 }
781 
ConvertStringVectorToStringList(const std::vector<std::string> & stringVector,Print_StringList & stringList)782 bool ConvertStringVectorToStringList(const std::vector<std::string> &stringVector, Print_StringList &stringList)
783 {
784     size_t count = stringVector.size();
785     if (count == 0 || count > MAX_STRING_COUNT) {
786         return false;
787     }
788     stringList.count = 0;
789     stringList.list = new (std::nothrow) char *[count];
790     if (stringList.list == nullptr) {
791         PRINT_HILOGW("stringList list allocate fail");
792         return false;
793     }
794     if (memset_s(stringList.list, count * sizeof(char *), 0, count * sizeof(char *)) != 0) {
795         PRINT_HILOGW("memset_s fail");
796         delete[] stringList.list;
797         stringList.list = nullptr;
798         return false;
799     }
800     for (auto const &key : stringVector) {
801         stringList.list[stringList.count] = CopyString(key);
802         stringList.count++;
803     }
804     return true;
805 }
806 
ReleaseStringList(Print_StringList & stringList)807 void ReleaseStringList(Print_StringList &stringList)
808 {
809     if (stringList.list != nullptr) {
810         for (uint32_t i = 0; i < stringList.count; i++) {
811             if (stringList.list[i] != nullptr) {
812                 delete[] stringList.list[i];
813                 stringList.list[i] = nullptr;
814             }
815         }
816         delete[] stringList.list;
817         stringList.list = nullptr;
818     }
819     stringList.count = 0;
820 }
821 }
822