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