1 /*
2 * Copyright (c) 2024 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 "vendor_ppd_driver.h"
17 #include "print_log.h"
18
19 using namespace OHOS::Print;
20 const int DISCOVERY_INTERVAL_MS = 5000;
21
VendorPpdDriver()22 VendorPpdDriver::VendorPpdDriver() {}
23
~VendorPpdDriver()24 VendorPpdDriver::~VendorPpdDriver()
25 {
26 UnInit();
27 }
28
Init(IPrinterVendorManager * manager)29 bool VendorPpdDriver::Init(IPrinterVendorManager *manager)
30 {
31 if (!VendorDriverBase::Init(manager)) {
32 PRINT_HILOGE("VendorDriverBase init fail");
33 return false;
34 }
35 return true;
36 }
37
UnInit()38 void VendorPpdDriver::UnInit()
39 {
40 OnStopDiscovery();
41 VendorDriverBase::UnInit();
42 }
43
GetVendorName()44 std::string VendorPpdDriver::GetVendorName()
45 {
46 return VENDOR_PPD_DRIVER;
47 }
48
OnQueryCapability(const std::string & printerId,int timeout)49 bool VendorPpdDriver::OnQueryCapability(const std::string &printerId, int timeout)
50 {
51 if (vendorManager == nullptr) {
52 PRINT_HILOGE("vendorManager is null");
53 return false;
54 }
55 auto printerInfo = vendorManager->QueryDiscoveredPrinterInfoById(GetVendorName(), printerId);
56 if (printerInfo == nullptr) {
57 PRINT_HILOGE("printer is not discovered.");
58 return false;
59 }
60 return TryConnectByPpdDriver(*printerInfo);
61 }
62
OnPrinterDiscovered(const std::string & vendorName,const PrinterInfo & printerInfo)63 int32_t VendorPpdDriver::OnPrinterDiscovered(const std::string &vendorName, const PrinterInfo &printerInfo)
64 {
65 connectingVendorGroup = vendorName;
66 connectingPrinterInfo = std::make_shared<PrinterInfo>(printerInfo);
67 return 0;
68 }
69
QueryProperty(const std::string & printerId,const std::string & key,std::string & value)70 bool VendorPpdDriver::QueryProperty(const std::string &printerId, const std::string &key, std::string &value)
71 {
72 if (connectingPrinterInfo == nullptr) {
73 PRINT_HILOGW("connectingPrinterInfo is null");
74 return false;
75 }
76 if (connectingPrinterInfo->GetPrinterId() != printerId) {
77 PRINT_HILOGW("not connecting printer");
78 return false;
79 }
80 if (key == PRINTER_PROPERTY_KEY_CUPS_PPD_NAME) {
81 auto makeAndModel = connectingPrinterInfo->GetPrinterMake();
82 value = QueryPpdName(makeAndModel);
83 return !value.empty();
84 }
85 return false;
86 }
87
QueryPpdName(const std::string & makeAndModel)88 std::string VendorPpdDriver::QueryPpdName(const std::string &makeAndModel)
89 {
90 if (vendorManager == nullptr) {
91 PRINT_HILOGW("vendorManager is null");
92 return std::string();
93 }
94 std::string ppdName;
95 if (!vendorManager->QueryPPDInformation(makeAndModel, ppdName)) {
96 PRINT_HILOGW("QueryPPDInformation fail. printerMake = %{public}s", makeAndModel.c_str());
97 return std::string();
98 }
99 return ppdName;
100 }
101
UpdateAllPrinterStatus()102 void VendorPpdDriver::UpdateAllPrinterStatus()
103 {
104 // not need update vendor backend printer by monitor. use default status by discovered state.
105 return;
106 }
107
DiscoverBackendPrinters()108 void VendorPpdDriver::DiscoverBackendPrinters()
109 {
110 std::vector<PrinterInfo> printers = {};
111 if (vendorManager == nullptr) {
112 PRINT_HILOGW("vendorManager is null");
113 return;
114 }
115 if (vendorManager->DiscoverBackendPrinters(GetVendorName(), printers) != E_PRINT_NONE) {
116 PRINT_HILOGW("Discovery backend printer fail.");
117 return;
118 }
119 std::unique_lock<std::mutex> lock(updateDiscoveryMutex_);
120 for (auto &isDiscoveredPair : discoveredPrinters_) {
121 isDiscoveredPair.second = false;
122 }
123 // add or update new printer is discovered
124 for (const auto &printer : printers) {
125 discoveredPrinters_[printer.GetPrinterId()] = true;
126 vendorManager->AddPrinterToDiscovery(GetVendorName(), printer);
127 }
128 // remove non-discovered printer
129 for (const auto &isDiscoveredPair : discoveredPrinters_) {
130 if (!isDiscoveredPair.second) {
131 vendorManager->RemovePrinterFromDiscovery(GetVendorName(), isDiscoveredPair.first);
132 }
133 }
134 }
135
OnStartDiscovery()136 void VendorPpdDriver::OnStartDiscovery()
137 {
138 PRINT_HILOGD("OnStartDiscovery enter");
139 if (vendorManager == nullptr) {
140 PRINT_HILOGW("OnStartDiscovery vendorManager is null.");
141 return;
142 }
143 std::unique_lock<std::mutex> lock(discoveryStateChangeMutex_);
144 if (!isDiscovering_) {
145 isDiscovering_ = true;
146 discoveryThread_ = std::thread(&VendorPpdDriver::DiscoveryProcess, this);
147 } else {
148 PRINT_HILOGW("allready start backend discovery.");
149 }
150 }
151
OnStopDiscovery()152 void VendorPpdDriver::OnStopDiscovery()
153 {
154 PRINT_HILOGD("OnStopDiscovery enter");
155 std::unique_lock<std::mutex> lock(discoveryStateChangeMutex_);
156 if (!isDiscovering_) {
157 PRINT_HILOGW("already stop discovery");
158 return;
159 }
160 isDiscovering_ = false;
161 waitDiscoveryCondition_.notify_all();
162 if (discoveryThread_.joinable()) {
163 discoveryThread_.join();
164 }
165 }
166
DiscoveryProcess()167 void VendorPpdDriver::DiscoveryProcess()
168 {
169 PRINT_HILOGI("DiscoveryProcess Enter");
170 while (WaitNext()) {
171 DiscoverBackendPrinters();
172 }
173 if (vendorManager == nullptr) {
174 PRINT_HILOGW("VendorManager is null. DiscoveryProcess Quit");
175 return;
176 }
177 std::unique_lock<std::mutex> lock(updateDiscoveryMutex_);
178 for (const auto &isDiscoveredPair : discoveredPrinters_) {
179 vendorManager->RemovePrinterFromDiscovery(GetVendorName(), isDiscoveredPair.first);
180 }
181 PRINT_HILOGI("DiscoveryProcess Quit");
182 }
183
WaitNext()184 bool VendorPpdDriver::WaitNext()
185 {
186 {
187 std::unique_lock<std::mutex> lock(waitDiscoveryMutex_);
188 waitDiscoveryCondition_.wait_for(lock, std::chrono::milliseconds(DISCOVERY_INTERVAL_MS),
189 [this] { return !isDiscovering_; });
190 }
191 if (!isDiscovering_) {
192 return false;
193 }
194 return true;
195 }
196
TryConnectByPpdDriver(const PrinterInfo & printerInfo)197 bool VendorPpdDriver::TryConnectByPpdDriver(const PrinterInfo &printerInfo)
198 {
199 if (vendorManager == nullptr) {
200 PRINT_HILOGW("vendorManager is null");
201 return false;
202 }
203 OnPrinterDiscovered(GetVendorName(), printerInfo);
204 std::string printerId = printerInfo.GetPrinterId();
205 std::string ppdName;
206 if (!QueryProperty(printerId, PRINTER_PROPERTY_KEY_CUPS_PPD_NAME, ppdName)) {
207 PRINT_HILOGI("no matched ppd");
208 return false;
209 }
210 if (vendorManager->AddPrinterToCupsWithPpd(GetVendorName(), VendorManager::ExtractPrinterId(printerId),
211 ppdName, "") != EXTENSION_ERROR_NONE) {
212 PRINT_HILOGI("AddPrinterToCupsWithPpd fail.");
213 return false;
214 }
215 PRINT_HILOGI("AddPrinterToCupsWithPpd success.");
216 return true;
217 }
218