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 #ifndef PRINT_CUPS_CLIENT_H
17 #define PRINT_CUPS_CLIENT_H
18 
19 #include <vector>
20 #include <string>
21 #include <functional>
22 #include <nlohmann/json.hpp>
23 
24 #include "singleton.h"
25 #include "print_cups_wrapper.h"
26 #include "print_service_ability.h"
27 #include "print_job.h"
28 
29 namespace OHOS::Print {
30 using json = nlohmann::json;
31 typedef std::function<void()> CallbackFunc;
32 
33 struct JobParameters {
34     uint32_t cupsJobId;
35     uint32_t borderless;
36     uint32_t numCopies;
37     bool isAutoRotate;
38     bool isLandscape;
39     std::string duplex;
40     std::string printQuality;
41     std::string jobName;
42     std::string jobOriginatingUserName;
43     std::string printerId;
44     std::string printerName;
45     std::string printerUri;
46     std::string documentFormat;
47     std::string mediaSize;
48     std::string mediaType;
49     std::string color;
50     std::string serviceJobId;
51     std::vector<uint32_t> fdList;
52     PrintServiceAbility *serviceAbility;
53     std::string printerAttrsOption_cupsOption;
54 };
55 
56 struct JobStatus {
57     char printer_state_reasons[1024];
58     ipp_jstate_t job_state;
59     char job_state_reasons[1024];
60 };
61 struct JobMonitorParam {
62     PrintServiceAbility *serviceAbility;
63     std::string serviceJobId;
64     int cupsJobId;
65     std::string printerUri;
66     std::string printerName;
67     std::string printerId;
68 };
69 struct MediaSize {
70     std::string name;
71     const float WidthInInches;
72     const float HeightInInches;
73 };
74 
75 class PrintCupsClient final : public DelayedSingleton<PrintCupsClient>,
76     public std::enable_shared_from_this<PrintCupsClient> {
77 public:
78     PrintCupsClient();
79     ~PrintCupsClient();
80 
81     int32_t InitCupsResources();
82     void StopCupsdService();
83     void QueryPPDInformation(const char *makeModel, std::vector<std::string> &ppds);
84     int32_t AddPrinterToCups(const std::string &printerUri, const std::string &printerName,
85         const std::string &printerMake);
86     int32_t AddPrinterToCupsWithSpecificPpd(const std::string &printerUri, const std::string &printerName,
87         const std::string &ppd);
88     int32_t AddPrinterToCupsWithPpd(const std::string &printerUri, const std::string &printerName,
89         const std::string &ppdName, const std::string &ppdData);
90     int32_t QueryPrinterCapabilityByUri(const std::string &printerUri, const std::string &printerId,
91         PrinterCapability &printerCaps);
92     int32_t QueryPrinterStatusByUri(const std::string &printerUri, PrinterStatus &status);
93     int32_t DeleteCupsPrinter(const char *printerName);
94     void AddCupsPrintJob(const PrintJob &jobInfo);
95     void CancelCupsJob(std::string serviceJobId);
96 
97     int32_t QueryAddedPrinterList(std::vector<std::string> &printerName);
98     ppd_file_t* GetPPDFile(const std::string &printerName);
99     int32_t SetDefaultPrinter(const std::string &printerName);
100 
101     int32_t QueryPrinterAttrList(const std::string &printerName, const std::vector<std::string> &keyList,
102         std::vector<std::string> &valueList);
103     int32_t QueryPrinterInfoByPrinterId(const std::string& printerId, PrinterInfo &info);
104     int32_t DiscoverUsbPrinters(std::vector<PrinterInfo> &printers);
105     int32_t QueryPrinterCapabilityFromPPD(const std::string &name, PrinterCapability &printerCaps);
106     bool CheckPrinterOnline(JobMonitorParam *param, const uint32_t timeout = 3000);
107 
108 private:
109     bool HandleFiles(JobParameters *jobParams, uint32_t num_files, http_t *http, uint32_t jobId);
110     void StartCupsJob(JobParameters *jobParams, CallbackFunc callback);
111     void MonitorJobState(JobMonitorParam *param, CallbackFunc callback);
112     void HandleJobState(http_t *http, JobMonitorParam *param, JobStatus *jobStatus,
113         JobStatus *prevousJobStatus);
114     void QueryJobState(http_t *http, JobMonitorParam *param, JobStatus *jobStatus);
115     void JobStatusCallback(JobMonitorParam *param, JobStatus *jobStatus, bool isOffline);
116     static void ReportBlockedReason(JobMonitorParam *param, JobStatus *jobStatus);
117     static void SymlinkFile(std::string &srcFilePath, std::string &destFilePath);
118     static void SymlinkDirectory(const char *srcDir, const char *destDir);
119     static void CopyDirectory(const char *srcDir, const char *destDir);
120     static bool ChangeFilterPermission(const std::string &path, mode_t mode);
121     bool CheckPrinterMakeModel(JobParameters *jobParams);
122     bool VerifyPrintJob(JobParameters *jobParams, int &num_options, uint32_t &jobId,
123         cups_option_t *options, http_t *http);
124     static int FillBorderlessOptions(JobParameters *jobParams, int num_options, cups_option_t **options);
125     static int FillLandscapeOptions(JobParameters *jobParams, int num_options, cups_option_t **options);
126     static int FillJobOptions(JobParameters *jobParams, int num_options, cups_option_t **options);
127     static float ConvertInchTo100MM(float num);
128     static void UpdateJobStatus(JobStatus *prevousJobStatus, JobStatus *jobStatus);
129     static void UpdatePrintJobStateInJobParams(JobParameters *jobParams, uint32_t state, uint32_t subState);
130     static std::string GetIpAddress(unsigned int number);
131     static bool IsIpConflict(const std::string &printerId, std::string &nic);
132     void QueryJobStateAgain(http_t *http, JobMonitorParam *param, JobStatus *jobStatus);
133     static uint32_t GetBlockedSubstate(JobStatus *jobStatus);
134 
135     int32_t StartCupsdService();
136     JobParameters *GetNextJob();
137     void StartNextJob();
138     void JobCompleteCallback();
139 
140     void UpdateBorderlessJobParameter(json& optionJson, JobParameters *params);
141     void UpdateJobParameterByOption(json& optionJson, JobParameters *params);
142     JobParameters* BuildJobParameters(const PrintJob &jobInfo);
143     std::string GetColorString(uint32_t colorCode);
144     std::string GetMedieSize(const PrintJob &jobInfo);
145     std::string GetDulpexString(uint32_t duplexCode);
146     void DumpJobParameters(JobParameters* jobParams);
147     bool IsCupsServerAlive();
148     bool IsPrinterExist(const char *printerUri, const char *printerName, const char *ppdName);
149 
150     void ParsePPDInfo(ipp_t *response, const char *ppd_make_model, const char *ppd_name,
151         std::vector<std::string> &ppds);
152     ipp_t *QueryPrinterAttributesByUri(const std::string &printerUri, const std::string &nic, int num,
153         const char * const *pattrs);
154     bool ResumePrinter(const std::string &printerName);
155     bool CancelPrinterJob(int cupsJobId);
156 
157 private:
158     bool toCups_ = true;
159     IPrintAbilityBase* printAbility_ = nullptr;
160     std::vector<JobParameters*> jobQueue_;
161     JobParameters *currentJob_ = nullptr;
162 };
163 } // namespace OHOS::Print
164 #endif // PRINT_CUPS_CLIENT_H