1 /*
2  * Copyright (c) 2023 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 <fcntl.h>
17 #include <unistd.h>
18 #include <iostream>
19 #include <fstream>
20 #include <streambuf>
21 #include "print_system_data.h"
22 #include "print_log.h"
23 #include "print_util.h"
24 #include "print_constant.h"
25 
26 namespace OHOS {
27 namespace Print {
28 
ParsePrinterListJsonV1(nlohmann::json & jsonObject)29 bool PrintSystemData::ParsePrinterListJsonV1(nlohmann::json &jsonObject)
30 {
31     if (!jsonObject.contains("printer_list") || !jsonObject["printer_list"].is_array()) {
32         PRINT_HILOGW("can not find printer_list");
33         return false;
34     }
35     for (auto &element : jsonObject["printer_list"].items()) {
36         nlohmann::json object = element.value();
37         if (!object.contains("id") || !object["id"].is_string()) {
38             PRINT_HILOGW("can not find id");
39             continue;
40         }
41         std::string id = object["id"];
42         if (!object.contains("name") || !object["name"].is_string()) {
43             PRINT_HILOGW("can not find name");
44             continue;
45         }
46         std::string name = object["name"];
47         if (!object.contains("uri") || !object["uri"].is_string()) {
48             PRINT_HILOGW("can not find uri");
49             continue;
50         }
51         std::string uri = object["uri"];
52         if (!object.contains("maker") || !object["maker"].is_string()) {
53             PRINT_HILOGW("can not find maker");
54             continue;
55         }
56         std::string maker = object["maker"];
57         if (!object.contains("capability") || !object["capability"].is_object()) {
58             PRINT_HILOGW("can not find capability");
59             continue;
60         }
61         nlohmann::json capsJson = object["capability"];
62         PrinterCapability printerCapability;
63         if (!ConvertJsonToPrinterCapability(capsJson, printerCapability)) {
64             PRINT_HILOGW("convert json to printer capability failed");
65             continue;
66         }
67         printerCapability.Dump();
68         CupsPrinterInfo info;
69         info.name = name;
70         info.uri = uri;
71         info.maker = maker;
72         info.printerCapability = printerCapability;
73         if (object.contains("alias") && object["alias"].is_string()) {
74             info.alias = object["alias"];
75         }
76         InsertCupsPrinter(id, info, true);
77     }
78     return true;
79 }
80 
Init()81 bool PrintSystemData::Init()
82 {
83     addedPrinterMap_.Clear();
84     nlohmann::json jsonObject;
85     std::string printerListFilePath = PRINTER_SERVICE_FILE_PATH + "/" + PRINTER_LIST_FILE;
86     if (!GetJsonObjectFromFile(jsonObject, printerListFilePath)) {
87         PRINT_HILOGW("get json from file fail");
88         return false;
89     }
90     return ParsePrinterListJsonV1(jsonObject);
91 }
92 
GetJsonObjectFromFile(nlohmann::json & jsonObject,const std::string & fileName)93 bool PrintSystemData::GetJsonObjectFromFile(nlohmann::json &jsonObject, const std::string &fileName)
94 {
95     std::ifstream ifs(fileName.c_str(), std::ios::in | std::ios::binary);
96     if (!ifs.is_open()) {
97         PRINT_HILOGW("open printer list file fail");
98         return false;
99     }
100     std::string fileData((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
101     ifs.close();
102     if (!nlohmann::json::accept(fileData)) {
103         PRINT_HILOGW("json accept fail");
104         return false;
105     }
106     jsonObject = nlohmann::json::parse(fileData);
107     if (!jsonObject.contains("version") || !jsonObject["version"].is_string()) {
108         PRINT_HILOGW("can not find version");
109         return false;
110     }
111     std::string version = jsonObject["version"].get<std::string>();
112     PRINT_HILOGI("json version: %{public}s", version.c_str());
113     std::string fileVersion = "";
114     std::string printerListFilePath = PRINTER_SERVICE_FILE_PATH + "/" + PRINTER_LIST_FILE;
115     if (strcmp(fileName.c_str(), printerListFilePath.c_str())) {
116         fileVersion = PRINTER_LIST_VERSION;
117     } else {
118         fileVersion = PRINT_USER_DATA_VERSION;
119     }
120     if (strcmp(version.c_str(), PRINTER_LIST_VERSION.c_str())) {
121         PRINT_HILOGW("printer list version is error.");
122         return false;
123     }
124     return true;
125 }
126 
InsertCupsPrinter(const std::string & printerId,const CupsPrinterInfo & printerInfo,bool needUpdateCaps)127 void PrintSystemData::InsertCupsPrinter(
128     const std::string &printerId, const CupsPrinterInfo &printerInfo, bool needUpdateCaps)
129 {
130     auto orderId = 0;
131     if (!addedPrinterOrderList_.empty()) {
132         orderId = addedPrinterOrderList_.rbegin()->first;
133     }
134     auto info = addedPrinterMap_.Find(printerId);
135     if (info == nullptr) {
136         PRINT_HILOGI("insert new printer");
137         addedPrinterMap_.Insert(printerId, printerInfo);
138     } else {
139         PRINT_HILOGI("update exist printer");
140         info->name = printerInfo.name;
141         info->uri = printerInfo.uri;
142         info->maker = printerInfo.maker;
143         info->printerStatus = printerInfo.printerStatus;
144         info->alias = printerInfo.alias;
145         if (needUpdateCaps) {
146             info->printerCapability = printerInfo.printerCapability;
147         }
148     }
149     if (needUpdateCaps) {
150         auto addedPrinterOrderListIter = std::find_if(addedPrinterOrderList_.begin(),
151             addedPrinterOrderList_.end(),
152             [&printerId](
153                 const std::pair<uint32_t, std::string> &addedPrinter) { return addedPrinter.second == printerId; });
154         if (addedPrinterOrderListIter != addedPrinterOrderList_.end()) {
155             PRINT_HILOGW("value found");
156         } else {
157             addedPrinterOrderList_.insert(std::make_pair(orderId + 1, printerId));
158             PRINT_HILOGI("printerId: %{public}s, orderId: %{public}d", printerId.c_str(), orderId + 1);
159         }
160     }
161 }
162 
DeleteCupsPrinter(const std::string & printerId)163 void PrintSystemData::DeleteCupsPrinter(const std::string &printerId)
164 {
165     if (!printerId.empty()) {
166         PRINT_HILOGI("DeleteCupsPrinter printerId: %{public}s", printerId.c_str());
167         addedPrinterMap_.Remove(printerId);
168         for (auto printer: addedPrinterOrderList_) {
169             if (!strcmp(printerId.c_str(), printer.second.c_str())) {
170                 addedPrinterOrderList_.erase(printer.first);
171                 PRINT_HILOGI("erase printer order success");
172                 break;
173             }
174         }
175         SaveCupsPrinterMap();
176     }
177 }
178 
SaveCupsPrinterMap()179 bool PrintSystemData::SaveCupsPrinterMap()
180 {
181     std::string printerListFilePath = PRINTER_SERVICE_FILE_PATH + "/" + PRINTER_LIST_FILE;
182     char realPidFile[PATH_MAX] = {};
183     if (realpath(PRINTER_SERVICE_FILE_PATH.c_str(), realPidFile) == nullptr) {
184         PRINT_HILOGE("The realPidFile is null, errno:%{public}s", std::to_string(errno).c_str());
185         return false;
186     }
187     int32_t fd = open(printerListFilePath.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0640);
188     PRINT_HILOGD("SaveCupsPrinterMap fd: %{public}d", fd);
189     if (fd < 0) {
190         PRINT_HILOGW("Failed to open file errno: %{public}s", std::to_string(errno).c_str());
191         return false;
192     }
193     nlohmann::json printerMapJson = nlohmann::json::array();
194     for (auto printer : addedPrinterOrderList_) {
195         auto info = addedPrinterMap_.Find(printer.second);
196         if (info == nullptr) {
197             continue;
198         }
199         nlohmann::json printerJson = nlohmann::json::object();
200         printerJson["id"] = printer.second;
201         printerJson["name"] = info->name;
202         printerJson["uri"] = info->uri;
203         printerJson["maker"] = info->maker;
204         printerJson["alias"] = info->alias;
205         nlohmann::json capsJson;
206         ConvertPrinterCapabilityToJson(info->printerCapability, capsJson);
207         printerJson["capability"] = capsJson;
208         printerMapJson.push_back(printerJson);
209     }
210     nlohmann::json jsonObject;
211     jsonObject["version"] = PRINTER_LIST_VERSION;
212     jsonObject["printer_list"] = printerMapJson;
213     std::string jsonString = jsonObject.dump();
214     size_t jsonLength = jsonString.length();
215     auto writeLength = write(fd, jsonString.c_str(), jsonLength);
216     close(fd);
217     PRINT_HILOGI("SaveCupsPrinterMap finished");
218     if (writeLength < 0) {
219         return false;
220     }
221     return (size_t)writeLength == jsonLength;
222 }
223 
QueryPrinterIdByStandardizeName(const std::string & printerName)224 std::string PrintSystemData::QueryPrinterIdByStandardizeName(const std::string &printerName)
225 {
226     std::string stardardizeName = PrintUtil::StandardizePrinterName(printerName);
227     return addedPrinterMap_.FindKey([this, stardardizeName](const CupsPrinterInfo &cupsPrinter) -> bool {
228         return PrintUtil::StandardizePrinterName(cupsPrinter.name) == stardardizeName;
229     });
230 }
231 
QueryCupsPrinterInfoByPrinterId(const std::string & printerId,CupsPrinterInfo & cupsPrinter)232 bool PrintSystemData::QueryCupsPrinterInfoByPrinterId(const std::string &printerId, CupsPrinterInfo &cupsPrinter)
233 {
234     auto info = addedPrinterMap_.Find(printerId);
235     if (info == nullptr) {
236         return false;
237     }
238     cupsPrinter.name = info->name;
239     cupsPrinter.uri = info->uri;
240     cupsPrinter.maker = info->maker;
241     cupsPrinter.printerCapability = info->printerCapability;
242     cupsPrinter.printerStatus = info->printerStatus;
243     cupsPrinter.alias = info->alias;
244     return true;
245 }
246 
QueryPrinterInfoById(const std::string & printerId,PrinterInfo & printerInfo)247 void PrintSystemData::QueryPrinterInfoById(const std::string &printerId, PrinterInfo &printerInfo)
248 {
249     CupsPrinterInfo cupsPrinter;
250     if (QueryCupsPrinterInfoByPrinterId(printerId, cupsPrinter)) {
251         printerInfo.SetPrinterId(printerId);
252         printerInfo.SetPrinterName(PrintUtil::RemoveUnderlineFromPrinterName(cupsPrinter.name));
253         printerInfo.SetCapability(cupsPrinter.printerCapability);
254         printerInfo.SetPrinterStatus(cupsPrinter.printerStatus);
255         nlohmann::json option;
256         option["printerName"] = cupsPrinter.name;
257         option["printerUri"] = cupsPrinter.uri;
258         option["make"] = cupsPrinter.maker;
259         option["alias"] = cupsPrinter.alias;
260         printerInfo.SetOption(option.dump());
261         printerInfo.Dump();
262     } else {
263         PRINT_HILOGE("query printer info failed.");
264     }
265 }
266 
UpdatePrinterStatus(const std::string & printerId,PrinterStatus printerStatus)267 void PrintSystemData::UpdatePrinterStatus(const std::string& printerId, PrinterStatus printerStatus)
268 {
269     auto info = addedPrinterMap_.Find(printerId);
270     if (info != nullptr) {
271         info->printerStatus = printerStatus;
272         PRINT_HILOGI("UpdatePrinterStatus success, status: %{public}d", info->printerStatus);
273     }
274 }
275 
UpdatePrinterAlias(const std::string & printerId,const std::string & printerAlias)276 bool PrintSystemData::UpdatePrinterAlias(const std::string& printerId, const std::string& printerAlias)
277 {
278     auto info = addedPrinterMap_.Find(printerId);
279     if (info != nullptr) {
280         if (info->alias != printerAlias) {
281             info->alias = printerAlias;
282             PRINT_HILOGI("UpdatePrinterAlias success, alias: %{public}s", info->alias.c_str());
283             return true;
284         }
285         PRINT_HILOGW("Alias is the same, no update needed.");
286         return false;
287     }
288     PRINT_HILOGE("Unable to find the corresponding printId.");
289     return false;
290 }
291 
UpdatePrinterUri(const std::shared_ptr<PrinterInfo> & printerInfo)292 void PrintSystemData::UpdatePrinterUri(const std::shared_ptr<PrinterInfo> &printerInfo)
293 {
294     auto info = addedPrinterMap_.Find(printerInfo->GetPrinterId());
295     if (info != nullptr) {
296         info->uri = printerInfo->GetUri();
297         PRINT_HILOGI("UpdatePrinterUri success");
298     }
299 }
300 
InsertPrinterInfo(const std::string & printerId,const PrinterInfo & printerInfo)301 void PrintSystemData::InsertPrinterInfo(const std::string &printerId, const PrinterInfo &printerInfo)
302 {
303     auto iter = addedPrinterInfoList_.find(printerId);
304     if (iter == addedPrinterInfoList_.end() || iter->second == nullptr) {
305         PRINT_HILOGI("insert new printerInfo");
306         addedPrinterInfoList_[printerId] = std::make_shared<PrinterInfo>(printerInfo);
307     }
308 }
309 
QueryPrinterInfoByPrinterId(const std::string & printerId)310 std::shared_ptr<PrinterInfo> PrintSystemData::QueryPrinterInfoByPrinterId(const std::string &printerId)
311 {
312     auto iter = addedPrinterInfoList_.find(printerId);
313     if (iter != addedPrinterInfoList_.end()) {
314         return iter->second;
315     }
316     return nullptr;
317 }
318 
GetAddedPrinterListFromSystemData(std::vector<std::string> & printerNameList)319 void PrintSystemData::GetAddedPrinterListFromSystemData(std::vector<std::string> &printerNameList)
320 {
321     for (auto it = addedPrinterOrderList_.rbegin(); it != addedPrinterOrderList_.rend(); ++it) {
322         auto info = addedPrinterMap_.Find(it->second);
323         if (info == nullptr) {
324             continue;
325         }
326         PRINT_HILOGD("GetAddedPrinterListFromSystemData info->name: %{public}s", info->name.c_str());
327         printerNameList.push_back(info->name);
328     }
329 }
330 
IsPrinterAdded(const std::string & printerId)331 bool PrintSystemData::IsPrinterAdded(const std::string &printerId)
332 {
333     auto info = addedPrinterMap_.Find(printerId);
334     if (info == nullptr) {
335         return false;
336     }
337     return true;
338 }
339 
ConvertPrinterCapabilityToJson(PrinterCapability & printerCapability,nlohmann::json & capsJson)340 void PrintSystemData::ConvertPrinterCapabilityToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)
341 {
342     capsJson["colorMode"] = printerCapability.GetColorMode();
343     capsJson["duplexMode"] = printerCapability.GetDuplexMode();
344     ConvertPageSizeToJson(printerCapability, capsJson);
345 
346     if (printerCapability.HasMargin()) {
347         ConvertPrintMarginToJson(printerCapability, capsJson);
348     }
349 
350     if (printerCapability.HasResolution()) {
351         ConvertPrintResolutionToJson(printerCapability, capsJson);
352     }
353 
354     if (printerCapability.HasSupportedColorMode()) {
355         ConvertSupportedColorModeToJson(printerCapability, capsJson);
356     }
357 
358     if (printerCapability.HasSupportedDuplexMode()) {
359         ConvertSupportedDuplexModeToJson(printerCapability, capsJson);
360     }
361 
362     if (printerCapability.HasSupportedMediaType()) {
363         ConvertSupportedMediaTypeToJson(printerCapability, capsJson);
364     }
365 
366     if (printerCapability.HasSupportedQuality()) {
367         ConvertSupportedQualityToJson(printerCapability, capsJson);
368     }
369 
370     if (printerCapability.HasOption()) {
371         std::string options = printerCapability.GetOption();
372         if (!nlohmann::json::accept(options)) {
373             PRINT_HILOGE("json accept capability options fail");
374             return;
375         }
376         capsJson["options"] = nlohmann::json::parse(options);
377     }
378 }
379 
ConvertPrintResolutionToJson(PrinterCapability & printerCapability,nlohmann::json & capsJson)380 void PrintSystemData::ConvertPrintResolutionToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)
381 {
382     nlohmann::json resolutionListJson = nlohmann::json::array();
383     std::vector<PrintResolution> resolutionList;
384     printerCapability.GetResolution(resolutionList);
385     for (auto iter : resolutionList) {
386         nlohmann::json resolutionJson = nlohmann::json::object();
387         resolutionJson["id"] = iter.GetId();
388         resolutionJson["horizontalDpi"] = iter.GetHorizontalDpi();
389         resolutionJson["verticalDpi"] = iter.GetVerticalDpi();
390         resolutionListJson.push_back(resolutionJson);
391     }
392     capsJson["resolution"] = resolutionListJson;
393 }
394 
ConvertSupportedColorModeToJson(PrinterCapability & printerCapability,nlohmann::json & capsJson)395 void PrintSystemData::ConvertSupportedColorModeToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)
396 {
397     nlohmann::json SupportedColorModeListJson = nlohmann::json::array();
398     std::vector<uint32_t> SupportedColorModeList;
399     printerCapability.GetSupportedColorMode(SupportedColorModeList);
400     for (auto iter : SupportedColorModeList) {
401         SupportedColorModeListJson.push_back(iter);
402     }
403     capsJson["supportedColorMode"] = SupportedColorModeListJson;
404 }
405 
ConvertSupportedDuplexModeToJson(PrinterCapability & printerCapability,nlohmann::json & capsJson)406 void PrintSystemData::ConvertSupportedDuplexModeToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)
407 {
408     nlohmann::json supportedDuplexModeListJson = nlohmann::json::array();
409     std::vector<uint32_t> supportedDuplexModeList;
410     printerCapability.GetSupportedDuplexMode(supportedDuplexModeList);
411     for (auto iter : supportedDuplexModeList) {
412         supportedDuplexModeListJson.push_back(iter);
413     }
414     capsJson["supportedDuplexMode"] = supportedDuplexModeListJson;
415 }
416 
ConvertSupportedMediaTypeToJson(PrinterCapability & printerCapability,nlohmann::json & capsJson)417 void PrintSystemData::ConvertSupportedMediaTypeToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)
418 {
419     nlohmann::json supportedMediaTypeListJson = nlohmann::json::array();
420     std::vector<std::string> supportedMediaTypeList;
421     printerCapability.GetSupportedMediaType(supportedMediaTypeList);
422     for (auto iter : supportedMediaTypeList) {
423         supportedMediaTypeListJson.push_back(iter);
424     }
425     capsJson["supportedMediaType"] = supportedMediaTypeListJson;
426 }
427 
ConvertSupportedQualityToJson(PrinterCapability & printerCapability,nlohmann::json & capsJson)428 void PrintSystemData::ConvertSupportedQualityToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)
429 {
430     nlohmann::json supportedQualityListJson = nlohmann::json::array();
431     std::vector<uint32_t> supportedQualityList;
432     printerCapability.GetSupportedQuality(supportedQualityList);
433     for (auto iter : supportedQualityList) {
434         supportedQualityListJson.push_back(iter);
435     }
436     capsJson["supportedQuality"] = supportedQualityListJson;
437 }
438 
ConvertPageSizeToJson(PrinterCapability & printerCapability,nlohmann::json & capsJson)439 void PrintSystemData::ConvertPageSizeToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)
440 {
441     nlohmann::json pageSizeListJson = nlohmann::json::array();
442     std::vector<PrintPageSize> pageSizeList;
443     printerCapability.GetSupportedPageSize(pageSizeList);
444     for (auto iter : pageSizeList) {
445         nlohmann::json pageSizeJson = nlohmann::json::object();
446         pageSizeJson["id"] = iter.GetId();
447         pageSizeJson["name"] = iter.GetName();
448         pageSizeJson["width"] = iter.GetWidth();
449         pageSizeJson["height"] = iter.GetHeight();
450         pageSizeListJson.push_back(pageSizeJson);
451     }
452     capsJson["pageSize"] = pageSizeListJson;
453 }
454 
ConvertPrintMarginToJson(PrinterCapability & printerCapability,nlohmann::json & capsJson)455 void PrintSystemData::ConvertPrintMarginToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)
456 {
457     nlohmann::json marginJson;
458     PrintMargin minMargin;
459     printerCapability.GetMinMargin(minMargin);
460     if (minMargin.HasTop()) {
461         marginJson["top"] = minMargin.GetTop();
462     }
463     if (minMargin.HasBottom()) {
464         marginJson["bottom"] = minMargin.GetBottom();
465     }
466     if (minMargin.HasLeft()) {
467         marginJson["left"] = minMargin.GetLeft();
468     }
469     if (minMargin.HasRight()) {
470         marginJson["right"] = minMargin.GetRight();
471     }
472     capsJson["minMargin"] = marginJson;
473 }
474 
ConvertJsonToPrinterCapability(nlohmann::json & capsJson,PrinterCapability & printerCapability)475 bool PrintSystemData::ConvertJsonToPrinterCapability(nlohmann::json &capsJson, PrinterCapability &printerCapability)
476 {
477     if (!capsJson.contains("colorMode") || !capsJson["colorMode"].is_number()) {
478         PRINT_HILOGW("can not find colorMode");
479         return false;
480     }
481     if (!capsJson.contains("duplexMode") || !capsJson["duplexMode"].is_number()) {
482         PRINT_HILOGW("can not find duplexMode");
483         return false;
484     }
485 
486     printerCapability.SetColorMode(capsJson["colorMode"].get<uint32_t>());
487 
488     printerCapability.SetDuplexMode(capsJson["duplexMode"].get<uint32_t>());
489 
490     if (capsJson.contains("minMargin") && capsJson["minMargin"].is_object()) {
491         PRINT_HILOGD("find minMargin");
492         ConvertJsonToPrintMargin(capsJson, printerCapability);
493     }
494 
495     if (!ConvertJsonToPrintResolution(capsJson, printerCapability)) {
496         PRINT_HILOGW("convert json to print resolution failed");
497         return false;
498     }
499 
500     if (!ConvertJsonToPageSize(capsJson, printerCapability)) {
501         PRINT_HILOGW("convert json to pageSize failed");
502         return false;
503     }
504 
505     if (!ConvertJsonToSupportedColorMode(capsJson, printerCapability)) {
506         PRINT_HILOGW("convert json to supportedColorMode failed.");
507         return false;
508     }
509 
510     if (!ConvertJsonToSupportedDuplexMode(capsJson, printerCapability)) {
511         PRINT_HILOGW("convert json to supportedDuplexMode failed.");
512         return false;
513     }
514 
515     if (!ConvertJsonToSupportedMediaType(capsJson, printerCapability)) {
516         PRINT_HILOGW("convert json to supportedMediaType failed.");
517         return false;
518     }
519 
520     if (!ConvertJsonToSupportedQuality(capsJson, printerCapability)) {
521         PRINT_HILOGW("convert json to supportedQuality failed.");
522         return false;
523     }
524 
525     if (!ConvertJsonToSupportedOrientation(capsJson, printerCapability)) {
526         PRINT_HILOGW("convert json to supportedOrientation failed.");
527         return false;
528     }
529 
530     if (capsJson.contains("options") && capsJson["options"].is_object()) {
531         PRINT_HILOGD("find options");
532         printerCapability.SetOption(capsJson["options"].dump());
533     }
534     return true;
535 }
536 
ConvertJsonToPageSize(nlohmann::json & capsJson,PrinterCapability & printerCapability)537 bool PrintSystemData::ConvertJsonToPageSize(nlohmann::json &capsJson, PrinterCapability &printerCapability)
538 {
539     return ProcessJsonToCapabilityList<PrintPageSize>(
540         capsJson, "pageSize", printerCapability, &PrinterCapability::SetSupportedPageSize,
541         [](const nlohmann::json &item, PrintPageSize &pageSize) -> bool {
542             if (!item.is_object() ||
543                 !item.contains("id") ||!PrintUtils::CheckJsonType<std::string>(item["id"]) ||
544                 !item.contains("name") ||!PrintUtils::CheckJsonType<std::string>(item["name"]) ||
545                 !item.contains("width") ||!PrintUtils::CheckJsonType<uint32_t>(item["width"]) ||
546                 !item.contains("height") ||!PrintUtils::CheckJsonType<uint32_t>(item["height"])) {
547                 return false;
548             }
549             pageSize.SetId(item["id"].get<std::string>());
550             pageSize.SetName(item["name"].get<std::string>());
551             pageSize.SetWidth(item["width"].get<uint32_t>());
552             pageSize.SetHeight(item["height"].get<uint32_t>());
553             return true;
554         }
555     );
556 }
557 
ConvertJsonToPrintResolution(nlohmann::json & capsJson,PrinterCapability & printerCapability)558 bool PrintSystemData::ConvertJsonToPrintResolution(nlohmann::json &capsJson, PrinterCapability &printerCapability)
559 {
560     return ProcessJsonToCapabilityList<PrintResolution>(capsJson, "resolution", printerCapability,
561         &PrinterCapability::SetResolution,
562         [](const nlohmann::json &item, PrintResolution &resolution) -> bool {
563             if (!item.is_object() ||
564                 !item.contains("id") || !PrintUtils::CheckJsonType<std::string>(item["id"]) ||
565                 !item.contains("horizontalDpi") || !PrintUtils::CheckJsonType<uint32_t>(item["horizontalDpi"]) ||
566                 !item.contains("verticalDpi") || !PrintUtils::CheckJsonType<uint32_t>(item["verticalDpi"])) {
567                 return false;
568             }
569             resolution.SetId(item["id"].get<std::string>());
570             resolution.SetHorizontalDpi(item["horizontalDpi"].get<uint32_t>());
571             resolution.SetVerticalDpi(item["verticalDpi"].get<uint32_t>());
572             return true;
573         }
574     );
575 }
576 
ConvertJsonToSupportedColorMode(nlohmann::json & capsJson,PrinterCapability & printerCapability)577 bool PrintSystemData::ConvertJsonToSupportedColorMode(nlohmann::json &capsJson, PrinterCapability &printerCapability)
578 {
579     return ProcessJsonToCapabilityList<uint32_t>(capsJson, "supportedColorMode", printerCapability,
580         &PrinterCapability::SetSupportedColorMode,
581         [](const nlohmann::json &item, uint32_t &colorMode) -> bool {
582             colorMode = item.get<uint32_t>();
583             return true;
584         });
585 }
586 
ConvertJsonToSupportedDuplexMode(nlohmann::json & capsJson,PrinterCapability & printerCapability)587 bool PrintSystemData::ConvertJsonToSupportedDuplexMode(nlohmann::json &capsJson, PrinterCapability &printerCapability)
588 {
589     return ProcessJsonToCapabilityList<uint32_t>(capsJson, "supportedDuplexMode", printerCapability,
590         &PrinterCapability::SetSupportedDuplexMode,
591         [](const nlohmann::json &item, uint32_t &duplexMode) -> bool {
592             duplexMode = item.get<uint32_t>();
593             return true;
594         });
595 }
596 
ConvertJsonToSupportedMediaType(nlohmann::json & capsJson,PrinterCapability & printerCapability)597 bool PrintSystemData::ConvertJsonToSupportedMediaType(nlohmann::json &capsJson, PrinterCapability &printerCapability)
598 {
599     return ProcessJsonToCapabilityList<std::string>(capsJson, "supportedMediaType", printerCapability,
600         &PrinterCapability::SetSupportedMediaType,
601         [](const nlohmann::json &item, std::string &mediaType) -> bool {
602             mediaType = item.get<std::string>();
603             return true;
604         });
605 }
606 
ConvertJsonToSupportedQuality(nlohmann::json & capsJson,PrinterCapability & printerCapability)607 bool PrintSystemData::ConvertJsonToSupportedQuality(nlohmann::json &capsJson, PrinterCapability &printerCapability)
608 {
609     return ProcessJsonToCapabilityList<uint32_t>(capsJson, "supportedQuality", printerCapability,
610         &PrinterCapability::SetSupportedQuality,
611         [](const nlohmann::json &item, uint32_t &quality) -> bool {
612             quality = item.get<uint32_t>();
613             return true;
614         });
615 }
616 
ConvertJsonToSupportedOrientation(nlohmann::json & capsJson,PrinterCapability & printerCapability)617 bool PrintSystemData::ConvertJsonToSupportedOrientation(nlohmann::json &capsJson, PrinterCapability &printerCapability)
618 {
619     return ProcessJsonToCapabilityList<uint32_t>(capsJson, "supportedOrientation", printerCapability,
620         &PrinterCapability::SetSupportedOrientation,
621         [](const nlohmann::json &item, uint32_t &orientation) -> bool {
622             orientation = item.get<uint32_t>();
623             return true;
624         });
625 }
626 
ConvertJsonToPrintMargin(nlohmann::json & capsJson,PrinterCapability & printerCapability)627 bool PrintSystemData::ConvertJsonToPrintMargin(nlohmann::json &capsJson, PrinterCapability &printerCapability)
628 {
629     nlohmann::json marginJson = capsJson["minMargin"];
630     PrintMargin minMargin;
631     if (!marginJson.is_object() ||
632         !marginJson.contains("top") || !PrintUtils::CheckJsonType<std::string>(marginJson["top"]) ||
633         !marginJson.contains("bottom") || !PrintUtils::CheckJsonType<std::string>(marginJson["bottom"]) ||
634         !marginJson.contains("left") || !PrintUtils::CheckJsonType<uint32_t>(marginJson["left"]) ||
635         !marginJson.contains("right") || !PrintUtils::CheckJsonType<uint32_t>(marginJson["right"])) {
636         PRINT_HILOGE("Invalid format,key is minMargin");
637         return false;
638     }
639     minMargin.SetTop(marginJson["top"].get<uint32_t>());
640     minMargin.SetBottom(marginJson["bottom"].get<uint32_t>());
641     minMargin.SetLeft(marginJson["left"].get<uint32_t>());
642     minMargin.SetRight(marginJson["right"].get<uint32_t>());
643     printerCapability.SetMinMargin(minMargin);
644     PRINT_HILOGD("ProcessJsonToCapabilityList success, key is minMargin");
645     return true;
646 }
647 
GetPrinterCapabilityFromSystemData(CupsPrinterInfo & cupsPrinter,std::string printerId,PrinterCapability & printerCapability)648 bool PrintSystemData::GetPrinterCapabilityFromSystemData(CupsPrinterInfo &cupsPrinter,
649     std::string printerId, PrinterCapability &printerCapability)
650 {
651     PrinterCapability cupsPrinterCaps = cupsPrinter.printerCapability;
652     std::vector<PrintPageSize> pageSizeList;
653     cupsPrinterCaps.GetPageSize(pageSizeList);
654     if (!pageSizeList.empty()) {
655         PRINT_HILOGI("find printer capability in system data");
656         printerCapability = cupsPrinterCaps;
657         return true;
658     } else if (GetPrinterCapabilityFromFile(printerId, printerCapability)) {
659         return true;
660     }
661     return false;
662 }
663 
GetPrinterCapabilityFromFile(std::string printerId,PrinterCapability & printerCapability)664 bool PrintSystemData::GetPrinterCapabilityFromFile(std::string printerId, PrinterCapability &printerCapability)
665 {
666     PRINT_HILOGI("GetPrinterCapabilityFromFile printerId: %{public}s", printerId.c_str());
667     nlohmann::json jsonObject;
668     std::string printerListFilePath = PRINTER_SERVICE_FILE_PATH + "/" + PRINTER_LIST_FILE;
669     if (!GetJsonObjectFromFile(jsonObject, printerListFilePath)) {
670         PRINT_HILOGW("get json from file fail");
671         return false;
672     }
673 
674     if (!GetPrinterCapabilityFromJson(printerId, jsonObject, printerCapability)) {
675         PRINT_HILOGW("get caps from file json fail");
676         return false;
677     }
678     return true;
679 }
680 
GetPrinterCapabilityFromJson(std::string printerId,nlohmann::json & jsonObject,PrinterCapability & printerCapability)681 bool PrintSystemData::GetPrinterCapabilityFromJson(
682     std::string printerId, nlohmann::json &jsonObject, PrinterCapability &printerCapability)
683 {
684     if (!jsonObject.contains("printer_list") || !jsonObject["printer_list"].is_array()) {
685         PRINT_HILOGW("can not find printer_list");
686         return false;
687     }
688     nlohmann::json printerMapJson = jsonObject["printer_list"];
689     if (printerMapJson.empty()) {
690         PRINT_HILOGW("printer map is empty");
691         return false;
692     }
693 
694     for (auto &element : jsonObject["printer_list"].items()) {
695         nlohmann::json object = element.value();
696         if (!CheckPrinterInfoJson(object, printerId)) {
697             continue;
698         }
699         if (!object.contains("capability")) {
700             PRINT_HILOGE("json does not contain the key as capability");
701             continue;
702         }
703         nlohmann::json capsJson = object["capability"];
704         PrinterCapability caps;
705         if (!ConvertJsonToPrinterCapability(capsJson, caps)) {
706             PRINT_HILOGW("convert json to printer capability failed");
707             continue;
708         }
709         std::vector<PrintPageSize> pageSizeList;
710         caps.GetPageSize(pageSizeList);
711         if (pageSizeList.size() != 0) {
712             PRINT_HILOGI("find printer capability in file");
713             caps.Dump();
714             printerCapability = caps;
715             return true;
716         }
717     }
718     return false;
719 }
720 
CheckPrinterInfoJson(nlohmann::json & object,std::string & printerId)721 bool PrintSystemData::CheckPrinterInfoJson(nlohmann::json &object, std::string &printerId)
722 {
723     if (!object.contains("id") || !object["id"].is_string()) {
724         PRINT_HILOGW("can not find id");
725         return false;
726     }
727     std::string id = object["id"];
728     if (id != printerId) {
729         return false;
730     }
731     if (!object.contains("name") || !object["name"].is_string()) {
732         PRINT_HILOGW("can not find name");
733         return false;
734     }
735     if (!object.contains("uri") || !object["uri"].is_string()) {
736         PRINT_HILOGW("can not find uri");
737         return false;
738     }
739     if (!object.contains("maker") || !object["maker"].is_string()) {
740         PRINT_HILOGW("can not find maker");
741         return false;
742     }
743     if (!object.contains("capability") || !object["capability"].is_object()) {
744         PRINT_HILOGW("can not find capability");
745         return false;
746     }
747     return true;
748 }
749 
CheckPrinterBusy(const std::string & printerId)750 bool PrintSystemData::CheckPrinterBusy(const std::string &printerId)
751 {
752     CupsPrinterInfo cupsPrinter;
753     QueryCupsPrinterInfoByPrinterId(printerId, cupsPrinter);
754     if (cupsPrinter.printerStatus == PRINTER_STATUS_BUSY) {
755         PRINT_HILOGI("printer is busy");
756         return true;
757     }
758     return false;
759 }
760 
GetAllPrintUser(std::vector<int32_t> & allPrintUserList)761 bool PrintSystemData::GetAllPrintUser(std::vector<int32_t> &allPrintUserList)
762 {
763     nlohmann::json jsonObject;
764     std::string userDataFilePath = PRINTER_SERVICE_FILE_PATH + "/" + PRINT_USER_DATA_FILE;
765     if (!GetJsonObjectFromFile(jsonObject, userDataFilePath)) {
766         PRINT_HILOGW("get json from file fail");
767         return false;
768     }
769     return ParseUserListJsonV1(jsonObject, allPrintUserList);
770 }
771 
ParseUserListJsonV1(nlohmann::json & jsonObject,std::vector<int32_t> & allPrintUserList)772 bool PrintSystemData::ParseUserListJsonV1(nlohmann::json &jsonObject, std::vector<int32_t> &allPrintUserList)
773 {
774     if (!jsonObject.contains("print_user_data") || !jsonObject["print_user_data"].is_object()) {
775         PRINT_HILOGE("can not find print_user_data");
776         return false;
777     }
778     for (auto &element : jsonObject["print_user_data"].items()) {
779         std::string userIdStr = element.key();
780         if (userIdStr.empty()) {
781             continue;
782         }
783         int32_t userId = 0;
784         if (!PrintUtil::ConvertToInt(userIdStr, userId)) {
785             PRINT_HILOGE("userIdStr [%{public}s] can not parse to number.", userIdStr.c_str());
786             return false;
787         }
788         PRINT_HILOGI("ParseUserListJsonV1 userId: %{public}d", userId);
789         allPrintUserList.push_back(userId);
790     }
791     if (!allPrintUserList.size()) {
792         PRINT_HILOGE("allPrintUserList is empty.");
793         return false;
794     }
795     return true;
796 }
797 
QueryAddedPrinterIdList()798 std::vector<std::string> PrintSystemData::QueryAddedPrinterIdList()
799 {
800     return addedPrinterMap_.GetKeyList();
801 }
802 
QueryDiscoveredPrinterInfoById(const std::string & printerId)803 std::shared_ptr<PrinterInfo> PrintSystemData::QueryDiscoveredPrinterInfoById(const std::string &printerId)
804 {
805     std::lock_guard<std::mutex> lock(discoveredListMutex);
806     auto printerIt = discoveredPrinterInfoList_.find(printerId);
807     if (printerIt != discoveredPrinterInfoList_.end()) {
808         return printerIt ->second;
809     }
810     return nullptr;
811 }
QueryDiscoveredPrinterInfoByName(const std::string & printerName)812 std::shared_ptr<PrinterInfo> PrintSystemData::QueryDiscoveredPrinterInfoByName(const std::string &printerName)
813 {
814     std::lock_guard<std::mutex> lock(discoveredListMutex);
815     std::string name = PrintUtil::StandardizePrinterName(printerName);
816     for (auto iter = discoveredPrinterInfoList_.begin(); iter != discoveredPrinterInfoList_.end(); ++iter) {
817         auto printerInfoPtr = iter->second;
818         if (printerInfoPtr == nullptr) {
819             continue;
820         }
821         if (PrintUtil::StandardizePrinterName(printerInfoPtr->GetPrinterName()) != name) {
822             continue;
823         }
824         return printerInfoPtr;
825     }
826     return nullptr;
827 }
828 
AddPrinterToDiscovery(std::shared_ptr<PrinterInfo> printerInfo)829 void PrintSystemData::AddPrinterToDiscovery(std::shared_ptr<PrinterInfo> printerInfo)
830 {
831     std::lock_guard<std::mutex> lock(discoveredListMutex);
832     if (printerInfo != nullptr) {
833         discoveredPrinterInfoList_[printerInfo->GetPrinterId()] = printerInfo;
834     }
835 }
836 
RemovePrinterFromDiscovery(const std::string & printerId)837 void PrintSystemData::RemovePrinterFromDiscovery(const std::string &printerId)
838 {
839     std::lock_guard<std::mutex> lock(discoveredListMutex);
840     discoveredPrinterInfoList_.erase(printerId);
841 }
842 
GetDiscoveredPrinterCount()843 size_t PrintSystemData::GetDiscoveredPrinterCount()
844 {
845     std::lock_guard<std::mutex> lock(discoveredListMutex);
846     return discoveredPrinterInfoList_.size();
847 }
848 
ClearDiscoveredPrinterList()849 void PrintSystemData::ClearDiscoveredPrinterList()
850 {
851     std::lock_guard<std::mutex> lock(discoveredListMutex);
852     discoveredPrinterInfoList_.clear();
853 }
854 
GetDiscoveredPrinterInfo()855 std::map<std::string, std::shared_ptr<PrinterInfo>> PrintSystemData::GetDiscoveredPrinterInfo()
856 {
857     return discoveredPrinterInfoList_;
858 }
859 }  // namespace Print
860 }  // namespace OHOS