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 ¶m)
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