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 E_PRINT_SERVER_FAILURE;
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     ConvertPageSizeToJson(printerCapability, capsJson);
351 
352     if (printerCapability.HasResolution()) {
353         ConvertPrintResolutionToJson(printerCapability, capsJson);
354     }
355 
356     if (printerCapability.HasSupportedColorMode()) {
357         ConvertSupportedColorModeToJson(printerCapability, capsJson);
358     }
359 
360     if (printerCapability.HasSupportedDuplexMode()) {
361         ConvertSupportedDuplexModeToJson(printerCapability, capsJson);
362     }
363 
364     if (printerCapability.HasSupportedMediaType()) {
365         ConvertSupportedMediaTypeToJson(printerCapability, capsJson);
366     }
367 
368     if (printerCapability.HasSupportedQuality()) {
369         ConvertSupportedQualityToJson(printerCapability, capsJson);
370     }
371 
372     if (printerCapability.HasOption()) {
373         std::string options = printerCapability.GetOption();
374         if (!nlohmann::json::accept(options)) {
375             PRINT_HILOGE("json accept capability options fail");
376             return;
377         }
378         capsJson["options"] = nlohmann::json::parse(options);
379     }
380 }
381 
ConvertPrintResolutionToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)382 void PrintSystemData::ConvertPrintResolutionToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)
383 {
384     nlohmann::json resolutionListJson = nlohmann::json::array();
385     std::vector<PrintResolution> resolutionList;
386     printerCapability.GetResolution(resolutionList);
387     for (auto iter : resolutionList) {
388         nlohmann::json resolutionJson = nlohmann::json::object();
389         resolutionJson["id"] = iter.GetId();
390         resolutionJson["horizontalDpi"] = iter.GetHorizontalDpi();
391         resolutionJson["verticalDpi"] = iter.GetVerticalDpi();
392         resolutionListJson.push_back(resolutionJson);
393     }
394     capsJson["resolution"] = resolutionListJson;
395 }
396 
ConvertSupportedColorModeToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)397 void PrintSystemData::ConvertSupportedColorModeToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)
398 {
399     nlohmann::json SupportedColorModeListJson = nlohmann::json::array();
400     std::vector<uint32_t> SupportedColorModeList;
401     printerCapability.GetSupportedColorMode(SupportedColorModeList);
402     for (auto iter : SupportedColorModeList) {
403         SupportedColorModeListJson.push_back(iter);
404     }
405     capsJson["supportedColorMode"] = SupportedColorModeListJson;
406 }
407 
ConvertSupportedDuplexModeToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)408 void PrintSystemData::ConvertSupportedDuplexModeToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)
409 {
410     nlohmann::json supportedDuplexModeListJson = nlohmann::json::array();
411     std::vector<uint32_t> supportedDuplexModeList;
412     printerCapability.GetSupportedDuplexMode(supportedDuplexModeList);
413     for (auto iter : supportedDuplexModeList) {
414         supportedDuplexModeListJson.push_back(iter);
415     }
416     capsJson["supportedDuplexMode"] = supportedDuplexModeListJson;
417 }
418 
ConvertSupportedMediaTypeToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)419 void PrintSystemData::ConvertSupportedMediaTypeToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)
420 {
421     nlohmann::json supportedMediaTypeListJson = nlohmann::json::array();
422     std::vector<std::string> supportedMediaTypeList;
423     printerCapability.GetSupportedMediaType(supportedMediaTypeList);
424     for (auto iter : supportedMediaTypeList) {
425         supportedMediaTypeListJson.push_back(iter);
426     }
427     capsJson["supportedMediaType"] = supportedMediaTypeListJson;
428 }
429 
ConvertSupportedQualityToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)430 void PrintSystemData::ConvertSupportedQualityToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)
431 {
432     nlohmann::json supportedQualityListJson = nlohmann::json::array();
433     std::vector<uint32_t> supportedQualityList;
434     printerCapability.GetSupportedQuality(supportedQualityList);
435     for (auto iter : supportedQualityList) {
436         supportedQualityListJson.push_back(iter);
437     }
438     capsJson["supportedQuality"] = supportedQualityListJson;
439 }
440 
ConvertPageSizeToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)441 void PrintSystemData::ConvertPageSizeToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)
442 {
443     nlohmann::json pageSizeListJson = nlohmann::json::array();
444     std::vector<PrintPageSize> pageSizeList;
445     printerCapability.GetSupportedPageSize(pageSizeList);
446     for (auto iter : pageSizeList) {
447         nlohmann::json pageSizeJson = nlohmann::json::object();
448         pageSizeJson["id"] = iter.GetId();
449         pageSizeJson["name"] = iter.GetName();
450         pageSizeJson["width"] = iter.GetWidth();
451         pageSizeJson["height"] = iter.GetHeight();
452         pageSizeListJson.push_back(pageSizeJson);
453     }
454     capsJson["pageSize"] = pageSizeListJson;
455 }
456 
ConvertPrintMarginToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)457 void PrintSystemData::ConvertPrintMarginToJson(PrinterCapability &printerCapability, nlohmann::json &capsJson)
458 {
459     nlohmann::json marginJson;
460     PrintMargin minMargin;
461     printerCapability.GetMinMargin(minMargin);
462     if (minMargin.HasTop()) {
463         marginJson["top"] = minMargin.GetTop();
464     }
465     if (minMargin.HasBottom()) {
466         marginJson["bottom"] = minMargin.GetBottom();
467     }
468     if (minMargin.HasLeft()) {
469         marginJson["left"] = minMargin.GetLeft();
470     }
471     if (minMargin.HasRight()) {
472         marginJson["right"] = minMargin.GetRight();
473     }
474     capsJson["minMargin"] = marginJson;
475 }
476 
ConvertJsonToPrinterCapability(nlohmann::json &capsJson, PrinterCapability &printerCapability)477 bool PrintSystemData::ConvertJsonToPrinterCapability(nlohmann::json &capsJson, PrinterCapability &printerCapability)
478 {
479     if (!capsJson.contains("colorMode") || !capsJson["colorMode"].is_number()) {
480         PRINT_HILOGW("can not find colorMode");
481         return false;
482     }
483     if (!capsJson.contains("duplexMode") || !capsJson["duplexMode"].is_number()) {
484         PRINT_HILOGW("can not find duplexMode");
485         return false;
486     }
487 
488     printerCapability.SetColorMode(capsJson["colorMode"].get<uint32_t>());
489 
490     printerCapability.SetDuplexMode(capsJson["duplexMode"].get<uint32_t>());
491 
492     if (capsJson.contains("minMargin") && capsJson["minMargin"].is_object()) {
493         PRINT_HILOGD("find minMargin");
494         ConvertJsonToPrintMargin(capsJson, printerCapability);
495     }
496 
497     if (!ConvertJsonToPrintResolution(capsJson, printerCapability)) {
498         PRINT_HILOGW("convert json to print resolution failed");
499         return false;
500     }
501 
502     if (!ConvertJsonToPageSize(capsJson, printerCapability)) {
503         PRINT_HILOGW("convert json to pageSize failed");
504         return false;
505     }
506 
507     if (!ConvertJsonToSupportedColorMode(capsJson, printerCapability)) {
508         PRINT_HILOGW("convert json to supportedColorMode failed.");
509         return false;
510     }
511 
512     if (!ConvertJsonToSupportedDuplexMode(capsJson, printerCapability)) {
513         PRINT_HILOGW("convert json to supportedDuplexMode failed.");
514         return false;
515     }
516 
517     if (!ConvertJsonToSupportedMediaType(capsJson, printerCapability)) {
518         PRINT_HILOGW("convert json to supportedMediaType failed.");
519         return false;
520     }
521 
522     if (!ConvertJsonToSupportedQuality(capsJson, printerCapability)) {
523         PRINT_HILOGW("convert json to supportedQuality failed.");
524         return false;
525     }
526 
527     if (!ConvertJsonToSupportedOrientation(capsJson, printerCapability)) {
528         PRINT_HILOGW("convert json to supportedOrientation failed.");
529         return false;
530     }
531 
532     if (capsJson.contains("options") && capsJson["options"].is_object()) {
533         PRINT_HILOGD("find options");
534         printerCapability.SetOption(capsJson["options"].dump());
535     }
536     return true;
537 }
538 
ConvertJsonToPageSize(nlohmann::json &capsJson, PrinterCapability &printerCapability)539 bool PrintSystemData::ConvertJsonToPageSize(nlohmann::json &capsJson, PrinterCapability &printerCapability)
540 {
541     return ProcessJsonToCapabilityList<PrintPageSize>(
542         capsJson, "pageSize", printerCapability, &PrinterCapability::SetSupportedPageSize,
543         [](const nlohmann::json &item, PrintPageSize &pageSize) -> bool {
544             if (!item.is_object() ||
545                 !item.contains("id") ||!PrintUtils::CheckJsonType<std::string>(item["id"]) ||
546                 !item.contains("name") ||!PrintUtils::CheckJsonType<std::string>(item["name"]) ||
547                 !item.contains("width") ||!PrintUtils::CheckJsonType<uint32_t>(item["width"]) ||
548                 !item.contains("height") ||!PrintUtils::CheckJsonType<uint32_t>(item["height"])) {
549                 return false;
550             }
551             pageSize.SetId(item["id"].get<std::string>());
552             pageSize.SetName(item["name"].get<std::string>());
553             pageSize.SetWidth(item["width"].get<uint32_t>());
554             pageSize.SetHeight(item["height"].get<uint32_t>());
555             return true;
556         }
557     );
558 }
559 
560 bool PrintSystemData::ConvertJsonToPrintResolution(nlohmann::json &capsJson, PrinterCapability &printerCapability)
561 {
562     return ProcessJsonToCapabilityList<PrintResolution>(capsJson, "resolution", printerCapability,
563         &PrinterCapability::SetResolution,
564         [](const nlohmann::json &item, PrintResolution &resolution) -> bool {
565             if (!item.is_object() ||
566                 !item.contains("id") || !PrintUtils::CheckJsonType<std::string>(item["id"]) ||
567                 !item.contains("horizontalDpi") || !PrintUtils::CheckJsonType<uint32_t>(item["horizontalDpi"]) ||
568                 !item.contains("verticalDpi") || !PrintUtils::CheckJsonType<uint32_t>(item["verticalDpi"])) {
569                 return false;
570             }
571             resolution.SetId(item["id"].get<std::string>());
572             resolution.SetHorizontalDpi(item["horizontalDpi"].get<uint32_t>());
573             resolution.SetVerticalDpi(item["verticalDpi"].get<uint32_t>());
574             return true;
575         }
576     );
577 }
578 
579 bool PrintSystemData::ConvertJsonToSupportedColorMode(nlohmann::json &capsJson, PrinterCapability &printerCapability)
580 {
581     return ProcessJsonToCapabilityList<uint32_t>(capsJson, "supportedColorMode", printerCapability,
582         &PrinterCapability::SetSupportedColorMode,
583         [](const nlohmann::json &item, uint32_t &colorMode) -> bool {
584             colorMode = item.get<uint32_t>();
585             return true;
586         });
587 }
588 
589 bool PrintSystemData::ConvertJsonToSupportedDuplexMode(nlohmann::json &capsJson, PrinterCapability &printerCapability)
590 {
591     return ProcessJsonToCapabilityList<uint32_t>(capsJson, "supportedDuplexMode", printerCapability,
592         &PrinterCapability::SetSupportedDuplexMode,
593         [](const nlohmann::json &item, uint32_t &duplexMode) -> bool {
594             duplexMode = item.get<uint32_t>();
595             return true;
596         });
597 }
598 
599 bool PrintSystemData::ConvertJsonToSupportedMediaType(nlohmann::json &capsJson, PrinterCapability &printerCapability)
600 {
601     return ProcessJsonToCapabilityList<std::string>(capsJson, "supportedMediaType", printerCapability,
602         &PrinterCapability::SetSupportedMediaType,
603         [](const nlohmann::json &item, std::string &mediaType) -> bool {
604             mediaType = item.get<std::string>();
605             return true;
606         });
607 }
608 
609 bool PrintSystemData::ConvertJsonToSupportedQuality(nlohmann::json &capsJson, PrinterCapability &printerCapability)
610 {
611     return ProcessJsonToCapabilityList<uint32_t>(capsJson, "supportedQuality", printerCapability,
612         &PrinterCapability::SetSupportedQuality,
613         [](const nlohmann::json &item, uint32_t &quality) -> bool {
614             quality = item.get<uint32_t>();
615             return true;
616         });
617 }
618 
619 bool PrintSystemData::ConvertJsonToSupportedOrientation(nlohmann::json &capsJson, PrinterCapability &printerCapability)
620 {
621     return ProcessJsonToCapabilityList<uint32_t>(capsJson, "supportedOrientation", printerCapability,
622         &PrinterCapability::SetSupportedOrientation,
623         [](const nlohmann::json &item, uint32_t &orientation) -> bool {
624             orientation = item.get<uint32_t>();
625             return true;
626         });
627 }
628 
629 bool PrintSystemData::ConvertJsonToPrintMargin(nlohmann::json &capsJson, PrinterCapability &printerCapability)
630 {
631     nlohmann::json marginJson = capsJson["minMargin"];
632     PrintMargin minMargin;
633     if (!marginJson.is_object() ||
634         !marginJson.contains("top") || !PrintUtils::CheckJsonType<std::string>(marginJson["top"]) ||
635         !marginJson.contains("bottom") || !PrintUtils::CheckJsonType<std::string>(marginJson["bottom"]) ||
636         !marginJson.contains("left") || !PrintUtils::CheckJsonType<uint32_t>(marginJson["left"]) ||
637         !marginJson.contains("right") || !PrintUtils::CheckJsonType<uint32_t>(marginJson["right"])) {
638         PRINT_HILOGE("Invalid format,key is minMargin");
639         return false;
640     }
641     minMargin.SetTop(marginJson["top"].get<uint32_t>());
642     minMargin.SetTop(marginJson["bottom"].get<uint32_t>());
643     minMargin.SetLeft(marginJson["left"].get<uint32_t>());
644     minMargin.SetRight(marginJson["right"].get<uint32_t>());
645     printerCapability.SetMinMargin(minMargin);
646     PRINT_HILOGD("ProcessJsonToCapabilityList success, key is minMargin");
647     return true;
648 }
649 
650 bool PrintSystemData::GetPrinterCapabilityFromSystemData(CupsPrinterInfo &cupsPrinter,
651     std::string printerId, PrinterCapability &printerCapability)
652 {
653     PrinterCapability cupsPrinterCaps = cupsPrinter.printerCapability;
654     std::vector<PrintPageSize> pageSizeList;
655     cupsPrinterCaps.GetPageSize(pageSizeList);
656     if (!pageSizeList.empty()) {
657         PRINT_HILOGI("find printer capability in system data");
658         printerCapability = cupsPrinterCaps;
659         return true;
660     } else if (GetPrinterCapabilityFromFile(printerId, printerCapability)) {
661         return true;
662     }
663     return false;
664 }
665 
666 bool PrintSystemData::GetPrinterCapabilityFromFile(std::string printerId, PrinterCapability &printerCapability)
667 {
668     PRINT_HILOGI("GetPrinterCapabilityFromFile printerId: %{public}s", printerId.c_str());
669     nlohmann::json jsonObject;
670     std::string printerListFilePath = PRINTER_SERVICE_FILE_PATH + "/" + PRINTER_LIST_FILE;
671     if (!GetJsonObjectFromFile(jsonObject, printerListFilePath)) {
672         PRINT_HILOGW("get json from file fail");
673         return false;
674     }
675 
676     if (!GetPrinterCapabilityFromJson(printerId, jsonObject, printerCapability)) {
677         PRINT_HILOGW("get caps from file json fail");
678         return false;
679     }
680     return true;
681 }
682 
683 bool PrintSystemData::GetPrinterCapabilityFromJson(
684     std::string printerId, nlohmann::json &jsonObject, PrinterCapability &printerCapability)
685 {
686     if (!jsonObject.contains("printer_list") || !jsonObject["printer_list"].is_array()) {
687         PRINT_HILOGW("can not find printer_list");
688         return false;
689     }
690     nlohmann::json printerMapJson = jsonObject["printer_list"];
691     if (printerMapJson.empty()) {
692         PRINT_HILOGW("printer map is empty");
693         return false;
694     }
695 
696     for (auto &element : jsonObject["printer_list"].items()) {
697         nlohmann::json object = element.value();
698         if (!CheckPrinterInfoJson(object, printerId)) {
699             continue;
700         }
701         if (!object.contains("capability")) {
702             PRINT_HILOGE("json does not contain the key as capability");
703             continue;
704         }
705         nlohmann::json capsJson = object["capability"];
706         PrinterCapability caps;
707         if (!ConvertJsonToPrinterCapability(capsJson, caps)) {
708             PRINT_HILOGW("convert json to printer capability failed");
709             continue;
710         }
711         std::vector<PrintPageSize> pageSizeList;
712         caps.GetPageSize(pageSizeList);
713         if (pageSizeList.size() != 0) {
714             PRINT_HILOGI("find printer capability in file");
715             caps.Dump();
716             printerCapability = caps;
717             return true;
718         }
719     }
720     return false;
721 }
722 
723 bool PrintSystemData::CheckPrinterInfoJson(nlohmann::json &object, std::string &printerId)
724 {
725     if (!object.contains("id") || !object["id"].is_string()) {
726         PRINT_HILOGW("can not find id");
727         return false;
728     }
729     std::string id = object["id"];
730     if (id != printerId) {
731         return false;
732     }
733     if (!object.contains("name") || !object["name"].is_string()) {
734         PRINT_HILOGW("can not find name");
735         return false;
736     }
737     if (!object.contains("uri") || !object["uri"].is_string()) {
738         PRINT_HILOGW("can not find uri");
739         return false;
740     }
741     if (!object.contains("maker") || !object["maker"].is_string()) {
742         PRINT_HILOGW("can not find maker");
743         return false;
744     }
745     if (!object.contains("capability") || !object["capability"].is_object()) {
746         PRINT_HILOGW("can not find capability");
747         return false;
748     }
749     return true;
750 }
751 
752 bool PrintSystemData::CheckPrinterBusy(const std::string &printerId)
753 {
754     CupsPrinterInfo cupsPrinter;
755     QueryCupsPrinterInfoByPrinterId(printerId, cupsPrinter);
756     if (cupsPrinter.printerStatus == PRINTER_STATUS_BUSY) {
757         PRINT_HILOGI("printer is busy");
758         return true;
759     }
760     return false;
761 }
762 
763 bool PrintSystemData::GetAllPrintUser(std::vector<int32_t> &allPrintUserList)
764 {
765     nlohmann::json jsonObject;
766     std::string userDataFilePath = PRINTER_SERVICE_FILE_PATH + "/" + PRINT_USER_DATA_FILE;
767     if (!GetJsonObjectFromFile(jsonObject, userDataFilePath)) {
768         PRINT_HILOGW("get json from file fail");
769         return false;
770     }
771     return ParseUserListJsonV1(jsonObject, allPrintUserList);
772 }
773 
774 bool PrintSystemData::ParseUserListJsonV1(nlohmann::json &jsonObject, std::vector<int32_t> &allPrintUserList)
775 {
776     if (!jsonObject.contains("print_user_data") || !jsonObject["print_user_data"].is_object()) {
777         PRINT_HILOGE("can not find print_user_data");
778         return false;
779     }
780     for (auto &element : jsonObject["print_user_data"].items()) {
781         std::string userIdStr = element.key();
782         if (userIdStr.empty()) {
783             continue;
784         }
785         int32_t userId = std::stoi(userIdStr);
786         PRINT_HILOGI("ParseUserListJsonV1 userId: %{public}d", userId);
787         allPrintUserList.push_back(userId);
788     }
789     if (!allPrintUserList.size()) {
790         PRINT_HILOGE("allPrintUserList is empty.");
791         return false;
792     }
793     return true;
794 }
795 
796 std::vector<std::string> PrintSystemData::QueryAddedPrinterIdList()
797 {
798     return addedPrinterMap_.GetKeyList();
799 }
800 
801 std::shared_ptr<PrinterInfo> PrintSystemData::QueryDiscoveredPrinterInfoById(const std::string &printerId)
802 {
803     std::lock_guard<std::mutex> lock(discoveredListMutex);
804     auto printerIt = discoveredPrinterInfoList_.find(printerId);
805     if (printerIt != discoveredPrinterInfoList_.end()) {
806         return printerIt ->second;
807     }
808     return nullptr;
809 }
810 std::shared_ptr<PrinterInfo> PrintSystemData::QueryDiscoveredPrinterInfoByName(const std::string &printerName)
811 {
812     std::lock_guard<std::mutex> lock(discoveredListMutex);
813     std::string name = PrintUtil::StandardizePrinterName(printerName);
814     for (auto iter = discoveredPrinterInfoList_.begin(); iter != discoveredPrinterInfoList_.end(); ++iter) {
815         auto printerInfoPtr = iter->second;
816         if (printerInfoPtr == nullptr) {
817             continue;
818         }
819         if (PrintUtil::StandardizePrinterName(printerInfoPtr->GetPrinterName()) != name) {
820             continue;
821         }
822         return printerInfoPtr;
823     }
824     return nullptr;
825 }
826 
827 void PrintSystemData::AddPrinterToDiscovery(std::shared_ptr<PrinterInfo> printerInfo)
828 {
829     std::lock_guard<std::mutex> lock(discoveredListMutex);
830     if (printerInfo != nullptr) {
831         discoveredPrinterInfoList_[printerInfo->GetPrinterId()] = printerInfo;
832     }
833 }
834 
835 void PrintSystemData::RemovePrinterFromDiscovery(const std::string &printerId)
836 {
837     std::lock_guard<std::mutex> lock(discoveredListMutex);
838     discoveredPrinterInfoList_.erase(printerId);
839 }
840 
841 size_t PrintSystemData::GetDiscoveredPrinterCount()
842 {
843     std::lock_guard<std::mutex> lock(discoveredListMutex);
844     return discoveredPrinterInfoList_.size();
845 }
846 
847 void PrintSystemData::ClearDiscoveredPrinterList()
848 {
849     std::lock_guard<std::mutex> lock(discoveredListMutex);
850     discoveredPrinterInfoList_.clear();
851 }
852 
853 std::map<std::string, std::shared_ptr<PrinterInfo>> PrintSystemData::GetDiscoveredPrinterInfo()
854 {
855     return discoveredPrinterInfoList_;
856 }
857 }  // namespace Print
858 }  // namespace OHOS