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 "nlohmann/json.hpp"
23
24 #include "print_log.h"
25 #include "print_constant.h"
26
27 namespace OHOS {
28 namespace Print {
29
RegisterPrinterCallback(const std::string & type,const sptr<IPrintCallback> & listener)30 void PrintUserData::RegisterPrinterCallback(const std::string &type, const sptr<IPrintCallback> &listener)
31 {
32 registeredListeners_[type] = listener;
33 }
34
UnregisterPrinterCallback(const std::string & type)35 void PrintUserData::UnregisterPrinterCallback(const std::string &type)
36 {
37 auto iter = registeredListeners_.find(type);
38 if (iter != registeredListeners_.end()) {
39 registeredListeners_.erase(iter);
40 }
41 }
42
SendPrinterEvent(const std::string & type,int event,const PrinterInfo & info)43 void PrintUserData::SendPrinterEvent(const std::string &type, int event, const PrinterInfo &info)
44 {
45 auto iter = registeredListeners_.find(type);
46 if (iter != registeredListeners_.end() && iter->second != nullptr) {
47 iter->second->OnCallback(event, info);
48 }
49 }
50
AddToPrintJobList(const std::string jobId,const std::shared_ptr<PrintJob> & printjob)51 void PrintUserData::AddToPrintJobList(const std::string jobId, const std::shared_ptr<PrintJob> &printjob)
52 {
53 printJobList_.insert(std::make_pair(jobId, printjob));
54 }
55
UpdateQueuedJobList(const std::string & jobId,const std::shared_ptr<PrintJob> & printJob,std::string jobOrderId)56 void PrintUserData::UpdateQueuedJobList(
57 const std::string &jobId, const std::shared_ptr<PrintJob> &printJob, std::string jobOrderId)
58 {
59 if (jobOrderId == "0") {
60 jobOrderList_.clear();
61 }
62 auto jobIt = printJobList_.find(jobId);
63 if (jobIt == printJobList_.end()) {
64 PRINT_HILOGE("invalid job id");
65 return;
66 }
67 printJobList_.erase(jobIt);
68
69 if (queuedJobList_.find(jobId) != queuedJobList_.end()) {
70 queuedJobList_[jobId] = printJob;
71 jobOrderList_[jobOrderId] = jobId;
72 } else {
73 queuedJobList_.insert(std::make_pair(jobId, printJob));
74 jobOrderList_.insert(std::make_pair(jobOrderId, jobId));
75 }
76 }
77
QueryPrintJobById(std::string & printJobId,PrintJob & printJob)78 int32_t PrintUserData::QueryPrintJobById(std::string &printJobId, PrintJob &printJob)
79 {
80 if (printJobList_.empty()) {
81 PRINT_HILOGE("printJobList is empty!");
82 return E_PRINT_INVALID_PRINTJOB;
83 }
84 auto jobIt = printJobList_.find(printJobId);
85 if (jobIt == printJobList_.end()) {
86 PRINT_HILOGW("no print job exists");
87 return E_PRINT_INVALID_PRINTJOB;
88 } else {
89 if (jobIt->second != nullptr) {
90 printJob = *jobIt->second;
91 }
92 }
93 PRINT_HILOGI("QueryPrintJobById End.");
94 return E_PRINT_NONE;
95 }
96
QueryAllPrintJob(std::vector<PrintJob> & printJobs)97 int32_t PrintUserData::QueryAllPrintJob(std::vector<PrintJob> &printJobs)
98 {
99 printJobs.clear();
100 for (auto iter : jobOrderList_) {
101 PRINT_HILOGI("QueryAllPrintJob queuedJobList_ jobOrderId: %{public}s, jobId: %{public}s",
102 iter.first.c_str(),
103 iter.second.c_str());
104 auto jobIt = queuedJobList_.find(iter.second);
105 if (jobIt == queuedJobList_.end()) {
106 PRINT_HILOGW("This job dose not exist.");
107 continue;
108 } else {
109 if (jobIt->second != nullptr) {
110 printJobs.emplace_back(*jobIt->second);
111 }
112 }
113 }
114 PRINT_HILOGI("QueryAllPrintJob End.");
115 return E_PRINT_NONE;
116 }
117
SetUserId(int32_t userId)118 void PrintUserData::SetUserId(int32_t userId)
119 {
120 userId_ = userId;
121 }
122
SetLastUsedPrinter(const std::string & printerId)123 int32_t PrintUserData::SetLastUsedPrinter(const std::string &printerId)
124 {
125 PRINT_HILOGI("begin SetLastUsedPrinter, printerId: %{public}s", printerId.c_str());
126 if (printerId.empty()) {
127 PRINT_HILOGE("printerId is empty");
128 return E_PRINT_INVALID_PARAMETER;
129 }
130 std::lock_guard<std::recursive_mutex> lock(userDataMutex_);
131 lastUsedPrinterId_ = printerId;
132
133 DeletePrinterFromUsedPrinterList(printerId);
134 usedPrinterList_.push_front(printerId);
135 PRINT_HILOGI("put printer at the head of the queue, printerId: %{public}s", usedPrinterList_.front().c_str());
136 if (useLastUsedPrinterForDefault_) {
137 defaultPrinterId_ = printerId;
138 PRINT_HILOGI("set the last used printer as the default printer");
139 }
140 if (!SetUserDataToFile()) {
141 PRINT_HILOGE("SetUserDataToFile failed.");
142 return E_PRINT_SERVER_FAILURE;
143 }
144
145 return E_PRINT_NONE;
146 }
147
GetLastUsedPrinter()148 std::string PrintUserData::GetLastUsedPrinter()
149 {
150 std::lock_guard<std::recursive_mutex> lock(userDataMutex_);
151 return lastUsedPrinterId_;
152 }
153
SetDefaultPrinter(const std::string & printerId,uint32_t type)154 int32_t PrintUserData::SetDefaultPrinter(const std::string &printerId, uint32_t type)
155 {
156 std::lock_guard<std::recursive_mutex> lock(userDataMutex_);
157 PRINT_HILOGI("begin SetDefaultPrinter");
158 PRINT_HILOGI("printerId: %{public}s", printerId.c_str());
159 PRINT_HILOGI("type: %{public}d", type);
160 if (type == DEFAULT_PRINTER_TYPE_SETTED_BY_USER) {
161 defaultPrinterId_ = printerId;
162 useLastUsedPrinterForDefault_ = false;
163 } else if (type == DEFAULT_PRINTER_TYPE_LAST_USED_PRINTER || type == DELETE_DEFAULT_PRINTER) {
164 defaultPrinterId_ = lastUsedPrinterId_;
165 useLastUsedPrinterForDefault_ = true;
166 } else if (type == DELETE_LAST_USED_PRINTER) {
167 defaultPrinterId_ = lastUsedPrinterId_;
168 }
169 PRINT_HILOGI("defaultPrinterId_: %{public}s", defaultPrinterId_.c_str());
170 if (!SetUserDataToFile()) {
171 PRINT_HILOGE("SetUserDataToFile failed.");
172 return E_PRINT_SERVER_FAILURE;
173 }
174
175 return E_PRINT_NONE;
176 }
177
GetDefaultPrinter()178 std::string PrintUserData::GetDefaultPrinter()
179 {
180 return defaultPrinterId_;
181 }
182
CheckIfUseLastUsedPrinterForDefault()183 bool PrintUserData::CheckIfUseLastUsedPrinterForDefault()
184 {
185 PRINT_HILOGI("useLastUsedPrinterForDefault_: %{public}d", useLastUsedPrinterForDefault_);
186 return useLastUsedPrinterForDefault_;
187 }
188
DeletePrinter(const std::string & printerId)189 void PrintUserData::DeletePrinter(const std::string &printerId)
190 {
191 DeletePrinterFromUsedPrinterList(printerId);
192 if (!strcmp(lastUsedPrinterId_.c_str(), printerId.c_str())) {
193 std::lock_guard<std::recursive_mutex> lock(userDataMutex_);
194 if (usedPrinterList_.size()) {
195 auto it = usedPrinterList_.begin();
196 lastUsedPrinterId_ = *it;
197 PRINT_HILOGI(
198 "change last used printer for delete printer, printerId: %{public}s", lastUsedPrinterId_.c_str());
199 } else {
200 lastUsedPrinterId_ = "";
201 PRINT_HILOGW("last used printer is null");
202 }
203 }
204 if (!SetUserDataToFile()) {
205 PRINT_HILOGE("SetUserDataToFile failed.");
206 return;
207 }
208 }
209
DeletePrinterFromUsedPrinterList(const std::string & printerId)210 void PrintUserData::DeletePrinterFromUsedPrinterList(const std::string &printerId)
211 {
212 std::lock_guard<std::recursive_mutex> lock(userDataMutex_);
213 for (auto it = usedPrinterList_.begin(); it != usedPrinterList_.end(); ++it) {
214 std::string id = *it;
215 PRINT_HILOGI("printerId in usedPrinterList_: %{public}s", id.c_str());
216 if (!strcmp(id.c_str(), printerId.c_str())) {
217 PRINT_HILOGI("find printerId in used printer list.");
218 usedPrinterList_.erase(it);
219 break;
220 }
221 }
222 }
223
ParseUserData()224 void PrintUserData::ParseUserData()
225 {
226 std::string fileData = "";
227 if (!GetFileData(fileData)) {
228 PRINT_HILOGW("get file data failed");
229 return;
230 }
231 nlohmann::json jsonObject;
232 if (CheckFileData(fileData, jsonObject)) {
233 ParseUserDataFromJson(jsonObject);
234 }
235 }
236
ParseUserDataFromJson(nlohmann::json & jsonObject)237 void PrintUserData::ParseUserDataFromJson(nlohmann::json &jsonObject)
238 {
239 if (!jsonObject.contains("print_user_data")) {
240 PRINT_HILOGW("can not find print_user_data");
241 return;
242 }
243 PRINT_HILOGI("userId_: %{public}d", userId_);
244 nlohmann::json userDataList = jsonObject["print_user_data"];
245 if (!userDataList.contains(std::to_string(userId_)) || !userDataList[std::to_string(userId_)].is_object()) {
246 PRINT_HILOGW("can not find current userId");
247 SetUserDataToFile();
248 }
249 nlohmann::json userData = userDataList[std::to_string(userId_)];
250 if (!userData.contains("defaultPrinter") || !userData["defaultPrinter"].is_string()) {
251 PRINT_HILOGW("can not find defaultPrinter");
252 return;
253 }
254 defaultPrinterId_ = userData["defaultPrinter"];
255 if (!userData.contains("lastUsedPrinter") || !userData["lastUsedPrinter"].is_string()) {
256 PRINT_HILOGW("can not find lastUsedPrinter");
257 return;
258 }
259 lastUsedPrinterId_ = userData["lastUsedPrinter"];
260 if (!userData.contains("useLastUsedPrinterForDefault") || !userData["useLastUsedPrinterForDefault"].is_boolean()) {
261 PRINT_HILOGW("can not find useLastUsedPrinterForDefault");
262 return;
263 }
264 useLastUsedPrinterForDefault_ = userData["useLastUsedPrinterForDefault"].get<bool>();
265 if (!userData.contains("usedPrinterList") || !userData["usedPrinterList"].is_array()) {
266 PRINT_HILOGW("can not find usedPrinterList");
267 return;
268 }
269 if (!ConvertJsonToUsedPrinterList(userData)) {
270 PRINT_HILOGW("convert json to usedPrinterList failed");
271 return;
272 }
273 PRINT_HILOGI(
274 "defaultPrinterId_: %{public}s, lastUsedPrinterId_: %{public}s, useLastUsedPrinterForDefault_: %{public}d",
275 defaultPrinterId_.c_str(),
276 lastUsedPrinterId_.c_str(),
277 useLastUsedPrinterForDefault_);
278 }
279
ConvertJsonToUsedPrinterList(nlohmann::json & userData)280 bool PrintUserData::ConvertJsonToUsedPrinterList(nlohmann::json &userData)
281 {
282 nlohmann::json usedPrinterListJson = userData["usedPrinterList"];
283 for (auto &item : usedPrinterListJson.items()) {
284 if (!item.value().is_string()) {
285 PRINT_HILOGW("usedPrinterListJson item is not string");
286 return false;
287 }
288 nlohmann::json printerIdJson = item.value();
289 usedPrinterList_.push_back(printerIdJson.get<std::string>());
290 }
291 uint32_t size = usedPrinterList_.size();
292 PRINT_HILOGI("usedPrinterList_ size: %{public}d", size);
293 for (auto it = usedPrinterList_.begin(); it != usedPrinterList_.end(); ++it) {
294 PRINT_HILOGI("printerId in usedPrinterList_: %{public}s", it->c_str());
295 }
296 return true;
297 }
298
ConvertUsedPrinterListToJson(nlohmann::json & usedPrinterListJson)299 void PrintUserData::ConvertUsedPrinterListToJson(nlohmann::json &usedPrinterListJson)
300 {
301 for (auto iter = usedPrinterList_.begin(); iter != usedPrinterList_.end(); ++iter) {
302 usedPrinterListJson.push_back(*iter);
303 }
304 }
305
GetFileData(std::string & fileData)306 bool PrintUserData::GetFileData(std::string &fileData)
307 {
308 PRINT_HILOGI("begin GetFileData");
309 std::string userDataFilePath = PRINTER_SERVICE_FILE_PATH + "/" + PRINT_USER_DATA_FILE;
310 std::ifstream ifs(userDataFilePath.c_str(), std::ios::in | std::ios::binary);
311 if (!ifs.is_open()) {
312 PRINT_HILOGW("open printer list file fail");
313 char realPidFile[PATH_MAX] = {};
314 if (realpath(PRINTER_SERVICE_FILE_PATH.c_str(), realPidFile) == nullptr) {
315 PRINT_HILOGE("The realPidFile is null, errno:%{public}s", std::to_string(errno).c_str());
316 return false;
317 }
318 int32_t fd = open(userDataFilePath.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0640);
319 PRINT_HILOGI("create file fd: %{public}d", fd);
320 if (fd < 0) {
321 PRINT_HILOGW("Failed to open file errno: %{public}s", std::to_string(errno).c_str());
322 return false;
323 }
324 nlohmann::json userDataJson = nlohmann::json::object();
325 nlohmann::json jsonObject;
326 jsonObject["version"] = PRINT_USER_DATA_VERSION;
327 jsonObject["print_user_data"] = userDataJson;
328 fileData = jsonObject.dump();
329 size_t jsonLength = fileData.length();
330 auto writeLength = write(fd, fileData.c_str(), jsonLength);
331 close(fd);
332 if (writeLength < 0 && (size_t)writeLength != jsonLength) {
333 return false;
334 }
335 } else {
336 fileData.assign((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
337 ifs.close();
338 }
339 return true;
340 }
341
SetUserDataToFile()342 bool PrintUserData::SetUserDataToFile()
343 {
344 PRINT_HILOGI("begin SetUserDataToFile");
345 std::string fileData = "";
346 if (!GetFileData(fileData)) {
347 PRINT_HILOGW("get file data failed");
348 return false;
349 }
350 nlohmann::json jsonObject;
351 if (CheckFileData(fileData, jsonObject)) {
352 PRINT_HILOGI("userId_: %{public}d", userId_);
353 nlohmann::json userData = nlohmann::json::object();
354 userData["defaultPrinter"] = defaultPrinterId_;
355 userData["lastUsedPrinter"] = lastUsedPrinterId_;
356 userData["useLastUsedPrinterForDefault"] = useLastUsedPrinterForDefault_;
357 nlohmann::json usedPrinterListJson = nlohmann::json::array();
358 ConvertUsedPrinterListToJson(usedPrinterListJson);
359 userData["usedPrinterList"] = usedPrinterListJson;
360 jsonObject["print_user_data"][std::to_string(userId_)] = userData;
361 std::string temp = jsonObject.dump();
362 PRINT_HILOGI("json temp: %{public}s", temp.c_str());
363 char realPidFile[PATH_MAX] = {};
364 std::string userDataFilePath = PRINTER_SERVICE_FILE_PATH + "/" + PRINT_USER_DATA_FILE;
365 if (realpath(PRINTER_SERVICE_FILE_PATH.c_str(), realPidFile) == nullptr) {
366 PRINT_HILOGE("The realPidFile is null, errno:%{public}s", std::to_string(errno).c_str());
367 return false;
368 }
369 int32_t fd = open(userDataFilePath.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0640);
370 PRINT_HILOGI("SetUserDataToFile fd: %{public}d", fd);
371 if (fd < 0) {
372 PRINT_HILOGW("Failed to open file errno: %{public}s", std::to_string(errno).c_str());
373 return false;
374 }
375 std::string jsonString = jsonObject.dump();
376 size_t jsonLength = jsonString.length();
377 auto writeLength = write(fd, jsonString.c_str(), jsonLength);
378 close(fd);
379 PRINT_HILOGI("SetUserDataToFile finished");
380 if (writeLength < 0) {
381 return false;
382 }
383 return (size_t)writeLength == jsonLength;
384 }
385 return true;
386 }
387
CheckFileData(std::string & fileData,nlohmann::json & jsonObject)388 bool PrintUserData::CheckFileData(std::string &fileData, nlohmann::json &jsonObject)
389 {
390 if (!nlohmann::json::accept(fileData)) {
391 PRINT_HILOGW("json accept fail");
392 return false;
393 }
394 jsonObject = nlohmann::json::parse(fileData);
395 if (!jsonObject.contains("version") || !jsonObject["version"].is_string()) {
396 PRINT_HILOGW("can not find version");
397 return false;
398 }
399 std::string version = jsonObject["version"].get<std::string>();
400 PRINT_HILOGI("json version: %{public}s", version.c_str());
401 if (version != PRINT_USER_DATA_VERSION || !jsonObject.contains("print_user_data")) {
402 PRINT_HILOGW("can not find print_user_data");
403 return false;
404 }
405 return true;
406 }
407 } // namespace Print
408 } // namespace OHOS