• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "print_user_data.h"
17 #include <fcntl.h>
18 #include <unistd.h>
19 #include <iostream>
20 #include <fstream>
21 #include <streambuf>
22 #include <algorithm>
23 #include <dirent.h>
24 #include <cstdlib>
25 #include <iomanip>
26 #include <json/json.h>
27 #include <filesystem>
28 
29 #include "print_log.h"
30 #include "print_constant.h"
31 #include "print_json_util.h"
32 
33 namespace OHOS {
34 namespace Print {
35 const uint32_t DEFAULT_BUFFER_SIZE_4K = 4096;
36 const uint32_t FD_INDEX_LEN = 4;
37 
38 static const std::string FILE_INDEX_DELIMITER = "_";
39 
RegisterPrinterCallback(const std::string & type,const sptr<IPrintCallback> & listener)40 void PrintUserData::RegisterPrinterCallback(const std::string &type, const sptr<IPrintCallback> &listener)
41 {
42     registeredListeners_[type] = listener;
43 }
44 
UnregisterPrinterCallback(const std::string & type)45 void PrintUserData::UnregisterPrinterCallback(const std::string &type)
46 {
47     auto iter = registeredListeners_.find(type);
48     if (iter != registeredListeners_.end()) {
49         registeredListeners_.erase(iter);
50     }
51 }
52 
SendPrinterEvent(const std::string & type,int event,const PrinterInfo & info)53 void PrintUserData::SendPrinterEvent(const std::string &type, int event, const PrinterInfo &info)
54 {
55     auto iter = registeredListeners_.find(type);
56     if (iter != registeredListeners_.end() && iter->second != nullptr) {
57         iter->second->OnCallback(event, info);
58     }
59 }
60 
AddToPrintJobList(const std::string jobId,const std::shared_ptr<PrintJob> & printjob)61 void PrintUserData::AddToPrintJobList(const std::string jobId, const std::shared_ptr<PrintJob> &printjob)
62 {
63     printJobList_.insert(std::make_pair(jobId, printjob));
64 }
65 
UpdateQueuedJobList(const std::string & jobId,const std::shared_ptr<PrintJob> & printJob,std::string jobOrderId)66 void PrintUserData::UpdateQueuedJobList(
67     const std::string &jobId, const std::shared_ptr<PrintJob> &printJob, std::string jobOrderId)
68 {
69     if (jobOrderId == "0") {
70         jobOrderList_.clear();
71     }
72     auto jobIt = printJobList_.find(jobId);
73     if (jobIt == printJobList_.end()) {
74         PRINT_HILOGE("invalid job id");
75         return;
76     }
77     printJobList_.erase(jobIt);
78 
79     if (queuedJobList_.find(jobId) != queuedJobList_.end()) {
80         queuedJobList_[jobId] = printJob;
81         jobOrderList_[jobOrderId] = jobId;
82     } else {
83         queuedJobList_.insert(std::make_pair(jobId, printJob));
84         jobOrderList_.insert(std::make_pair(jobOrderId, jobId));
85     }
86 }
87 
QueryPrintJobById(const std::string & printJobId,PrintJob & printJob)88 int32_t PrintUserData::QueryPrintJobById(const std::string &printJobId, PrintJob &printJob)
89 {
90     if (printJobList_.empty()) {
91         PRINT_HILOGE("printJobList is empty!");
92         return E_PRINT_INVALID_PRINTJOB;
93     }
94     auto jobIt = printJobList_.find(printJobId);
95     if (jobIt == printJobList_.end()) {
96         PRINT_HILOGW("no print job exists");
97         return E_PRINT_INVALID_PRINTJOB;
98     } else {
99         if (jobIt->second != nullptr) {
100             printJob = *jobIt->second;
101         }
102     }
103     PRINT_HILOGI("QueryPrintJobById End.");
104     return E_PRINT_NONE;
105 }
106 
QueryHistoryPrintJobById(const std::string & printJobId,PrintJob & printJob)107 int32_t PrintUserData::QueryHistoryPrintJobById(const std::string &printJobId, PrintJob &printJob)
108 {
109     PRINT_HILOGI("QueryHistoryPrintJobById Start.");
110     std::lock_guard<std::recursive_mutex> lock(userDataMutex_);
111     for (auto it = printHistoryJobList_.begin(); it != printHistoryJobList_.end(); ++it) {
112         if (it->second == nullptr) {
113             PRINT_HILOGE("printerHistoryJobList_ is null.");
114             return E_PRINT_INVALID_PRINTJOB;
115         }
116         for (auto innerIt = (it->second)->begin(); innerIt != (it->second)->end(); ++innerIt) {
117             if (innerIt->second == nullptr) {
118                 PRINT_HILOGE("printJob object is null.");
119                 return E_PRINT_INVALID_PRINTJOB;
120             }
121 
122             if (innerIt->first == printJobId) {
123                 printJob = *(innerIt->second);
124                 return E_PRINT_NONE;
125             }
126         }
127     }
128     return E_PRINT_INVALID_PRINTJOB;
129 }
130 
QueryAllActivePrintJob(std::vector<PrintJob> & printJobs)131 int32_t PrintUserData::QueryAllActivePrintJob(std::vector<PrintJob> &printJobs)
132 {
133     printJobs.clear();
134     for (auto iter : jobOrderList_) {
135         PRINT_HILOGI("QueryAllActivePrintJob queuedJobList_ jobOrderId: %{public}s, jobId: %{public}s",
136             iter.first.c_str(),
137             iter.second.c_str());
138         auto jobIt = queuedJobList_.find(iter.second);
139         if (jobIt == queuedJobList_.end()) {
140             PRINT_HILOGW("This job dose not exist.");
141             continue;
142         } else {
143             if (jobIt->second != nullptr) {
144                 printJobs.emplace_back(*jobIt->second);
145             }
146         }
147     }
148     PRINT_HILOGI("QueryAllActivePrintJob End.");
149     return E_PRINT_NONE;
150 }
151 
QueryAllPrintJob(std::vector<std::string> printerIds,std::vector<PrintJob> & printJobs)152 int32_t PrintUserData::QueryAllPrintJob(std::vector<std::string> printerIds, std::vector<PrintJob> &printJobs)
153 {
154     PRINT_HILOGI("QueryAllPrintJob Start.");
155     printJobs.clear();
156     for (auto iter : jobOrderList_) {
157         auto jobIt = queuedJobList_.find(iter.second);
158         if (jobIt == queuedJobList_.end()) {
159             PRINT_HILOGW("This job dose not exist.");
160             continue;
161         } else {
162             if (jobIt->second != nullptr) {
163                 printJobs.emplace_back(*jobIt->second);
164             }
165         }
166     }
167     for (std::string printerId : printerIds) {
168         InitPrintHistoryJobList(printerId);
169     }
170     for (auto it = printHistoryJobList_.begin(); it != printHistoryJobList_.end(); ++it) {
171         for (auto innerIt = (it->second)->begin(); innerIt != (it->second)->end(); ++innerIt) {
172             if (innerIt->second == nullptr) {
173                 return E_PRINT_INVALID_PRINTJOB;
174             }
175             printJobs.emplace_back(*(innerIt->second));
176         }
177     }
178     PRINT_HILOGI("QueryAllPrintJob End.");
179     return E_PRINT_NONE;
180 }
181 
SetUserId(int32_t userId)182 void PrintUserData::SetUserId(int32_t userId)
183 {
184     userId_ = userId;
185 }
186 
SetLastUsedPrinter(const std::string & printerId)187 int32_t PrintUserData::SetLastUsedPrinter(const std::string &printerId)
188 {
189     PRINT_HILOGI("begin SetLastUsedPrinter, printerId: %{private}s", printerId.c_str());
190     if (printerId.empty()) {
191         PRINT_HILOGE("printerId is empty");
192         return E_PRINT_INVALID_PARAMETER;
193     }
194     std::lock_guard<std::recursive_mutex> lock(userDataMutex_);
195     lastUsedPrinterId_ = printerId;
196 
197     DeletePrinterFromUsedPrinterList(printerId);
198     usedPrinterList_.push_front(printerId);
199     PRINT_HILOGI("put printer at the head of the queue, printerId: %{private}s", usedPrinterList_.front().c_str());
200     if (useLastUsedPrinterForDefault_) {
201         defaultPrinterId_ = printerId;
202         PRINT_HILOGI("set the last used printer as the default printer");
203     }
204     if (!SetUserDataToFile()) {
205         PRINT_HILOGE("SetUserDataToFile failed.");
206         return E_PRINT_SERVER_FAILURE;
207     }
208 
209     return E_PRINT_NONE;
210 }
211 
GetLastUsedPrinter()212 std::string PrintUserData::GetLastUsedPrinter()
213 {
214     std::lock_guard<std::recursive_mutex> lock(userDataMutex_);
215     return lastUsedPrinterId_;
216 }
217 
SetDefaultPrinter(const std::string & printerId,uint32_t type)218 int32_t PrintUserData::SetDefaultPrinter(const std::string &printerId, uint32_t type)
219 {
220     std::lock_guard<std::recursive_mutex> lock(userDataMutex_);
221     PRINT_HILOGI("begin SetDefaultPrinter");
222     PRINT_HILOGD("printerId: %{private}s", printerId.c_str());
223     PRINT_HILOGI("type: %{public}d", type);
224     if (type == DEFAULT_PRINTER_TYPE_SETTED_BY_USER) {
225         defaultPrinterId_ = printerId;
226         useLastUsedPrinterForDefault_ = false;
227     } else if (type == DEFAULT_PRINTER_TYPE_LAST_USED_PRINTER || type == DELETE_DEFAULT_PRINTER) {
228         defaultPrinterId_ = lastUsedPrinterId_;
229         useLastUsedPrinterForDefault_ = true;
230     } else if (type == DELETE_LAST_USED_PRINTER) {
231         defaultPrinterId_ = lastUsedPrinterId_;
232     }
233     PRINT_HILOGD("defaultPrinterId_: %{private}s", defaultPrinterId_.c_str());
234     if (!SetUserDataToFile()) {
235         PRINT_HILOGE("SetUserDataToFile failed.");
236         return E_PRINT_SERVER_FAILURE;
237     }
238 
239     return E_PRINT_NONE;
240 }
241 
GetDefaultPrinter()242 std::string PrintUserData::GetDefaultPrinter()
243 {
244     return defaultPrinterId_;
245 }
246 
CheckIfUseLastUsedPrinterForDefault()247 bool PrintUserData::CheckIfUseLastUsedPrinterForDefault()
248 {
249     PRINT_HILOGI("useLastUsedPrinterForDefault_: %{public}d", useLastUsedPrinterForDefault_);
250     return useLastUsedPrinterForDefault_;
251 }
252 
DeletePrinter(const std::string & printerId)253 void PrintUserData::DeletePrinter(const std::string &printerId)
254 {
255     DeletePrinterFromUsedPrinterList(printerId);
256     if (!strcmp(lastUsedPrinterId_.c_str(), printerId.c_str())) {
257         std::lock_guard<std::recursive_mutex> lock(userDataMutex_);
258         if (usedPrinterList_.size()) {
259             auto it = usedPrinterList_.begin();
260             lastUsedPrinterId_ = *it;
261             PRINT_HILOGI(
262                 "change last used printer for delete printer, printerId: %{private}s", lastUsedPrinterId_.c_str());
263         } else {
264             lastUsedPrinterId_ = "";
265             PRINT_HILOGW("last used printer is null");
266         }
267     }
268     if (!SetUserDataToFile()) {
269         PRINT_HILOGE("SetUserDataToFile failed.");
270         return;
271     }
272 }
273 
DeletePrinterFromUsedPrinterList(const std::string & printerId)274 void PrintUserData::DeletePrinterFromUsedPrinterList(const std::string &printerId)
275 {
276     std::lock_guard<std::recursive_mutex> lock(userDataMutex_);
277     for (auto it = usedPrinterList_.begin(); it != usedPrinterList_.end(); ++it) {
278         std::string id = *it;
279         PRINT_HILOGI("printerId in usedPrinterList_: %{private}s", id.c_str());
280         if (!strcmp(id.c_str(), printerId.c_str())) {
281             PRINT_HILOGI("find printerId in used printer list.");
282             usedPrinterList_.erase(it);
283             break;
284         }
285     }
286 }
287 
ParseUserData()288 bool PrintUserData::ParseUserData()
289 {
290     std::string fileData = "";
291     if (!GetFileData(fileData)) {
292         PRINT_HILOGW("get file data failed");
293         return false;
294     }
295     Json::Value jsonObject;
296     if (CheckFileData(fileData, jsonObject)) {
297         ParseUserDataFromJson(jsonObject);
298     }
299     return true;
300 }
301 
ParseUserDataFromJson(Json::Value & jsonObject)302 void PrintUserData::ParseUserDataFromJson(Json::Value &jsonObject)
303 {
304     if (!PrintJsonUtil::IsMember(jsonObject, "print_user_data")) {
305         PRINT_HILOGW("can not find print_user_data");
306         return;
307     }
308     PRINT_HILOGI("userId_: %{public}d", userId_);
309     Json::Value userDataList = jsonObject["print_user_data"];
310     if (!PrintJsonUtil::IsMember(userDataList, std::to_string(userId_)) ||
311         !userDataList[std::to_string(userId_)].isObject()) {
312         PRINT_HILOGW("can not find current userId");
313         SetUserDataToFile();
314     }
315     Json::Value userData = userDataList[std::to_string(userId_)];
316     if (!PrintJsonUtil::IsMember(userData, "defaultPrinter") || !userData["defaultPrinter"].isString()) {
317         PRINT_HILOGW("can not find defaultPrinter");
318         return;
319     }
320     defaultPrinterId_ = userData["defaultPrinter"].asString();
321     if (!PrintJsonUtil::IsMember(userData, "lastUsedPrinter") || !userData["lastUsedPrinter"].isString()) {
322         PRINT_HILOGW("can not find lastUsedPrinter");
323         return;
324     }
325     lastUsedPrinterId_ = userData["lastUsedPrinter"].asString();
326     if (!PrintJsonUtil::IsMember(userData, "useLastUsedPrinterForDefault") ||
327         !userData["useLastUsedPrinterForDefault"].isBool()) {
328         PRINT_HILOGW("can not find useLastUsedPrinterForDefault");
329         return;
330     }
331     useLastUsedPrinterForDefault_ = userData["useLastUsedPrinterForDefault"].asBool();
332     if (!PrintJsonUtil::IsMember(userData, "usedPrinterList") || !userData["usedPrinterList"].isArray()) {
333         PRINT_HILOGW("can not find usedPrinterList");
334         return;
335     }
336     if (!ConvertJsonToUsedPrinterList(userData)) {
337         PRINT_HILOGW("convert json to usedPrinterList failed");
338         return;
339     }
340     PRINT_HILOGI(
341         "defaultPrinterId_: %{private}s, lastUsedPrinterId_: %{private}s, useLastUsedPrinterForDefault_: %{public}d",
342         defaultPrinterId_.c_str(),
343         lastUsedPrinterId_.c_str(),
344         useLastUsedPrinterForDefault_);
345 }
346 
ConvertJsonToUsedPrinterList(Json::Value & userData)347 bool PrintUserData::ConvertJsonToUsedPrinterList(Json::Value &userData)
348 {
349     Json::Value usedPrinterListJson = userData["usedPrinterList"];
350     uint32_t jsonSize = usedPrinterListJson.size();
351     if (jsonSize > MAX_PRINTER_SIZE) {
352         PRINT_HILOGE("usedPrinterList size is illegal");
353         return false;
354     }
355     for (uint32_t i = 0; i < jsonSize; i++) {
356         if (!usedPrinterListJson[i].isString()) {
357             PRINT_HILOGW("usedPrinterListJson item is not string");
358             return false;
359         }
360         usedPrinterList_.push_back(usedPrinterListJson[i].asString());
361     }
362     uint32_t size = usedPrinterList_.size();
363     PRINT_HILOGI("usedPrinterList_ size: %{public}d", size);
364     for (auto it = usedPrinterList_.begin(); it != usedPrinterList_.end(); ++it) {
365         PRINT_HILOGD("printerId in usedPrinterList_: %{private}s", it->c_str());
366     }
367     return true;
368 }
369 
ConvertUsedPrinterListToJson(Json::Value & usedPrinterListJson)370 void PrintUserData::ConvertUsedPrinterListToJson(Json::Value &usedPrinterListJson)
371 {
372     for (auto iter = usedPrinterList_.begin(); iter != usedPrinterList_.end(); ++iter) {
373         usedPrinterListJson.append(*iter);
374     }
375 }
376 
GetFileData(std::string & fileData)377 bool PrintUserData::GetFileData(std::string &fileData)
378 {
379     PRINT_HILOGI("begin GetFileData");
380     std::string userDataFilePath = PRINTER_SERVICE_FILE_PATH + "/" + PRINT_USER_DATA_FILE;
381     std::ifstream ifs(userDataFilePath.c_str(), std::ios::in | std::ios::binary);
382     if (!ifs.is_open()) {
383         PRINT_HILOGW("open printer list file fail");
384         char realPidFile[PATH_MAX] = {};
385         if (realpath(PRINTER_SERVICE_FILE_PATH.c_str(), realPidFile) == nullptr) {
386             PRINT_HILOGE("The realPidFile is null, errno:%{public}s", std::to_string(errno).c_str());
387             return false;
388         }
389         FILE *file = fopen(userDataFilePath.c_str(), "w+");
390         if (file == nullptr) {
391             PRINT_HILOGW("Failed to open file errno: %{public}s", std::to_string(errno).c_str());
392             return false;
393         }
394         Json::Value userDataJson;
395         Json::Value jsonObject;
396         jsonObject["version"] = PRINT_USER_DATA_VERSION;
397         jsonObject["print_user_data"] = userDataJson;
398         fileData = PrintJsonUtil::WriteString(jsonObject);
399         size_t jsonLength = fileData.length();
400         size_t writeLength = fwrite(fileData.c_str(), 1, strlen(fileData.c_str()), file);
401         int fcloseResult = fclose(file);
402         if (fcloseResult != 0 || writeLength < 0 || writeLength != jsonLength) {
403             PRINT_HILOGE("File Operation Failure.");
404             return false;
405         }
406     } else {
407         fileData.assign((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
408         ifs.close();
409     }
410     return true;
411 }
412 
SetUserDataToFile()413 bool PrintUserData::SetUserDataToFile()
414 {
415     PRINT_HILOGI("begin SetUserDataToFile");
416     std::string fileData = "";
417     if (!GetFileData(fileData)) {
418         PRINT_HILOGW("get file data failed");
419         return false;
420     }
421     Json::Value jsonObject;
422     if (CheckFileData(fileData, jsonObject)) {
423         PRINT_HILOGI("userId_: %{private}d", userId_);
424         Json::Value userData;
425         userData["defaultPrinter"] = defaultPrinterId_;
426         userData["lastUsedPrinter"] = lastUsedPrinterId_;
427         userData["useLastUsedPrinterForDefault"] = useLastUsedPrinterForDefault_;
428         Json::Value usedPrinterListJson;
429         ConvertUsedPrinterListToJson(usedPrinterListJson);
430         userData["usedPrinterList"] = usedPrinterListJson;
431         jsonObject["print_user_data"][std::to_string(userId_)] = userData;
432         std::string temp = PrintJsonUtil::WriteString(jsonObject);
433         PRINT_HILOGD("json temp: %{public}s", temp.c_str());
434         char realPidFile[PATH_MAX] = {};
435         std::string userDataFilePath = PRINTER_SERVICE_FILE_PATH + "/" + PRINT_USER_DATA_FILE;
436         if (realpath(PRINTER_SERVICE_FILE_PATH.c_str(), realPidFile) == nullptr) {
437             PRINT_HILOGE("The realPidFile is null, errno:%{public}s", std::to_string(errno).c_str());
438             return false;
439         }
440         FILE *file = fopen(userDataFilePath.c_str(), "w+");
441         if (file == nullptr) {
442             PRINT_HILOGW("Failed to open file errno: %{public}s", std::to_string(errno).c_str());
443             return false;
444         }
445         std::string jsonString = PrintJsonUtil::WriteString(jsonObject);
446         size_t jsonLength = jsonString.length();
447         size_t writeLength = fwrite(jsonString.c_str(), 1, strlen(jsonString.c_str()), file);
448         int fcloseResult = fclose(file);
449         if (fcloseResult != 0 || writeLength < 0) {
450             PRINT_HILOGE("File Operation Failure.");
451             return false;
452         }
453         PRINT_HILOGI("SetUserDataToFile finished");
454         return writeLength == jsonLength;
455     }
456     return true;
457 }
458 
CheckFileData(std::string & fileData,Json::Value & jsonObject)459 bool PrintUserData::CheckFileData(std::string &fileData, Json::Value &jsonObject)
460 {
461     if (!PrintJsonUtil::Parse(fileData, jsonObject)) {
462         PRINT_HILOGW("json accept fail");
463         return false;
464     }
465     if (!PrintJsonUtil::IsMember(jsonObject, "version") || !jsonObject["version"].isString()) {
466         PRINT_HILOGW("can not find version");
467         return false;
468     }
469     std::string version = jsonObject["version"].asString();
470     PRINT_HILOGI("json version: %{public}s", version.c_str());
471     if (version != PRINT_USER_DATA_VERSION || !PrintJsonUtil::IsMember(jsonObject, "print_user_data")) {
472         PRINT_HILOGW("can not find print_user_data");
473         return false;
474     }
475     return true;
476 }
477 
FlushCacheFileToUserData(const std::string & jobId)478 bool PrintUserData::FlushCacheFileToUserData(const std::string &jobId)
479 {
480     PRINT_HILOGI("FlushCacheFileToUserData Start.");
481     PrintJob printJob;
482     if (QueryQueuedPrintJobById(jobId, printJob) != E_PRINT_NONE) {
483         PRINT_HILOGE("Can not find print job");
484         return false;
485     }
486     std::vector<uint32_t> fdList;
487     printJob.GetFdList(fdList);
488     PRINT_HILOGI("fdList size: %{public}d", fdList.size());
489     bool ret = false;
490     for (uint32_t i = 0; i < fdList.size(); i++) {
491         int32_t srcFd = dup(static_cast<int32_t>(fdList[i]));
492         ret = srcFd >= 0;
493         if (ret) {
494             ret = FlushCacheFile(srcFd, printJob.GetJobId(), i);
495             close(srcFd);
496         }
497         if (!ret) {
498             PRINT_HILOGE("flush cache file failed, fd: %{public}d.", srcFd);
499             DeleteCacheFileFromUserData(jobId);
500             break;
501         }
502     }
503     return ret;
504 }
505 
FlushCacheFile(int32_t fd,const std::string jobId,uint32_t index)506 bool PrintUserData::FlushCacheFile(int32_t fd, const std::string jobId, uint32_t index)
507 {
508     if (lseek(fd, 0, SEEK_SET) != 0) {
509         PRINT_HILOGE("Error seeking to the beginning of the file");
510         return false;
511     }
512     char cachePath[PATH_MAX] = { 0 };
513     std::string cacheDir = ObtainUserCacheDirectory();
514     if (realpath(cacheDir.c_str(), cachePath) == nullptr) {
515         PRINT_HILOGE("The real cache dir is null, errno:%{public}s", std::to_string(errno).c_str());
516         return false;
517     }
518     cacheDir = cachePath;
519     std::ostringstream cacheFileStream;
520     cacheFileStream << cacheDir << "/" << jobId << "_" << std::setw(FD_INDEX_LEN) << std::setfill('0') << index;
521     std::string cacheFilePath = cacheFileStream.str();
522     int32_t cacheFileFd = open(cacheFilePath.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0644);
523     if (cacheFileFd == -1) {
524         PRINT_HILOGE("Open file failed");
525         return false;
526     }
527 
528     char buffer[DEFAULT_BUFFER_SIZE_4K] = { 0 };
529     ssize_t bytesRead = -1;
530     bool ret = true;
531     while ((bytesRead = read(fd, buffer, sizeof(buffer))) > 0) {
532         if (write(cacheFileFd, buffer, bytesRead) < bytesRead) {
533             ret = false;
534             PRINT_HILOGE("write file failed");
535             break;
536         }
537     }
538     if (bytesRead == -1) {
539         PRINT_HILOGE("read file failed");
540         ret = false;
541     }
542     if (lseek(fd, 0, SEEK_SET) != 0) {
543         PRINT_HILOGE("Error seeking to the beginning of the file");
544         ret = false;
545     }
546     close(cacheFileFd);
547     return ret;
548 }
549 
DeleteCacheFileFromUserData(const std::string & jobId)550 bool PrintUserData::DeleteCacheFileFromUserData(const std::string &jobId)
551 {
552     PRINT_HILOGI("DeleteCacheFileFromUserData Start.");
553     if (jobId.empty()) {
554         PRINT_HILOGE("empty jobId, not find files");
555         return false;
556     }
557     char cachePath[PATH_MAX] = { 0 };
558     std::string cacheDir = ObtainUserCacheDirectory();
559     if (realpath(cacheDir.c_str(), cachePath) == nullptr) {
560         PRINT_HILOGE("The real cache dir is null, errno:%{public}s", std::to_string(errno).c_str());
561         return false;
562     }
563     cacheDir = cachePath;
564     DIR *dir = opendir(cachePath);
565     if (dir == nullptr) {
566         PRINT_HILOGE("Failed to open Dir: %{private}s", cachePath);
567         return false;
568     }
569     struct dirent *file;
570     std::vector<std::string> fileNames;
571     std::string cacheFile;
572     while ((file = readdir(dir)) != nullptr) {
573         if (strncmp(file->d_name, jobId.c_str(), jobId.length()) == 0) {
574             cacheFile = cacheDir + '/' + std::string(file->d_name);
575             if (realpath(cacheFile.c_str(), cachePath) == nullptr) {
576                 PRINT_HILOGE("The realFile is null, errno:%{public}s", strerror(errno));
577                 continue;
578             }
579             if (std::remove(cachePath) != 0) {
580                 PRINT_HILOGW("error deleting file %{public}s err: %{public}s", cachePath, strerror(errno));
581             }
582         }
583     }
584     closedir(dir);
585     return true;
586 }
587 
OpenCacheFileFd(const std::string & jobId,std::vector<uint32_t> & fdList)588 bool PrintUserData::OpenCacheFileFd(const std::string &jobId, std::vector<uint32_t> &fdList)
589 {
590     PRINT_HILOGI("OpenCacheFileFd Start.");
591     fdList.clear();
592     char cachePath[PATH_MAX] = { 0 };
593     std::string cacheDir = ObtainUserCacheDirectory();
594     if (realpath(cacheDir.c_str(), cachePath) == nullptr) {
595         PRINT_HILOGE("The real cache dir is null, errno:%{public}s", std::to_string(errno).c_str());
596         return false;
597     }
598     cacheDir = cachePath;
599 
600     DIR *dir = opendir(cacheDir.c_str());
601     // dir real path
602     if (dir == nullptr) {
603         PRINT_HILOGE("Failed to find history file");
604         return false;
605     }
606     if (access(cacheDir.c_str(), R_OK) != 0) {
607         PRINT_HILOGE("Failed to find history file");
608         closedir(dir);
609         return false;
610     }
611     struct dirent *file;
612     std::vector<std::string> fileNames;
613     while ((file = readdir(dir)) != nullptr) {
614         if (strncmp(file->d_name, jobId.c_str(), jobId.length()) == 0) {
615             fileNames.push_back(std::string(file->d_name));
616         }
617     }
618 
619     std::string cacheFile;
620     bool ret = true;
621     for (auto fileName : fileNames) {
622         cacheFile = cacheDir + "/" + fileName;
623         if (realpath(cacheFile.c_str(), cachePath) == nullptr) {
624             PRINT_HILOGE("The realFile is null, errno:%{public}s", std::to_string(errno).c_str());
625             ret = false;
626             break;
627         }
628         int32_t fd = open(cachePath, O_RDONLY);
629         if (fd < 0) {
630             PRINT_HILOGE("open file failed, errno:%{public}s", std::to_string(errno).c_str());
631             ret = false;
632             break;
633         }
634         fdList.push_back(fd);
635     }
636     if (!ret) {
637         for (auto fd : fdList) { close(fd); }
638     }
639     closedir(dir);
640     return ret;
641 }
642 
ObtainUserCacheDirectory()643 std::string PrintUserData::ObtainUserCacheDirectory()
644 {
645     std::ostringstream oss;
646     oss << "/data/service/el2/" << userId_ << "/print_service";
647     return oss.str();
648 }
649 
QueryQueuedPrintJobById(const std::string & printJobId,PrintJob & printJob)650 int32_t PrintUserData::QueryQueuedPrintJobById(const std::string &printJobId, PrintJob &printJob)
651 {
652     PRINT_HILOGI("QueryQueuedPrintJobById Start.");
653     if (queuedJobList_.empty()) {
654         PRINT_HILOGE("printJobList is empty!");
655         return E_PRINT_INVALID_PRINTJOB;
656     }
657     auto jobIt = queuedJobList_.find(printJobId);
658     if (jobIt == queuedJobList_.end()) {
659         PRINT_HILOGW("no print job exists");
660         return E_PRINT_INVALID_PRINTJOB;
661     }
662     if (jobIt->second == nullptr) {
663         PRINT_HILOGW("no print job exists");
664         return E_PRINT_INVALID_PRINTJOB;
665     }
666     printJob = *jobIt->second;
667     PRINT_HILOGD("QueryQueuedPrintJobById End.");
668     return E_PRINT_NONE;
669 }
670 
AddPrintJobToHistoryList(const std::string & printerId,const std::string & jobId,const std::shared_ptr<PrintJob> & printJob)671 bool PrintUserData::AddPrintJobToHistoryList(const std::string &printerId,
672     const std::string &jobId, const std::shared_ptr<PrintJob> &printJob)
673 {
674     PRINT_HILOGI("AddPrintJobToHistoryList Start.");
675     if (printJob == nullptr) {
676         PRINT_HILOGE("printJob is null.");
677         return false;
678     }
679     InitPrintHistoryJobList(printerId);
680     auto& printerHistroyJobList = printHistoryJobList_[printerId];
681     if (!printerHistroyJobList) {
682         PRINT_HILOGE("printerHistroyJobList is null.");
683         return false;
684     }
685     std::string oldOption = printJob->GetOption();
686     PRINT_HILOGD("Print job option: %{public}s", oldOption.c_str());
687     Json::Value infoJson;
688     if (!PrintJsonUtil::Parse(oldOption, infoJson)) {
689         PRINT_HILOGW("old option not accepted");
690         return false;
691     }
692     infoJson["isHistory"] = true;
693     std::string updatedOption = PrintJsonUtil::WriteString(infoJson);
694     PRINT_HILOGD("Updated print job option: %{public}s", updatedOption.c_str());
695     printJob->SetOption(updatedOption);
696     auto it = printerHistroyJobList->begin();
697     // erase the history print jobs more than 500
698     while (printerHistroyJobList->size() > MAX_HISTORY_JOB_NUM) {
699         it = printerHistroyJobList->erase(it);
700     }
701     if ((printerHistroyJobList->insert(std::make_pair(jobId, printJob))).second) {
702         FlushPrintHistoryJobFile(printerId);
703         return true;
704     }
705     return false;
706 }
707 
FlushPrintHistoryJobFile(const std::string & printerId)708 void PrintUserData::FlushPrintHistoryJobFile(const std::string &printerId)
709 {
710     PRINT_HILOGI("FlushPrintHistoryJobFile Start.");
711     std::string filePath = ObtainUserCacheDirectory();
712     char cachePath[PATH_MAX] = { 0 };
713     if (realpath(filePath.c_str(), cachePath) == nullptr) {
714         PRINT_HILOGE("The real cache dir is null, errno:%{public}s", std::to_string(errno).c_str());
715         return;
716     }
717     filePath.assign(cachePath);
718     std::string printHistoryJobFilePath = filePath + "/" + printerId + ".json";
719     if (printHistoryJobList_.find(printerId) == printHistoryJobList_.end()) {
720         PRINT_HILOGE("printHistoryJobList_[printerId] is null.");
721         std::filesystem::remove(printHistoryJobFilePath);
722         return;
723     }
724 
725     FILE *printHistoryJobFile = fopen(printHistoryJobFilePath.c_str(), "w+");
726     if (printHistoryJobFile == nullptr) {
727         PRINT_HILOGW("Failed to open file errno: %{public}s", std::to_string(errno).c_str());
728         return;
729     }
730     std::string jsonString = ParsePrintHistoryJobListToJsonString(printerId);
731     size_t jsonLength = jsonString.length();
732     size_t writeLength = fwrite(jsonString.c_str(), 1, strlen(jsonString.c_str()), printHistoryJobFile);
733     int fcloseResult = fclose(printHistoryJobFile);
734     if (fcloseResult != 0) {
735         PRINT_HILOGE("Close File Failure.");
736         return;
737     }
738     PRINT_HILOGI("FlushPrintHistoryJobFile End.");
739     if (writeLength < 0 || writeLength != jsonLength) {
740         PRINT_HILOGE("SavePrintHistoryJobFile error");
741     }
742 }
743 
ParsePrintHistoryJobListToJsonString(const std::string & printerId)744 std::string PrintUserData::ParsePrintHistoryJobListToJsonString(const std::string &printerId)
745 {
746     PRINT_HILOGI("ParsePrintHistoryJobListToJsonString Start.");
747     Json::Value allPrintJobJson;
748     for (auto it = printHistoryJobList_.begin(); it != printHistoryJobList_.end(); ++it) {
749         if (it->first == printerId) {
750             if (it->second == nullptr) {
751                 return "";
752             }
753 
754             Json::Value printJobJson;
755             for (auto innerIt = (it->second)->begin(); innerIt != (it->second)->end(); innerIt++) {
756                 printJobJson[innerIt->first] = (innerIt->second)->ConvertToJsonObject();
757             }
758             allPrintJobJson[printerId] = printJobJson;
759             return PrintJsonUtil::WriteString(allPrintJobJson);
760         }
761     }
762     return "";
763 }
764 
GetPrintHistoryJobFromFile(const std::string & printerId)765 bool PrintUserData::GetPrintHistoryJobFromFile(const std::string &printerId)
766 {
767     PRINT_HILOGI("GetPrintHistoryJobFromFile Start.");
768     char cachePath[PATH_MAX] = { 0 };
769     std::string filePath = ObtainUserCacheDirectory();
770     if (realpath(filePath.c_str(), cachePath) == nullptr) {
771         PRINT_HILOGE("The real cache dir is null, errno:%{public}s", std::to_string(errno).c_str());
772         return false;
773     }
774     filePath.assign(cachePath);
775     std::string printHistoryJobFilePath = filePath + "/" + printerId + ".json";
776     Json::Value printHistoryJobJson;
777     if (GetJsonObjectFromFile(printHistoryJobJson, printHistoryJobFilePath, printerId) &&
778         ParseJsonObjectToPrintHistory(printHistoryJobJson, printerId)) {
779         PRINT_HILOGI("parse print history job file success");
780         return true;
781     }
782     return false;
783 }
784 
GetJsonObjectFromFile(Json::Value & jsonObject,const std::string & filePath,const std::string & printerId)785 bool PrintUserData::GetJsonObjectFromFile(Json::Value &jsonObject,
786     const std::string &filePath, const std::string &printerId)
787 {
788     PRINT_HILOGI("GetJsonObjectFromFile Start.");
789     std::ifstream ifs(filePath.c_str(), std::ios::in | std::ios::binary);
790     if (!ifs.is_open()) {
791         PRINT_HILOGW("open printer list file fail");
792         return false;
793     }
794     if (ifs.peek() == std::ifstream::traits_type::eof()) {
795         PRINT_HILOGW("file is empty.");
796         ifs.close();
797         return false;
798     }
799     if (!PrintJsonUtil::ParseFromStream(ifs, jsonObject)) {
800         PRINT_HILOGW("json accept fail");
801         ifs.close();
802         return false;
803     }
804     ifs.close();
805     if (!PrintJsonUtil::IsMember(jsonObject, printerId)) {
806         PRINT_HILOGW("can not find printer history job");
807         return false;
808     }
809     return true;
810 }
811 
ParseJsonObjectToPrintHistory(Json::Value & jsonObject,const std::string & printerId)812 bool PrintUserData::ParseJsonObjectToPrintHistory(Json::Value &jsonObject, const std::string &printerId)
813 {
814     PRINT_HILOGI("ParseJsonObjectToPrintHistory Start.");
815     if (!printHistoryJobList_[printerId]) {
816         PRINT_HILOGE("printerHistoryJobList_ is not exist.");
817         return false;
818     }
819     if (!PrintJsonUtil::IsMember(jsonObject, printerId) || !jsonObject[printerId].isObject()) {
820         PRINT_HILOGE("This printer has no historical jobs.");
821         return false;
822     }
823 
824     for (const auto& jobId : jsonObject[printerId].getMemberNames()) {
825         const Json::Value& printJobInfoJson = jsonObject[printerId][jobId];
826         auto& printHistoryJob = (*(printHistoryJobList_[printerId]))[jobId];
827         if (!printHistoryJob) {
828             PRINT_HILOGE("printHistoryJob is not exist.");
829             printHistoryJob = std::make_shared<PrintJob>();
830         }
831         PRINT_HILOGI("printHistoryJob is created.");
832         if (!ParseJsonObjectToPrintJob(printJobInfoJson, printHistoryJob)) {
833             continue;
834         }
835     }
836     return true;
837 }
838 
ParseJsonObjectToPrintJob(const Json::Value & printJobInfoJson,std::shared_ptr<PrintJob> & printHistoryJob)839 bool PrintUserData::ParseJsonObjectToPrintJob(
840     const Json::Value &printJobInfoJson, std::shared_ptr<PrintJob> &printHistoryJob)
841 {
842     if (!PrintJsonUtil::IsMember(printJobInfoJson, "jobId") || !printJobInfoJson["jobId"].isString() ||
843         !PrintJsonUtil::IsMember(printJobInfoJson, "printerId") || !printJobInfoJson["printerId"].isString()) {
844         PRINT_HILOGE("Can not find necessary params.");
845         return false;
846     }
847     printHistoryJob->SetJobId(printJobInfoJson["jobId"].asString());
848     printHistoryJob->SetPrinterId(printJobInfoJson["printerId"].asString());
849     if (PrintJsonUtil::IsMember(printJobInfoJson, "jobState") && printJobInfoJson["jobState"].isInt()) {
850         printHistoryJob->SetJobState(printJobInfoJson["jobState"].asInt());
851     }
852     if (PrintJsonUtil::IsMember(printJobInfoJson, "subState") && printJobInfoJson["subState"].isInt()) {
853         printHistoryJob->SetSubState(printJobInfoJson["subState"].asInt());
854     }
855     if (PrintJsonUtil::IsMember(printJobInfoJson, "copyNumber") && printJobInfoJson["copyNumber"].isInt()) {
856         printHistoryJob->SetCopyNumber(printJobInfoJson["copyNumber"].asInt());
857     }
858     if (PrintJsonUtil::IsMember(printJobInfoJson, "isSequential") && printJobInfoJson["isSequential"].isBool()) {
859         printHistoryJob->SetIsSequential(printJobInfoJson["isSequential"].asBool());
860     }
861     if (PrintJsonUtil::IsMember(printJobInfoJson, "isLandscape") && printJobInfoJson["isLandscape"].isBool()) {
862         printHistoryJob->SetIsLandscape(printJobInfoJson["isLandscape"].asBool());
863     }
864     if (PrintJsonUtil::IsMember(printJobInfoJson, "colorMode") && printJobInfoJson["colorMode"].isInt()) {
865         printHistoryJob->SetColorMode(printJobInfoJson["colorMode"].asInt());
866     }
867     if (PrintJsonUtil::IsMember(printJobInfoJson, "duplexMode") && printJobInfoJson["duplexMode"].isInt()) {
868         printHistoryJob->SetDuplexMode(printJobInfoJson["duplexMode"].asInt());
869     }
870 
871     ParseOptionalJsonObjectToPrintJob(printJobInfoJson, printHistoryJob);
872     return true;
873 }
874 
ParseOptionalJsonObjectToPrintJob(const Json::Value & printJobInfoJson,std::shared_ptr<PrintJob> & printHistoryJob)875 void PrintUserData::ParseOptionalJsonObjectToPrintJob(
876     const Json::Value &printJobInfoJson, std::shared_ptr<PrintJob> &printHistoryJob)
877 {
878     if (PrintJsonUtil::IsMember(printJobInfoJson, "pageRange") && printJobInfoJson["pageRange"].isObject()) {
879         printHistoryJob->SetPageRange(ParseJsonObjectToPrintRange(printJobInfoJson["pageRange"]));
880     }
881     if (PrintJsonUtil::IsMember(printJobInfoJson, "pageSize") && printJobInfoJson["pageSize"].isObject()) {
882         printHistoryJob->SetPageSize(ParseJsonObjectToPrintPageSize(printJobInfoJson["pageSize"]));
883     }
884     if (CheckOptionalParam(printJobInfoJson, "hasmargin") &&
885         PrintJsonUtil::IsMember(printJobInfoJson, "margin") && printJobInfoJson["margin"].isObject()) {
886         printHistoryJob->SetMargin(ParseJsonObjectToMargin(printJobInfoJson["margin"]));
887     }
888     if (CheckOptionalParam(printJobInfoJson, "hasPreview") &&
889         PrintJsonUtil::IsMember(printJobInfoJson, "preview") && printJobInfoJson["preview"].isObject()) {
890         printHistoryJob->SetPreview(ParseJsonObjectToPrintPreviewAttribute(printJobInfoJson["preview"]));
891     }
892     if (CheckOptionalParam(printJobInfoJson, "hasOption") &&
893         PrintJsonUtil::IsMember(printJobInfoJson, "option") && printJobInfoJson["option"].isString()) {
894         printHistoryJob->SetOption(printJobInfoJson["option"].asString());
895     }
896 }
897 
ParseJsonObjectToPrintPreviewAttribute(const Json::Value & jsonObject)898 PrintPreviewAttribute PrintUserData::ParseJsonObjectToPrintPreviewAttribute(const Json::Value &jsonObject)
899 {
900     PrintPreviewAttribute printPreviewAttribute;
901     if (CheckOptionalParam(jsonObject, "hasResult_") &&
902         PrintJsonUtil::IsMember(jsonObject, "result_") && jsonObject["result_"].isInt()) {
903         printPreviewAttribute.SetResult(jsonObject["result_"].asInt());
904     }
905     if (PrintJsonUtil::IsMember(jsonObject, "previewRange_") && jsonObject["previewRange_"].isObject()) {
906         printPreviewAttribute.SetPreviewRange(
907             ParseJsonObjectToPrintRange(jsonObject["previewRange_"]));
908     }
909     return printPreviewAttribute;
910 }
911 
ParseJsonObjectToPrintPageSize(const Json::Value & jsonObject)912 PrintPageSize PrintUserData::ParseJsonObjectToPrintPageSize(const Json::Value &jsonObject)
913 {
914     PrintPageSize pageSize;
915 
916     if (PrintJsonUtil::IsMember(jsonObject, "id_") && jsonObject["id_"].isString()) {
917         pageSize.SetId(jsonObject["id_"].asString());
918     }
919     if (PrintJsonUtil::IsMember(jsonObject, "name_") && jsonObject["name_"].isString()) {
920         pageSize.SetName(jsonObject["name_"].asString());
921     }
922     if (PrintJsonUtil::IsMember(jsonObject, "width_") && jsonObject["width_"].isInt()) {
923         pageSize.SetWidth(jsonObject["width_"].asInt());
924     }
925     if (PrintJsonUtil::IsMember(jsonObject, "height_") && jsonObject["height_"].isInt()) {
926         pageSize.SetHeight(jsonObject["height_"].asInt());
927     }
928     return pageSize;
929 }
930 
ParseJsonObjectToPrintRange(const Json::Value & jsonObject)931 PrintRange PrintUserData::ParseJsonObjectToPrintRange(const Json::Value &jsonObject)
932 {
933     PrintRange printRange;
934     if (CheckOptionalParam(jsonObject, "hasStartPage_") &&
935         PrintJsonUtil::IsMember(jsonObject, "startPage") && jsonObject["startPage"].isInt()) {
936         printRange.SetStartPage(jsonObject["startPage"].asInt());
937     }
938     if (CheckOptionalParam(jsonObject, "hasEndPage_") &&
939         PrintJsonUtil::IsMember(jsonObject, "endPage") && jsonObject["endPage"].isInt()) {
940         printRange.SetStartPage(jsonObject["endPage"].asInt());
941     }
942     if (PrintJsonUtil::IsMember(jsonObject, "pages") && jsonObject["pages"].isArray()) {
943         std::vector<uint32_t> pages;
944         Json::Value pagesJsonObject = jsonObject["pages"];
945         for (const auto& item : pagesJsonObject) {
946             if (item.isInt()) {
947                 pages.push_back(item.asInt());
948             }
949         }
950         printRange.SetPages(pages);
951     }
952     return printRange;
953 }
954 
ParseJsonObjectToMargin(const Json::Value & jsonObject)955 PrintMargin PrintUserData::ParseJsonObjectToMargin(const Json::Value &jsonObject)
956 {
957     PrintMargin margin;
958     if (CheckOptionalParam(jsonObject, "hasTop_") &&
959         PrintJsonUtil::IsMember(jsonObject, "top_") && jsonObject["top_"].isInt()) {
960         margin.SetTop(jsonObject["top_"].asInt());
961     }
962     if (CheckOptionalParam(jsonObject, "hasLeft_") &&
963         PrintJsonUtil::IsMember(jsonObject, "left_") && jsonObject["left_"].isInt()) {
964         margin.SetTop(jsonObject["left_"].asInt());
965     }
966     if (CheckOptionalParam(jsonObject, "hasRight_") &&
967         PrintJsonUtil::IsMember(jsonObject, "right_") && jsonObject["right_"].isInt()) {
968         margin.SetTop(jsonObject["right_"].asInt());
969     }
970     if (CheckOptionalParam(jsonObject, "hasBottom_") &&
971         PrintJsonUtil::IsMember(jsonObject, "bottom_") && jsonObject["bottom_"].isInt()) {
972         margin.SetTop(jsonObject["bottom_"].asInt());
973     }
974     return margin;
975 }
976 
CheckOptionalParam(const Json::Value & jsonObject,const std::string & param)977 bool PrintUserData::CheckOptionalParam(const Json::Value &jsonObject, const std::string &param)
978 {
979     if (PrintJsonUtil::IsMember(jsonObject, param) && jsonObject[param].isBool() &&
980         jsonObject[param].asBool()) {
981         return true;
982     }
983     return false;
984 }
985 
DeletePrintJobFromHistoryList(const std::string & jobId)986 bool PrintUserData::DeletePrintJobFromHistoryList(const std::string &jobId)
987 {
988     PRINT_HILOGI("DeletePrintJobFromHistoryList Start.");
989     std::lock_guard<std::recursive_mutex> lock(userDataMutex_);
990     for (const auto& [printerId, printerHistoryJobMap] : printHistoryJobList_) {
991         if (!printerHistoryJobMap) {
992             PRINT_HILOGE("printerHistoryJobMap is not exist.");
993             continue;
994         }
995         auto printJob = printerHistoryJobMap->find(jobId);
996         if (printJob != printerHistoryJobMap->end()) {
997             std::string curPrinterId = printerId;
998             printerHistoryJobMap->erase(jobId);
999             DeleteCacheFileFromUserData(jobId);
1000             if (printerHistoryJobMap->empty()) {
1001                 printHistoryJobList_.erase(curPrinterId);
1002             }
1003             FlushPrintHistoryJobFile(curPrinterId);
1004             return true;
1005         }
1006     }
1007     return false;
1008 }
1009 
DeletePrintJobFromHistoryListByPrinterId(const std::string & printerId)1010 bool PrintUserData::DeletePrintJobFromHistoryListByPrinterId(const std::string &printerId)
1011 {
1012     PRINT_HILOGI("DeletePrintJobFromHistoryListByPrinterId Start.");
1013     InitPrintHistoryJobList(printerId);
1014     std::lock_guard<std::recursive_mutex> lock(userDataMutex_);
1015     for (auto it = printHistoryJobList_.begin(); it != printHistoryJobList_.end(); ++it) {
1016         if (it->first == printerId && it->second != nullptr) {
1017             for (auto innerIt = (it->second)->begin(); innerIt != (it->second)->end(); ++innerIt) {
1018                 DeleteCacheFileFromUserData(innerIt->first);
1019             }
1020             printHistoryJobList_.erase(printerId);
1021             FlushPrintHistoryJobFile(printerId);
1022             return true;
1023         }
1024     }
1025     return false;
1026 }
1027 
InitPrintHistoryJobList(const std::string & printerId)1028 void PrintUserData::InitPrintHistoryJobList(const std::string &printerId)
1029 {
1030     PRINT_HILOGI("InitPrintHistoryJobList Start.");
1031     auto it = printHistoryJobList_.find(printerId);
1032     if (it == printHistoryJobList_.end()) {
1033         auto printerHistoryJobList = std::make_unique<std::map<std::string, std::shared_ptr<PrintJob>>>();
1034         if (printerHistoryJobList != nullptr) {
1035             printHistoryJobList_.emplace(printerId, std::move(printerHistoryJobList));
1036             GetPrintHistoryJobFromFile(printerId);
1037         }
1038     }
1039 }
1040 
ContainsHistoryPrintJob(const std::vector<std::string> & printerIds,const std::string & jobId)1041 bool PrintUserData::ContainsHistoryPrintJob(const std::vector<std::string> &printerIds, const std::string &jobId)
1042 {
1043     for (std::string printerId : printerIds) {
1044         InitPrintHistoryJobList(printerId);
1045     }
1046     for (auto it = printHistoryJobList_.begin(); it != printHistoryJobList_.end(); it++) {
1047         if (it->second == nullptr) {
1048             return false;
1049         }
1050         if ((it->second)->find(jobId) != (it->second)->end()) {
1051             return true;
1052         }
1053     }
1054     return false;
1055 }
1056 
1057 }  // namespace Print
1058 }  // namespace OHOS