1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <fcntl.h>
17 #include <unistd.h>
18 #include <iostream>
19 #include <fstream>
20 #include <streambuf>
21 #include "nlohmann/json.hpp"
22
23 #include "print_user_data.h"
24 #include "print_log.h"
25 #include "print_constant.h"
26
27 namespace OHOS {
28 namespace Print {
29
30 using namespace std;
31
32 const std::string PRINT_USER_DATA_FILE = "/data/service/el2/public/print_service/print_user_data.json";
33 const std::string PRINT_USER_DATA_VERSION = "v1";
34
RegisterPrinterCallback(const std::string & type,const sptr<IPrintCallback> & listener)35 void PrintUserData::RegisterPrinterCallback(const std::string &type, const sptr<IPrintCallback> &listener)
36 {
37 registeredListeners_[type] = listener;
38 }
39
UnregisterPrinterCallback(const std::string & type)40 void PrintUserData::UnregisterPrinterCallback(const std::string &type)
41 {
42 auto iter = registeredListeners_.find(type);
43 if (iter != registeredListeners_.end()) {
44 registeredListeners_.erase(iter);
45 }
46 }
47
SendPrinterEvent(const std::string & type,int event,const PrinterInfo & info)48 void PrintUserData::SendPrinterEvent(const std::string &type, int event, const PrinterInfo &info)
49 {
50 auto iter = registeredListeners_.find(type);
51 if (iter != registeredListeners_.end() && iter->second != nullptr) {
52 iter->second->OnCallback(event, info);
53 }
54 }
55
AddToPrintJobList(const std::string jobId,const std::shared_ptr<PrintJob> & printjob)56 void PrintUserData::AddToPrintJobList(const std::string jobId, const std::shared_ptr<PrintJob> &printjob)
57 {
58 printJobList_.insert(std::make_pair(jobId, printjob));
59 }
60
UpdateQueuedJobList(const std::string & jobId,const std::shared_ptr<PrintJob> & printJob,std::string jobOrderId)61 void PrintUserData::UpdateQueuedJobList(
62 const std::string &jobId, const std::shared_ptr<PrintJob> &printJob, std::string jobOrderId)
63 {
64 if (jobOrderId == "0") {
65 jobOrderList_.clear();
66 }
67 auto jobIt = printJobList_.find(jobId);
68 if (jobIt == printJobList_.end()) {
69 PRINT_HILOGE("invalid job id");
70 return;
71 }
72 printJobList_.erase(jobIt);
73
74 if (queuedJobList_.find(jobId) != queuedJobList_.end()) {
75 queuedJobList_[jobId] = printJob;
76 jobOrderList_[jobOrderId] = jobId;
77 } else {
78 queuedJobList_.insert(std::make_pair(jobId, printJob));
79 jobOrderList_.insert(std::make_pair(jobOrderId, jobId));
80 }
81 }
82
QueryPrintJobById(std::string & printJobId,PrintJob & printJob)83 int32_t PrintUserData::QueryPrintJobById(std::string &printJobId, PrintJob &printJob)
84 {
85 if (printJobList_.empty()) {
86 PRINT_HILOGE("printJobList is empty!");
87 return E_PRINT_INVALID_PRINTJOB;
88 }
89 auto jobIt = printJobList_.find(printJobId);
90 if (jobIt == printJobList_.end()) {
91 PRINT_HILOGW("no print job exists");
92 return E_PRINT_INVALID_PRINTJOB;
93 } else {
94 if (jobIt->second != nullptr) {
95 printJob = *jobIt->second;
96 }
97 }
98 PRINT_HILOGI("QueryPrintJobById End.");
99 return E_PRINT_NONE;
100 }
101
QueryAllPrintJob(std::vector<PrintJob> & printJobs)102 int32_t PrintUserData::QueryAllPrintJob(std::vector<PrintJob> &printJobs)
103 {
104 printJobs.clear();
105 for (auto iter : jobOrderList_) {
106 PRINT_HILOGI("QueryAllPrintJob queuedJobList_ jobOrderId: %{public}s, jobId: %{public}s",
107 iter.first.c_str(),
108 iter.second.c_str());
109 auto jobIt = queuedJobList_.find(iter.second);
110 if (jobIt == queuedJobList_.end()) {
111 PRINT_HILOGW("This job dose not exist.");
112 continue;
113 } else {
114 if (jobIt->second != nullptr) {
115 printJobs.emplace_back(*jobIt->second);
116 }
117 }
118 }
119 PRINT_HILOGI("QueryAllPrintJob End.");
120 return E_PRINT_NONE;
121 }
122
SetUserId(int32_t userId)123 void PrintUserData::SetUserId(int32_t userId)
124 {
125 userId_ = userId;
126 }
127
SetLastUsedPrinter(const std::string & printerId)128 int32_t PrintUserData::SetLastUsedPrinter(const std::string &printerId)
129 {
130 PRINT_HILOGI("begin SetLastUsedPrinter, printerId: %{public}s", printerId.c_str());
131 if (printerId.empty()) {
132 PRINT_HILOGE("printerId is empty");
133 return E_PRINT_INVALID_PARAMETER;
134 }
135 std::lock_guard<std::recursive_mutex> lock(userDataMutex_);
136 lastUsedPrinterId_ = printerId;
137
138 DeletePrinterFromUsedPrinterList(printerId);
139 usedPrinterList_.push_front(printerId);
140 PRINT_HILOGI("put printer at the head of the queue, printerId: %{public}s", usedPrinterList_.front().c_str());
141 if (useLastUsedPrinterForDefault_) {
142 defaultPrinterId_ = printerId;
143 PRINT_HILOGI("set the last used printer as the default printer");
144 }
145 if (!SetUserDataToFile()) {
146 PRINT_HILOGE("SetUserDataToFile failed.");
147 return E_PRINT_SERVER_FAILURE;
148 }
149
150 return E_PRINT_NONE;
151 }
152
GetLastUsedPrinter()153 std::string PrintUserData::GetLastUsedPrinter()
154 {
155 return lastUsedPrinterId_;
156 }
157
SetDefaultPrinter(const std::string & printerId,uint32_t type)158 int32_t PrintUserData::SetDefaultPrinter(const std::string &printerId, uint32_t type)
159 {
160 PRINT_HILOGI("begin SetDefaultPrinter");
161 PRINT_HILOGI("printerId: %{public}s", printerId.c_str());
162 PRINT_HILOGI("type: %{public}d", type);
163 if (type == DEFAULT_PRINTER_TYPE_SETTED_BY_USER) {
164 defaultPrinterId_ = printerId;
165 useLastUsedPrinterForDefault_ = false;
166 } else if (type == DEFAULT_PRINTER_TYPE_LAST_USED_PRINTER || type == DELETE_DEFAULT_PRINTER) {
167 defaultPrinterId_ = lastUsedPrinterId_;
168 useLastUsedPrinterForDefault_ = true;
169 } else if (type == DELETE_LAST_USED_PRINTER) {
170 defaultPrinterId_ = lastUsedPrinterId_;
171 }
172 PRINT_HILOGI("defaultPrinterId_: %{public}s", defaultPrinterId_.c_str());
173 if (!SetUserDataToFile()) {
174 PRINT_HILOGE("SetUserDataToFile failed.");
175 return E_PRINT_SERVER_FAILURE;
176 }
177
178 return E_PRINT_NONE;
179 }
180
GetDefaultPrinter()181 std::string PrintUserData::GetDefaultPrinter()
182 {
183 return defaultPrinterId_;
184 }
185
CheckIfUseLastUsedPrinterForDefault()186 bool PrintUserData::CheckIfUseLastUsedPrinterForDefault()
187 {
188 PRINT_HILOGI("useLastUsedPrinterForDefault_: %{public}d", useLastUsedPrinterForDefault_);
189 return useLastUsedPrinterForDefault_;
190 }
191
DeletePrinter(const std::string & printerId)192 void PrintUserData::DeletePrinter(const std::string &printerId)
193 {
194 DeletePrinterFromUsedPrinterList(printerId);
195 if (!strcmp(lastUsedPrinterId_.c_str(), printerId.c_str())) {
196 if (usedPrinterList_.size()) {
197 auto it = usedPrinterList_.begin();
198 lastUsedPrinterId_ = *it;
199 PRINT_HILOGI(
200 "change last used printer for delete printer, printerId: %{public}s", lastUsedPrinterId_.c_str());
201 } else {
202 lastUsedPrinterId_ = "";
203 PRINT_HILOGW("last used printer is null");
204 }
205 }
206 if (!SetUserDataToFile()) {
207 PRINT_HILOGE("SetUserDataToFile failed.");
208 return;
209 }
210 }
211
DeletePrinterFromUsedPrinterList(const std::string & printerId)212 void PrintUserData::DeletePrinterFromUsedPrinterList(const std::string &printerId)
213 {
214 std::lock_guard<std::recursive_mutex> lock(userDataMutex_);
215 for (auto it = usedPrinterList_.begin(); it != usedPrinterList_.end(); ++it) {
216 std::string id = *it;
217 PRINT_HILOGI("printerId in usedPrinterList_: %{public}s", id.c_str());
218 if (!strcmp(id.c_str(), printerId.c_str())) {
219 PRINT_HILOGI("find printerId in used printer list.");
220 usedPrinterList_.erase(it);
221 break;
222 }
223 }
224 }
225
ParseUserData()226 void PrintUserData::ParseUserData()
227 {
228 std::string fileData = "";
229 if (!GetFileData(fileData)) {
230 PRINT_HILOGW("get file data failed");
231 return;
232 }
233 nlohmann::json jsonObject;
234 if (CheckFileData(fileData, jsonObject)) {
235 ParseUserDataFromJson(jsonObject);
236 }
237 }
238
ParseUserDataFromJson(nlohmann::json & jsonObject)239 void PrintUserData::ParseUserDataFromJson(nlohmann::json &jsonObject)
240 {
241 if (!jsonObject.contains("print_user_data")) {
242 PRINT_HILOGW("can not find print_user_data");
243 return;
244 }
245 PRINT_HILOGI("userId_: %{public}d", userId_);
246 nlohmann::json userDataList = jsonObject["print_user_data"];
247 if (!userDataList.contains(std::to_string(userId_)) || !userDataList[std::to_string(userId_)].is_object()) {
248 PRINT_HILOGW("can not find current userId");
249 SetUserDataToFile();
250 }
251 nlohmann::json userData = userDataList[std::to_string(userId_)];
252 if (!userData.contains("defaultPrinter") || !userData["defaultPrinter"].is_string()) {
253 PRINT_HILOGW("can not find defaultPrinter");
254 return;
255 }
256 defaultPrinterId_ = userData["defaultPrinter"];
257 if (!userData.contains("lastUsedPrinter") || !userData["lastUsedPrinter"].is_string()) {
258 PRINT_HILOGW("can not find lastUsedPrinter");
259 return;
260 }
261 lastUsedPrinterId_ = userData["lastUsedPrinter"];
262 if (!userData.contains("useLastUsedPrinterForDefault") || !userData["useLastUsedPrinterForDefault"].is_boolean()) {
263 PRINT_HILOGW("can not find useLastUsedPrinterForDefault");
264 return;
265 }
266 useLastUsedPrinterForDefault_ = userData["useLastUsedPrinterForDefault"].get<bool>();
267 if (!userData.contains("usedPrinterList") || !userData["usedPrinterList"].is_array()) {
268 PRINT_HILOGW("can not find usedPrinterList");
269 return;
270 }
271 if (!ConvertJsonToUsedPrinterList(userData)) {
272 PRINT_HILOGW("convert json to usedPrinterList failed");
273 return;
274 }
275 PRINT_HILOGI(
276 "defaultPrinterId_: %{public}s, lastUsedPrinterId_: %{public}s, useLastUsedPrinterForDefault_: %{public}d",
277 defaultPrinterId_.c_str(),
278 lastUsedPrinterId_.c_str(),
279 useLastUsedPrinterForDefault_);
280 }
281
ConvertJsonToUsedPrinterList(nlohmann::json & userData)282 bool PrintUserData::ConvertJsonToUsedPrinterList(nlohmann::json &userData)
283 {
284 nlohmann::json usedPrinterListJson = userData["usedPrinterList"];
285 for (auto &item : usedPrinterListJson.items()) {
286 if (!item.value().is_string()) {
287 PRINT_HILOGW("usedPrinterListJson item is not string");
288 return false;
289 }
290 nlohmann::json printerIdJson = item.value();
291 usedPrinterList_.push_back(printerIdJson.get<std::string>());
292 }
293 uint32_t size = usedPrinterList_.size();
294 PRINT_HILOGI("usedPrinterList_ size: %{public}d", size);
295 for (auto it = usedPrinterList_.begin(); it != usedPrinterList_.end(); ++it) {
296 PRINT_HILOGI("printerId in usedPrinterList_: %{public}s", it->c_str());
297 }
298 return true;
299 }
300
ConvertUsedPrinterListToJson(nlohmann::json & usedPrinterListJson)301 void PrintUserData::ConvertUsedPrinterListToJson(nlohmann::json &usedPrinterListJson)
302 {
303 for (auto iter = usedPrinterList_.begin(); iter != usedPrinterList_.end(); ++iter) {
304 usedPrinterListJson.push_back(*iter);
305 }
306 }
307
GetFileData(std::string & fileData)308 bool PrintUserData::GetFileData(std::string &fileData)
309 {
310 PRINT_HILOGI("begin GetFileData");
311 std::ifstream ifs(PRINT_USER_DATA_FILE.c_str(), std::ios::in | std::ios::binary);
312 if (!ifs.is_open()) {
313 PRINT_HILOGW("open printer list file fail");
314 int32_t fd = open(PRINT_USER_DATA_FILE.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0740);
315 PRINT_HILOGI("create file fd: %{public}d", fd);
316 if (fd < 0) {
317 PRINT_HILOGW("Failed to open file errno: %{public}s", std::to_string(errno).c_str());
318 close(fd);
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 int32_t fd = open(PRINT_USER_DATA_FILE.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0740);
361 PRINT_HILOGI("SetUserDataToFile fd: %{public}d", fd);
362 if (fd < 0) {
363 PRINT_HILOGW("Failed to open file errno: %{public}s", std::to_string(errno).c_str());
364 close(fd);
365 return false;
366 }
367 std::string jsonString = jsonObject.dump();
368 size_t jsonLength = jsonString.length();
369 auto writeLength = write(fd, jsonString.c_str(), jsonLength);
370 close(fd);
371 PRINT_HILOGI("SetUserDataToFile finished");
372 if (writeLength < 0) {
373 return false;
374 }
375 return (size_t)writeLength == jsonLength;
376 }
377 return true;
378 }
379
CheckFileData(std::string & fileData,nlohmann::json & jsonObject)380 bool PrintUserData::CheckFileData(std::string &fileData, nlohmann::json &jsonObject)
381 {
382 if (!nlohmann::json::accept(fileData)) {
383 PRINT_HILOGW("json accept fail");
384 return false;
385 }
386 jsonObject = nlohmann::json::parse(fileData);
387 if (!jsonObject.contains("version") || !jsonObject["version"].is_string()) {
388 PRINT_HILOGW("can not find version");
389 return false;
390 }
391 std::string version = jsonObject["version"].get<std::string>();
392 PRINT_HILOGI("json version: %{public}s", version.c_str());
393 if (version != PRINT_USER_DATA_VERSION || !jsonObject.contains("print_user_data")) {
394 PRINT_HILOGW("can not find print_user_data");
395 return false;
396 }
397 return true;
398 }
399 } // namespace Print
400 } // namespace OHOS