• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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_utils.h"
17 
18 #include <chrono>
19 #include <cstdlib>
20 #include <ctime>
21 #include <fcntl.h>
22 #include <random>
23 #include <sstream>
24 #include "ability.h"
25 #include "print_util.h"
26 #include "securec.h"
27 
28 namespace OHOS::Print {
29 
30 std::mutex PrintUtils::instanceLock_;
31 
32 static const std::string LAUNCH_PARAMETER_DOCUMENT_NAME = "documentName";
33 static const std::string LAUNCH_PARAMETER_PRINT_ATTRIBUTE = "printAttributes";
34 
35 static std::map<uint32_t, std::string> jobStateMap_;
36 const std::string GLOBAL_ID_DELIMITER = ":";
37 const std::string EXTENSION_CID_DELIMITER = ":";
38 const std::string TASK_EVENT_DELIMITER = "-";
39 const std::string USER_ID_DELIMITER = ":";
40 const int32_t DEFAULT_FD = 99;
41 const int32_t MINIMUN_RANDOM_NUMBER_100 = 100;
42 const int32_t MAXIMUN_RANDOM_NUMBER_999 = 999;
43 
ToLower(const std::string & s)44 std::string PrintUtils::ToLower(const std::string &s)
45 {
46     std::string res = s;
47     std::transform(res.begin(), res.end(), res.begin(), tolower);
48     return res;
49 }
50 
GetExtensionId(const std::string & globalId)51 std::string PrintUtils::GetExtensionId(const std::string &globalId)
52 {
53     auto pos = globalId.find(GLOBAL_ID_DELIMITER);
54     if (pos == std::string::npos) {
55         return "";
56     }
57     return globalId.substr(0, pos);
58 }
59 
GetGlobalId(const std::string & extensionId,const std::string & localId)60 std::string PrintUtils::GetGlobalId(const std::string& extensionId, const std::string& localId)
61 {
62     return extensionId + GLOBAL_ID_DELIMITER + localId;
63 }
64 
GetLocalId(const std::string & globalId,const std::string & extensionId)65 std::string PrintUtils::GetLocalId(const std::string& globalId, const std::string& extensionId)
66 {
67     auto pos = globalId.find(GLOBAL_ID_DELIMITER);
68     if (pos == std::string::npos) {
69         return "";
70     }
71 
72     if (globalId.substr(0, pos) != extensionId) {
73         return "";
74     }
75     return globalId.substr(pos + 1);
76 }
77 
EncodeExtensionCid(const std::string & extensionId,uint32_t callbackId)78 std::string PrintUtils::EncodeExtensionCid(const std::string &extensionId, uint32_t callbackId)
79 {
80     return extensionId + EXTENSION_CID_DELIMITER + std::to_string(callbackId);
81 }
82 
DecodeExtensionCid(const std::string & cid,std::string & extensionId,uint32_t & callbackId)83 bool PrintUtils::DecodeExtensionCid(const std::string &cid, std::string &extensionId, uint32_t &callbackId)
84 {
85     auto pos = cid.find(EXTENSION_CID_DELIMITER);
86     if (pos == std::string::npos) {
87         return false;
88     }
89     extensionId = cid.substr(0, pos);
90     int32_t callbackIdTmp = 0;
91     if (!PrintUtil::ConvertToInt(cid.substr(pos + 1), callbackIdTmp)) {
92         return false;
93     }
94     callbackId = static_cast<uint32_t>(callbackIdTmp);
95     return true;
96 }
97 
GetTaskEventId(const std::string & taskId,const std::string & type)98 std::string PrintUtils::GetTaskEventId(const std::string &taskId, const std::string &type)
99 {
100     return type + TASK_EVENT_DELIMITER + taskId;
101 }
102 
GetEventTypeWithToken(int32_t userId,int64_t pid,const std::string & type)103 std::string PrintUtils::GetEventTypeWithToken(int32_t userId, int64_t pid, const std::string &type)
104 {
105     std::string eventType =
106         std::to_string(userId) + USER_ID_DELIMITER + std::to_string(pid) + TASK_EVENT_DELIMITER + type;
107     PRINT_HILOGD("eventType: %{public}s", eventType.c_str());
108     return eventType;
109 }
110 
GetEventType(const std::string & type)111 std::string PrintUtils::GetEventType(const std::string &type)
112 {
113     auto pos = type.find(TASK_EVENT_DELIMITER);
114     if (pos == std::string::npos || pos + 1 >= type.length()) {
115         return type;
116     }
117     std::string eventType = type.substr(pos + 1);
118     PRINT_HILOGD("eventType: %{public}s", eventType.c_str());
119     return eventType;
120 }
121 
CheckUserIdInEventType(const std::string & type,int32_t callerUserId)122 bool PrintUtils::CheckUserIdInEventType(const std::string &type, int32_t callerUserId)
123 {
124     auto userIdPos = type.find(USER_ID_DELIMITER);
125     if (userIdPos == std::string::npos || userIdPos >= type.length()) {
126         return false;
127     }
128     std::string userIdStr = type.substr(0, userIdPos);
129     PRINT_HILOGD("userId: %{public}s", userIdStr.c_str());
130     if (userIdStr == std::to_string(callerUserId)) {
131         return true;
132     }
133     return false;
134 }
135 
OpenFile(const std::string & filePath)136 int32_t PrintUtils::OpenFile(const std::string &filePath)
137 {
138     if (filePath.find("content://") == 0) {
139         return DEFAULT_FD;
140     }
141     if (!IsPathValid(filePath)) {
142         return PRINT_INVALID_ID;
143     }
144     int32_t fd = open(filePath.c_str(), O_RDONLY);
145     PRINT_HILOGD("fd: %{public}d", fd);
146     if (fd < 0) {
147         PRINT_HILOGE("Failed to open file errno: %{public}s", std::to_string(errno).c_str());
148         fdsan_close_with_tag(fd, PRINT_LOG_DOMAIN);
149         return PRINT_INVALID_ID;
150     }
151     return fd;
152 }
153 
IsPathValid(const std::string & filePath)154 bool PrintUtils::IsPathValid(const std::string &filePath)
155 {
156     auto path = filePath.substr(0, filePath.rfind('/'));
157     char resolvedPath[PATH_MAX] = { 0 };
158     if (path.length() >= PATH_MAX || realpath(path.c_str(), resolvedPath) == nullptr ||
159         strncmp(resolvedPath, path.c_str(), path.length()) != 0) {
160         PRINT_HILOGE("invalid file path!");
161         return false;
162     }
163     return true;
164 }
165 
GetIdFromFdPath(const std::string & fdPath)166 uint32_t PrintUtils::GetIdFromFdPath(const std::string &fdPath)
167 {
168     std::string fd_str = fdPath.substr(fdPath.rfind('/') + 1, fdPath.length());
169     std::stringstream getStrStream(fd_str);
170     uint32_t fd = 0;
171     if (!(getStrStream >> fd)) {
172         PRINT_HILOGD("failed to convert to uint32");
173     }
174     return fd;
175 }
176 
GetJobStateChar(const uint32_t state)177 std::string PrintUtils::GetJobStateChar(const uint32_t state)
178 {
179     if (jobStateMap_.size() == 0) {
180         jobStateMap_[PRINT_JOB_PREPARED] = "PRINT_JOB_PREPARED";
181         jobStateMap_[PRINT_JOB_QUEUED] = "PRINT_JOB_QUEUED";
182         jobStateMap_[PRINT_JOB_RUNNING] = "PRINT_JOB_RUNNING";
183         jobStateMap_[PRINT_JOB_BLOCKED] = "PRINT_JOB_BLOCKED";
184         jobStateMap_[PRINT_JOB_COMPLETED] = "PRINT_JOB_COMPLETED";
185         jobStateMap_[PRINT_JOB_CREATE_FILE_COMPLETED] = "PRINT_JOB_CREATE_FILE_COMPLETED";
186         jobStateMap_[PRINT_JOB_UNKNOWN] = "PRINT_JOB_UNKNOWN";
187     }
188     auto it = jobStateMap_.find(state);
189     if (it != jobStateMap_.end()) {
190         return it -> second;
191     }
192     return "PRINT_JOB_UNKNOWN";
193 }
194 
BuildAdapterParam(const std::shared_ptr<AdapterParam> & adapterParam,AAFwk::Want & want)195 void PrintUtils::BuildAdapterParam(const std::shared_ptr<AdapterParam> &adapterParam, AAFwk::Want &want)
196 {
197     want.SetParam(LAUNCH_PARAMETER_DOCUMENT_NAME, adapterParam->documentName);
198     if (adapterParam->isCheckFdList) {
199         std::string defaultAttribute = "";
200         want.SetParam(LAUNCH_PARAMETER_PRINT_ATTRIBUTE, defaultAttribute);
201         return;
202     }
203     BuildPrintAttributesParam(adapterParam, want);
204 }
205 
BuildPrintAttributesParam(const std::shared_ptr<AdapterParam> & adapterParam,AAFwk::Want & want)206 void PrintUtils::BuildPrintAttributesParam(const std::shared_ptr<AdapterParam> &adapterParam, AAFwk::Want &want)
207 {
208     Json::Value attrJson;
209     PrintAttributes attrParam = adapterParam->printAttributes;
210     if (attrParam.HasCopyNumber()) {
211         attrJson["copyNumber"] = attrParam.GetCopyNumber();
212     }
213     if (attrParam.HasSequential()) {
214         attrJson["isSequential"] = attrParam.GetIsSequential();
215     }
216     if (attrParam.HasLandscape()) {
217         attrJson["isLandscape"] = attrParam.GetIsLandscape();
218     }
219     if (attrParam.HasDirectionMode()) {
220         attrJson["directionMode"] = attrParam.GetDirectionMode();
221     }
222     if (attrParam.HasColorMode()) {
223         attrJson["colorMode"] = attrParam.GetColorMode();
224     }
225     if (attrParam.HasDuplexMode()) {
226         attrJson["duplexMode"] = attrParam.GetDuplexMode();
227     }
228     ParseAttributesObjectParamForJson(attrParam, attrJson);
229     if (attrParam.HasOption()) {
230         attrJson["options"] = attrParam.GetOption();
231     }
232     want.SetParam(LAUNCH_PARAMETER_PRINT_ATTRIBUTE, (PrintJsonUtil::WriteString(attrJson)));
233     PRINT_HILOGD("CallSpooler set printAttributes: %{public}s", (PrintJsonUtil::WriteString(attrJson)).c_str());
234 }
235 
CreatePageRangeJson(const PrintAttributes & attrParam)236 Json::Value PrintUtils::CreatePageRangeJson(const PrintAttributes &attrParam)
237 {
238     Json::Value pageRangeJson;
239     PrintRange printRangeAttr;
240     attrParam.GetPageRange(printRangeAttr);
241     if (printRangeAttr.HasStartPage()) {
242         pageRangeJson["startPage"] = printRangeAttr.GetStartPage();
243     }
244     if (printRangeAttr.HasEndPage()) {
245         pageRangeJson["endPage"] = printRangeAttr.GetEndPage();
246     }
247     if (printRangeAttr.HasPages()) {
248         std::vector<uint32_t> pages;
249         printRangeAttr.GetPages(pages);
250         Json::Value pagesJson;
251         for (const auto &item : pages) {
252             pagesJson.append(item);
253         }
254         pageRangeJson["pages"] = pagesJson;
255     }
256     return pageRangeJson;
257 }
258 
CreatePageSizeJson(const PrintAttributes & attrParam)259 Json::Value PrintUtils::CreatePageSizeJson(const PrintAttributes &attrParam)
260 {
261     Json::Value pageSizeJson;
262     PrintPageSize pageSizeAttr;
263     attrParam.GetPageSize(pageSizeAttr);
264     pageSizeJson["id"] = pageSizeAttr.GetId();
265     pageSizeJson["name"] = pageSizeAttr.GetName();
266     pageSizeJson["width"] = pageSizeAttr.GetWidth();
267     pageSizeJson["height"] = pageSizeAttr.GetHeight();
268     return pageSizeJson;
269 }
270 
CreateMarginJson(const PrintAttributes & attrParam)271 Json::Value PrintUtils::CreateMarginJson(const PrintAttributes &attrParam)
272 {
273     Json::Value marginJson;
274     PrintMargin marginAttr;
275     attrParam.GetMargin(marginAttr);
276     if (marginAttr.HasTop()) {
277         marginJson["top"] = marginAttr.GetTop();
278     }
279     if (marginAttr.HasBottom()) {
280         marginJson["bottom"] = marginAttr.GetBottom();
281     }
282     if (marginAttr.HasLeft()) {
283         marginJson["left"] = marginAttr.GetLeft();
284     }
285     if (marginAttr.HasRight()) {
286         marginJson["right"] = marginAttr.GetRight();
287     }
288     return marginJson;
289 }
290 
ParseAttributesObjectParamForJson(const PrintAttributes & attrParam,Json::Value & attrJson)291 void PrintUtils::ParseAttributesObjectParamForJson(const PrintAttributes &attrParam, Json::Value &attrJson)
292 {
293     if (attrParam.HasPageRange()) {
294         attrJson["pageRange"] = CreatePageRangeJson(attrParam);
295     }
296     if (attrParam.HasPageSize()) {
297         attrJson["pageSize"] = CreatePageSizeJson(attrParam);
298     }
299     if (attrParam.HasMargin()) {
300         attrJson["margin"] = CreateMarginJson(attrParam);
301     }
302 }
303 
GetBundleNameForUid(const int uid)304 std::string PrintUtils::GetBundleNameForUid(const int uid)
305 {
306     OHOS::AppExecFwk::BundleMgrClient bmsClient;
307     std::string bundleName = "";
308     auto ret = bmsClient.GetNameForUid(uid, bundleName);
309     if (ret != OHOS::ERR_OK || bundleName.empty()) {
310         PRINT_HILOGE("get bundleName failed.");
311     }
312     PRINT_HILOGI("bundleName: %{public}s", bundleName.c_str());
313     return bundleName;
314 }
315 
GetPrintJobId()316 std::string PrintUtils::GetPrintJobId()
317 {
318     std::lock_guard<std::mutex> autoLock(instanceLock_);
319     auto nowTime = std::chrono::system_clock::now();
320     auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(nowTime.time_since_epoch()).count();
321     std::stringstream ss;
322     ss << timestamp;
323 
324     std::random_device rd;
325     std::mt19937 gen(rd());
326     std::uniform_int_distribution<> dis(MINIMUN_RANDOM_NUMBER_100, MAXIMUN_RANDOM_NUMBER_999);
327     int32_t randomNumber = dis(gen);
328     std::string jobId = ss.str() + "_" + std::to_string(randomNumber);
329     PRINT_HILOGI("jobId: %{public}s", jobId.c_str());
330     return jobId;
331 }
332 }  // namespace OHOS::Print
333