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 return lastUsedPrinterId_;
151 }
152
SetDefaultPrinter(const std::string &printerId, uint32_t type)153 int32_t PrintUserData::SetDefaultPrinter(const std::string &printerId, uint32_t type)
154 {
155 PRINT_HILOGI("begin SetDefaultPrinter");
156 PRINT_HILOGI("printerId: %{public}s", printerId.c_str());
157 PRINT_HILOGI("type: %{public}d", type);
158 if (type == DEFAULT_PRINTER_TYPE_SETTED_BY_USER) {
159 defaultPrinterId_ = printerId;
160 useLastUsedPrinterForDefault_ = false;
161 } else if (type == DEFAULT_PRINTER_TYPE_LAST_USED_PRINTER || type == DELETE_DEFAULT_PRINTER) {
162 defaultPrinterId_ = lastUsedPrinterId_;
163 useLastUsedPrinterForDefault_ = true;
164 } else if (type == DELETE_LAST_USED_PRINTER) {
165 defaultPrinterId_ = lastUsedPrinterId_;
166 }
167 PRINT_HILOGI("defaultPrinterId_: %{public}s", defaultPrinterId_.c_str());
168 if (!SetUserDataToFile()) {
169 PRINT_HILOGE("SetUserDataToFile failed.");
170 return E_PRINT_SERVER_FAILURE;
171 }
172
173 return E_PRINT_NONE;
174 }
175
GetDefaultPrinter()176 std::string PrintUserData::GetDefaultPrinter()
177 {
178 return defaultPrinterId_;
179 }
180
CheckIfUseLastUsedPrinterForDefault()181 bool PrintUserData::CheckIfUseLastUsedPrinterForDefault()
182 {
183 PRINT_HILOGI("useLastUsedPrinterForDefault_: %{public}d", useLastUsedPrinterForDefault_);
184 return useLastUsedPrinterForDefault_;
185 }
186
DeletePrinter(const std::string &printerId)187 void PrintUserData::DeletePrinter(const std::string &printerId)
188 {
189 DeletePrinterFromUsedPrinterList(printerId);
190 if (!strcmp(lastUsedPrinterId_.c_str(), printerId.c_str())) {
191 if (usedPrinterList_.size()) {
192 auto it = usedPrinterList_.begin();
193 lastUsedPrinterId_ = *it;
194 PRINT_HILOGI(
195 "change last used printer for delete printer, printerId: %{public}s", lastUsedPrinterId_.c_str());
196 } else {
197 lastUsedPrinterId_ = "";
198 PRINT_HILOGW("last used printer is null");
199 }
200 }
201 if (!SetUserDataToFile()) {
202 PRINT_HILOGE("SetUserDataToFile failed.");
203 return;
204 }
205 }
206
DeletePrinterFromUsedPrinterList(const std::string &printerId)207 void PrintUserData::DeletePrinterFromUsedPrinterList(const std::string &printerId)
208 {
209 std::lock_guard<std::recursive_mutex> lock(userDataMutex_);
210 for (auto it = usedPrinterList_.begin(); it != usedPrinterList_.end(); ++it) {
211 std::string id = *it;
212 PRINT_HILOGI("printerId in usedPrinterList_: %{public}s", id.c_str());
213 if (!strcmp(id.c_str(), printerId.c_str())) {
214 PRINT_HILOGI("find printerId in used printer list.");
215 usedPrinterList_.erase(it);
216 break;
217 }
218 }
219 }
220
ParseUserData()221 void PrintUserData::ParseUserData()
222 {
223 std::string fileData = "";
224 if (!GetFileData(fileData)) {
225 PRINT_HILOGW("get file data failed");
226 return;
227 }
228 nlohmann::json jsonObject;
229 if (CheckFileData(fileData, jsonObject)) {
230 ParseUserDataFromJson(jsonObject);
231 }
232 }
233
ParseUserDataFromJson(nlohmann::json &jsonObject)234 void PrintUserData::ParseUserDataFromJson(nlohmann::json &jsonObject)
235 {
236 if (!jsonObject.contains("print_user_data")) {
237 PRINT_HILOGW("can not find print_user_data");
238 return;
239 }
240 PRINT_HILOGI("userId_: %{public}d", userId_);
241 nlohmann::json userDataList = jsonObject["print_user_data"];
242 if (!userDataList.contains(std::to_string(userId_)) || !userDataList[std::to_string(userId_)].is_object()) {
243 PRINT_HILOGW("can not find current userId");
244 SetUserDataToFile();
245 }
246 nlohmann::json userData = userDataList[std::to_string(userId_)];
247 if (!userData.contains("defaultPrinter") || !userData["defaultPrinter"].is_string()) {
248 PRINT_HILOGW("can not find defaultPrinter");
249 return;
250 }
251 defaultPrinterId_ = userData["defaultPrinter"];
252 if (!userData.contains("lastUsedPrinter") || !userData["lastUsedPrinter"].is_string()) {
253 PRINT_HILOGW("can not find lastUsedPrinter");
254 return;
255 }
256 lastUsedPrinterId_ = userData["lastUsedPrinter"];
257 if (!userData.contains("useLastUsedPrinterForDefault") || !userData["useLastUsedPrinterForDefault"].is_boolean()) {
258 PRINT_HILOGW("can not find useLastUsedPrinterForDefault");
259 return;
260 }
261 useLastUsedPrinterForDefault_ = userData["useLastUsedPrinterForDefault"].get<bool>();
262 if (!userData.contains("usedPrinterList") || !userData["usedPrinterList"].is_array()) {
263 PRINT_HILOGW("can not find usedPrinterList");
264 return;
265 }
266 if (!ConvertJsonToUsedPrinterList(userData)) {
267 PRINT_HILOGW("convert json to usedPrinterList failed");
268 return;
269 }
270 PRINT_HILOGI(
271 "defaultPrinterId_: %{public}s, lastUsedPrinterId_: %{public}s, useLastUsedPrinterForDefault_: %{public}d",
272 defaultPrinterId_.c_str(),
273 lastUsedPrinterId_.c_str(),
274 useLastUsedPrinterForDefault_);
275 }
276
ConvertJsonToUsedPrinterList(nlohmann::json &userData)277 bool PrintUserData::ConvertJsonToUsedPrinterList(nlohmann::json &userData)
278 {
279 nlohmann::json usedPrinterListJson = userData["usedPrinterList"];
280 for (auto &item : usedPrinterListJson.items()) {
281 if (!item.value().is_string()) {
282 PRINT_HILOGW("usedPrinterListJson item is not string");
283 return false;
284 }
285 nlohmann::json printerIdJson = item.value();
286 usedPrinterList_.push_back(printerIdJson.get<std::string>());
287 }
288 uint32_t size = usedPrinterList_.size();
289 PRINT_HILOGI("usedPrinterList_ size: %{public}d", size);
290 for (auto it = usedPrinterList_.begin(); it != usedPrinterList_.end(); ++it) {
291 PRINT_HILOGI("printerId in usedPrinterList_: %{public}s", it->c_str());
292 }
293 return true;
294 }
295
ConvertUsedPrinterListToJson(nlohmann::json &usedPrinterListJson)296 void PrintUserData::ConvertUsedPrinterListToJson(nlohmann::json &usedPrinterListJson)
297 {
298 for (auto iter = usedPrinterList_.begin(); iter != usedPrinterList_.end(); ++iter) {
299 usedPrinterListJson.push_back(*iter);
300 }
301 }
302
GetFileData(std::string &fileData)303 bool PrintUserData::GetFileData(std::string &fileData)
304 {
305 PRINT_HILOGI("begin GetFileData");
306 std::string userDataFilePath = PRINTER_SERVICE_FILE_PATH + "/" + PRINT_USER_DATA_FILE;
307 std::ifstream ifs(userDataFilePath.c_str(), std::ios::in | std::ios::binary);
308 if (!ifs.is_open()) {
309 PRINT_HILOGW("open printer list file fail");
310 char realPidFile[PATH_MAX] = {};
311 if (realpath(PRINTER_SERVICE_FILE_PATH.c_str(), realPidFile) == nullptr) {
312 PRINT_HILOGE("The realPidFile is null, errno:%{public}s", std::to_string(errno).c_str());
313 return E_PRINT_SERVER_FAILURE;
314 }
315 int32_t fd = open(userDataFilePath.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0640);
316 PRINT_HILOGI("create file fd: %{public}d", fd);
317 if (fd < 0) {
318 PRINT_HILOGW("Failed to open file errno: %{public}s", std::to_string(errno).c_str());
319 return false;
320 }
321 nlohmann::json userDataJson = nlohmann::json::object();
322 nlohmann::json jsonObject;
323 jsonObject["version"] = PRINT_USER_DATA_VERSION;
324 jsonObject["print_user_data"] = userDataJson;
325 fileData = jsonObject.dump();
326 size_t jsonLength = fileData.length();
327 auto writeLength = write(fd, fileData.c_str(), jsonLength);
328 close(fd);
329 if (writeLength < 0 && (size_t)writeLength != jsonLength) {
330 return false;
331 }
332 } else {
333 fileData.assign((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
334 ifs.close();
335 }
336 return true;
337 }
338
SetUserDataToFile()339 bool PrintUserData::SetUserDataToFile()
340 {
341 PRINT_HILOGI("begin SetUserDataToFile");
342 std::string fileData = "";
343 if (!GetFileData(fileData)) {
344 PRINT_HILOGW("get file data failed");
345 return false;
346 }
347 nlohmann::json jsonObject;
348 if (CheckFileData(fileData, jsonObject)) {
349 PRINT_HILOGI("userId_: %{public}d", userId_);
350 nlohmann::json userData = nlohmann::json::object();
351 userData["defaultPrinter"] = defaultPrinterId_;
352 userData["lastUsedPrinter"] = lastUsedPrinterId_;
353 userData["useLastUsedPrinterForDefault"] = useLastUsedPrinterForDefault_;
354 nlohmann::json usedPrinterListJson = nlohmann::json::array();
355 ConvertUsedPrinterListToJson(usedPrinterListJson);
356 userData["usedPrinterList"] = usedPrinterListJson;
357 jsonObject["print_user_data"][std::to_string(userId_)] = userData;
358 std::string temp = jsonObject.dump();
359 PRINT_HILOGI("json temp: %{public}s", temp.c_str());
360 char realPidFile[PATH_MAX] = {};
361 std::string userDataFilePath = PRINTER_SERVICE_FILE_PATH + "/" + PRINT_USER_DATA_FILE;
362 if (realpath(PRINTER_SERVICE_FILE_PATH.c_str(), realPidFile) == nullptr) {
363 PRINT_HILOGE("The realPidFile is null, errno:%{public}s", std::to_string(errno).c_str());
364 return E_PRINT_SERVER_FAILURE;
365 }
366 int32_t fd = open(userDataFilePath.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0640);
367 PRINT_HILOGI("SetUserDataToFile fd: %{public}d", fd);
368 if (fd < 0) {
369 PRINT_HILOGW("Failed to open file errno: %{public}s", std::to_string(errno).c_str());
370 return false;
371 }
372 std::string jsonString = jsonObject.dump();
373 size_t jsonLength = jsonString.length();
374 auto writeLength = write(fd, jsonString.c_str(), jsonLength);
375 close(fd);
376 PRINT_HILOGI("SetUserDataToFile finished");
377 if (writeLength < 0) {
378 return false;
379 }
380 return (size_t)writeLength == jsonLength;
381 }
382 return true;
383 }
384
CheckFileData(std::string &fileData, nlohmann::json &jsonObject)385 bool PrintUserData::CheckFileData(std::string &fileData, nlohmann::json &jsonObject)
386 {
387 if (!nlohmann::json::accept(fileData)) {
388 PRINT_HILOGW("json accept fail");
389 return false;
390 }
391 jsonObject = nlohmann::json::parse(fileData);
392 if (!jsonObject.contains("version") || !jsonObject["version"].is_string()) {
393 PRINT_HILOGW("can not find version");
394 return false;
395 }
396 std::string version = jsonObject["version"].get<std::string>();
397 PRINT_HILOGI("json version: %{public}s", version.c_str());
398 if (version != PRINT_USER_DATA_VERSION || !jsonObject.contains("print_user_data")) {
399 PRINT_HILOGW("can not find print_user_data");
400 return false;
401 }
402 return true;
403 }
404 } // namespace Print
405 } // namespace OHOS