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 <chrono>
17 #include "vendor_manager.h"
18 #include "vendor_helper.h"
19 #include "vendor_bsuni_driver.h"
20 #include "vendor_ipp_everywhere.h"
21 #include "print_log.h"
22
23 using namespace OHOS::Print;
24 namespace {
25 const std::string VENDOR_MANAGER_PREFIX = "fwk.";
26 const std::string GLOBAL_ID_DELIMITER = ":";
27 const int MONITOR_CHECK_INTERVAL_MS = 1000;
28 const size_t IP_LENGTH_MIN = 10;
29 }
30
VendorManager()31 VendorManager::VendorManager() {}
32
~VendorManager()33 VendorManager::~VendorManager()
34 {
35 UnInit();
36 }
37
GetGlobalVendorName(const std::string &vendorName)38 std::string VendorManager::GetGlobalVendorName(const std::string &vendorName)
39 {
40 return VENDOR_MANAGER_PREFIX + vendorName;
41 }
GetGlobalPrinterId(const std::string &globalVendorName, const std::string &printerId)42 std::string VendorManager::GetGlobalPrinterId(const std::string &globalVendorName, const std::string &printerId)
43 {
44 return globalVendorName + GLOBAL_ID_DELIMITER + printerId;
45 }
ExtractVendorName(const std::string &globalVendorName)46 std::string VendorManager::ExtractVendorName(const std::string &globalVendorName)
47 {
48 auto pos = globalVendorName.find(VENDOR_MANAGER_PREFIX);
49 if (pos != 0 || globalVendorName.length() <= VENDOR_MANAGER_PREFIX.length()) {
50 return "";
51 }
52 return globalVendorName.substr(VENDOR_MANAGER_PREFIX.length());
53 }
54
ExtractGlobalVendorName(const std::string &globalPrinterId)55 std::string VendorManager::ExtractGlobalVendorName(const std::string &globalPrinterId)
56 {
57 auto pos = globalPrinterId.find(GLOBAL_ID_DELIMITER);
58 if (pos == std::string::npos) {
59 return "";
60 }
61 return globalPrinterId.substr(0, pos);
62 }
63
ExtractPrinterId(const std::string &globalPrinterId)64 std::string VendorManager::ExtractPrinterId(const std::string &globalPrinterId)
65 {
66 auto pos = globalPrinterId.find(GLOBAL_ID_DELIMITER);
67 if (pos == std::string::npos || globalPrinterId.length() <= pos + 1) {
68 return "";
69 }
70 return globalPrinterId.substr(pos + 1);
71 }
72
Init(IPrintServiceAbility *sa, bool loadDefault)73 bool VendorManager::Init(IPrintServiceAbility *sa, bool loadDefault)
74 {
75 PRINT_HILOGI("Init enter");
76 printServiceAbility = sa;
77 if (!loadDefault) {
78 return true;
79 }
80 bool expectLoaded = false;
81 if (!defaultLoaded.compare_exchange_strong(expectLoaded, true)) {
82 PRINT_HILOGI("load already");
83 return true;
84 }
85 PRINT_HILOGI("load default vendor...");
86 auto vendorBsUni = std::make_shared<VendorBsuniDriver>();
87 if (!LoadVendorDriver(vendorBsUni)) {
88 PRINT_HILOGW("BsUni driver load fail");
89 auto vendorIppEverywhere = std::make_shared<VendorIppEveryWhere>();
90 if (!LoadVendorDriver(vendorIppEverywhere)) {
91 PRINT_HILOGW("IppEverywhere driver load fail");
92 return false;
93 }
94 }
95 PRINT_HILOGI("Init quit");
96 return true;
97 }
98
UnInit()99 void VendorManager::UnInit()
100 {
101 PRINT_HILOGI("UnInit enter");
102 StopStatusMonitor();
103 std::lock_guard<std::mutex> lock(vendorMapMutex);
104 for (auto const &pair : vendorMap) {
105 PRINT_HILOGD("UnInit %{public}s", pair.first.c_str());
106 if (pair.second == nullptr) {
107 PRINT_HILOGW("vendor extension is null");
108 continue;
109 }
110 pair.second->OnDestroy();
111 pair.second->UnInit();
112 }
113 vendorMap.clear();
114 printServiceAbility = nullptr;
115 defaultLoaded = false;
116 PRINT_HILOGI("UnInit quit");
117 }
118
LoadVendorDriver(std::shared_ptr<VendorDriverBase> vendorDriver)119 bool VendorManager::LoadVendorDriver(std::shared_ptr<VendorDriverBase> vendorDriver)
120 {
121 if (vendorDriver == nullptr) {
122 PRINT_HILOGW("vendorDriver is null");
123 return false;
124 }
125 if (!vendorDriver->Init(this)) {
126 PRINT_HILOGW("vendorDriver init fail");
127 return false;
128 }
129 std::lock_guard<std::mutex> lock(vendorMapMutex);
130 vendorMap.insert(std::make_pair(vendorDriver->GetVendorName(), vendorDriver));
131 vendorDriver->OnCreate();
132 return true;
133 }
UnloadVendorDriver(const std::string &vendorName)134 bool VendorManager::UnloadVendorDriver(const std::string &vendorName)
135 {
136 std::lock_guard<std::mutex> lock(vendorMapMutex);
137 auto iter = vendorMap.find(vendorName);
138 if (iter == vendorMap.end()) {
139 return false;
140 }
141 auto vendorDriver = iter->second;
142 vendorMap.erase(iter);
143 if (vendorDriver != nullptr) {
144 vendorDriver->OnDestroy();
145 vendorDriver->UnInit();
146 }
147 return true;
148 }
149
ConnectPrinter(const std::string &globalPrinterId)150 bool VendorManager::ConnectPrinter(const std::string &globalPrinterId)
151 {
152 PRINT_HILOGI("ConnectPrinter enter");
153 std::string printerId = ExtractPrinterId(globalPrinterId);
154 if (printerId.empty()) {
155 PRINT_HILOGW("empty printer id");
156 return false;
157 }
158 auto vendorDriver = FindDriverByPrinterId(globalPrinterId);
159 if (vendorDriver == nullptr) {
160 PRINT_HILOGW("vendorDriver is null");
161 return false;
162 }
163 PRINT_HILOGD("OnQueryCapability: %{public}s", printerId.c_str());
164 return vendorDriver->OnQueryCapability(printerId, 0);
165 }
166
ConnectPrinterByIp(const std::string &printerIp, const std::string &protocol)167 bool VendorManager::ConnectPrinterByIp(const std::string &printerIp, const std::string &protocol)
168 {
169 PRINT_HILOGI("ConnectPrinterByIp enter");
170 bool ret = false;
171 if (printerIp.size() < IP_LENGTH_MIN) {
172 PRINT_HILOGW("ip length incorrect");
173 return ret;
174 }
175 for (auto const &pair : vendorMap) {
176 PRINT_HILOGD("ConnectPrinterByIp %{public}s", pair.first.c_str());
177 if (pair.second == nullptr) {
178 PRINT_HILOGW("vendor extension is null");
179 continue;
180 }
181 if (pair.second->OnQueryCapabilityByIp(printerIp, protocol)) {
182 ret = true;
183 }
184 }
185 PRINT_HILOGI("ConnectPrinterByIp quit");
186 return ret;
187 }
188
QueryPrinterInfo(const std::string &globalPrinterId, int timeout)189 bool VendorManager::QueryPrinterInfo(const std::string &globalPrinterId, int timeout)
190 {
191 PRINT_HILOGI("QueryPrinterInfo enter");
192 std::string printerId = ExtractPrinterId(globalPrinterId);
193 if (printerId.empty()) {
194 PRINT_HILOGW("empty printer id");
195 return false;
196 }
197 auto vendorDriver = FindDriverByPrinterId(globalPrinterId);
198 if (vendorDriver == nullptr) {
199 PRINT_HILOGW("vendorDriver is null");
200 return false;
201 }
202 PRINT_HILOGD("OnQueryCapability: %{public}s", printerId.c_str());
203 vendorDriver->OnQueryCapability(printerId, timeout);
204 PRINT_HILOGI("QueryPrinterInfo quit");
205 return true;
206 }
207
StartDiscovery()208 void VendorManager::StartDiscovery()
209 {
210 PRINT_HILOGI("StartDiscovery enter");
211 std::lock_guard<std::mutex> lock(vendorMapMutex);
212 for (auto const &pair : vendorMap) {
213 PRINT_HILOGD("StartDiscovery %{public}s", pair.first.c_str());
214 if (pair.second == nullptr) {
215 PRINT_HILOGW("vendor extension is null");
216 continue;
217 }
218 pair.second->OnStartDiscovery();
219 }
220 PRINT_HILOGI("StartDiscovery quit");
221 }
StopDiscovery()222 void VendorManager::StopDiscovery()
223 {
224 PRINT_HILOGI("StopDiscovery enter");
225 std::lock_guard<std::mutex> lock(vendorMapMutex);
226 for (auto const &pair : vendorMap) {
227 if (pair.second == nullptr) {
228 PRINT_HILOGW("vendor extension is null");
229 continue;
230 }
231 pair.second->OnStopDiscovery();
232 }
233 PRINT_HILOGI("StopDiscovery quit");
234 }
235
AddPrinterToDiscovery(const std::string &vendorName, const PrinterInfo &printerInfo)236 int32_t VendorManager::AddPrinterToDiscovery(const std::string &vendorName, const PrinterInfo &printerInfo)
237 {
238 PRINT_HILOGI("AddPrinterToDiscovery enter");
239 if (printServiceAbility == nullptr) {
240 PRINT_HILOGW("printServiceAbility is null");
241 return EXTENSION_ERROR_CALLBACK_FAIL;
242 }
243 if (!printServiceAbility->AddVendorPrinterToDiscovery(GetGlobalVendorName(vendorName), printerInfo)) {
244 PRINT_HILOGW("AddPrinterToDiscovery fail");
245 return EXTENSION_ERROR_CALLBACK_FAIL;
246 }
247 PRINT_HILOGI("AddPrinterToDiscovery quit");
248 return EXTENSION_ERROR_NONE;
249 }
250
UpdatePrinterToDiscovery(const std::string &vendorName, const PrinterInfo &printerInfo)251 int32_t VendorManager::UpdatePrinterToDiscovery(const std::string &vendorName, const PrinterInfo &printerInfo)
252 {
253 PRINT_HILOGI("UpdatePrinterToDiscovery enter");
254 if (printServiceAbility == nullptr) {
255 PRINT_HILOGW("printServiceAbility is null");
256 return EXTENSION_ERROR_CALLBACK_FAIL;
257 }
258 std::string globalVendorName = GetGlobalVendorName(vendorName);
259 if (!printServiceAbility->UpdateVendorPrinterToDiscovery(globalVendorName, printerInfo)) {
260 PRINT_HILOGW("UpdatePrinterToDiscovery fail");
261 return EXTENSION_ERROR_CALLBACK_FAIL;
262 }
263 PRINT_HILOGI("UpdatePrinterToDiscovery quit");
264 return EXTENSION_ERROR_NONE;
265 }
RemovePrinterFromDiscovery(const std::string &vendorName, const std::string &printerId)266 int32_t VendorManager::RemovePrinterFromDiscovery(const std::string &vendorName, const std::string &printerId)
267 {
268 PRINT_HILOGI("RemovePrinterFromDiscovery enter");
269 if (printServiceAbility == nullptr) {
270 PRINT_HILOGW("printServiceAbility is null");
271 return EXTENSION_ERROR_CALLBACK_FAIL;
272 }
273 if (!printServiceAbility->RemoveVendorPrinterFromDiscovery(GetGlobalVendorName(vendorName), printerId)) {
274 PRINT_HILOGW("RemovePrinterFromDiscovery fail");
275 return EXTENSION_ERROR_CALLBACK_FAIL;
276 }
277 PRINT_HILOGI("RemovePrinterFromDiscovery quit");
278 return EXTENSION_ERROR_NONE;
279 }
280
AddPrinterToCupsWithPpd(const std::string &vendorName, const std::string &printerId, const std::string &ppdData)281 int32_t VendorManager::AddPrinterToCupsWithPpd(const std::string &vendorName, const std::string &printerId,
282 const std::string &ppdData)
283 {
284 PRINT_HILOGI("AddPrinterToCupsWithPpd enter");
285 if (printServiceAbility == nullptr) {
286 PRINT_HILOGW("printServiceAbility is null");
287 return EXTENSION_ERROR_CALLBACK_FAIL;
288 }
289 std::string globalVendorName = GetGlobalVendorName(vendorName);
290 if (!printServiceAbility->AddVendorPrinterToCupsWithPpd(globalVendorName, printerId, ppdData)) {
291 PRINT_HILOGW("AddPrinterToCupsWithPpd fail");
292 return EXTENSION_ERROR_CALLBACK_FAIL;
293 }
294 PRINT_HILOGI("AddPrinterToCupsWithPpd quit");
295 return EXTENSION_ERROR_NONE;
296 }
297
RemovePrinterFromCups(const std::string &vendorName, const std::string &printerId)298 int32_t VendorManager::RemovePrinterFromCups(const std::string &vendorName, const std::string &printerId)
299 {
300 PRINT_HILOGI("RemovePrinterFromCups enter");
301 if (printServiceAbility == nullptr) {
302 PRINT_HILOGW("printServiceAbility is null");
303 return EXTENSION_ERROR_CALLBACK_FAIL;
304 }
305 std::string globalVendorName = GetGlobalVendorName(vendorName);
306 if (!printServiceAbility->RemoveVendorPrinterFromCups(globalVendorName, printerId)) {
307 PRINT_HILOGW("RemovePrinterFromCups fail");
308 return EXTENSION_ERROR_CALLBACK_FAIL;
309 }
310 PRINT_HILOGI("RemovePrinterFromCups quit");
311 return EXTENSION_ERROR_NONE;
312 }
313
OnPrinterPpdQueried(const std::string &vendorName, const std::string &printerId, const std::string &ppdData)314 bool VendorManager::OnPrinterPpdQueried(const std::string &vendorName, const std::string &printerId,
315 const std::string &ppdData)
316 {
317 PRINT_HILOGI("OnPrinterPpdQueried enter");
318 if (printServiceAbility == nullptr) {
319 PRINT_HILOGW("printServiceAbility is null");
320 return false;
321 }
322 std::string globalVendorName = GetGlobalVendorName(vendorName);
323 std::string globalPrinterId = GetGlobalPrinterId(globalVendorName, printerId);
324 PRINT_HILOGD("global printer id %{public}s", globalPrinterId.c_str());
325 if (!IsConnectingPrinter(globalPrinterId, "")) {
326 PRINT_HILOGW("not connecting");
327 return false;
328 }
329 if (!printServiceAbility->AddVendorPrinterToCupsWithPpd(globalVendorName, printerId, ppdData)) {
330 PRINT_HILOGW("AddPrinterToCupsWithPpd fail");
331 return false;
332 }
333 PRINT_HILOGI("OnPrinterPpdQueried quit");
334 return true;
335 }
336
OnPrinterStatusChanged(const std::string &vendorName, const std::string &printerId, const PrinterVendorStatus &status)337 bool VendorManager::OnPrinterStatusChanged(const std::string &vendorName, const std::string &printerId,
338 const PrinterVendorStatus &status)
339 {
340 std::string globalVendorName = GetGlobalVendorName(vendorName);
341 if (printServiceAbility != nullptr) {
342 return printServiceAbility->OnVendorStatusUpdate(globalVendorName, printerId, status);
343 }
344 return true;
345 }
346
FindDriverByPrinterId(const std::string &globalPrinterId)347 std::shared_ptr<VendorDriverBase> VendorManager::FindDriverByPrinterId(const std::string &globalPrinterId)
348 {
349 std::string globalVendorName = ExtractGlobalVendorName(globalPrinterId);
350 std::string vendorName = ExtractVendorName(globalVendorName);
351 if (vendorName.empty()) {
352 PRINT_HILOGW("Invalid printer id");
353 return nullptr;
354 }
355 return FindDriverByVendorName(vendorName);
356 }
357
FindDriverByVendorName(const std::string &vendorName)358 std::shared_ptr<VendorDriverBase> VendorManager::FindDriverByVendorName(const std::string &vendorName)
359 {
360 std::lock_guard<std::mutex> lock(vendorMapMutex);
361 auto iter = vendorMap.find(vendorName);
362 if (iter == vendorMap.end()) {
363 PRINT_HILOGW("cannot find vendor extension: %{public}s", vendorName.c_str());
364 return nullptr;
365 }
366 return iter->second;
367 }
368
StartStatusMonitor()369 void VendorManager::StartStatusMonitor()
370 {
371 PRINT_HILOGI("StartStatusMonitor Enter");
372 {
373 std::unique_lock<std::mutex> lock(statusMonitorMutex);
374 if (statusMonitorOn) {
375 PRINT_HILOGW("already on");
376 return;
377 }
378 statusMonitorOn = true;
379 }
380 PRINT_HILOGI("StartStatusMonitor Now");
381 statusMonitorThread = std::thread(&VendorManager::StatusMonitorProcess, this);
382 PRINT_HILOGI("StartStatusMonitor Quit");
383 }
384
StopStatusMonitor()385 void VendorManager::StopStatusMonitor()
386 {
387 PRINT_HILOGI("StopStatusMonitor Enter");
388 {
389 std::unique_lock<std::mutex> lock(statusMonitorMutex);
390 statusMonitorOn = false;
391 }
392 statusMonitorCondition.notify_one();
393 if (statusMonitorThread.joinable()) {
394 statusMonitorThread.join();
395 }
396 PRINT_HILOGI("StopStatusMonitor Quit");
397 }
398
StatusMonitorProcess()399 void VendorManager::StatusMonitorProcess()
400 {
401 PRINT_HILOGI("StatusMonitorProcess Enter");
402 while (WaitNext()) {
403 UpdateAllPrinterStatus();
404 }
405 PRINT_HILOGI("StatusMonitorProcess Quit");
406 }
407
UpdateAllPrinterStatus()408 void VendorManager::UpdateAllPrinterStatus()
409 {
410 std::lock_guard<std::mutex> lock(vendorMapMutex);
411 for (auto const &pair : vendorMap) {
412 if (pair.second == nullptr) {
413 PRINT_HILOGW("vendor extension is null");
414 continue;
415 }
416 pair.second->UpdateAllPrinterStatus();
417 }
418 }
419
WaitNext()420 bool VendorManager::WaitNext()
421 {
422 std::unique_lock<std::mutex> lock(statusMonitorMutex);
423 if (!statusMonitorOn) {
424 return false;
425 }
426 statusMonitorCondition.wait_for(lock, std::chrono::milliseconds(MONITOR_CHECK_INTERVAL_MS));
427 if (!statusMonitorOn) {
428 return false;
429 }
430 return true;
431 }
432
MonitorPrinterStatus(const std::string &globalPrinterId, bool on)433 bool VendorManager::MonitorPrinterStatus(const std::string &globalPrinterId, bool on)
434 {
435 std::string globalVendorName = ExtractGlobalVendorName(globalPrinterId);
436 std::string printerId = ExtractPrinterId(globalPrinterId);
437 if (globalVendorName.empty() || printerId.empty()) {
438 PRINT_HILOGW("invalid printer id: %{private}s", globalPrinterId.c_str());
439 return false;
440 }
441 std::string vendorName = ExtractVendorName(globalVendorName);
442 if (vendorName.empty()) {
443 PRINT_HILOGW("vendor name empty");
444 return false;
445 }
446 auto vendorDriver = FindDriverByVendorName(vendorName);
447 if (vendorDriver == nullptr) {
448 PRINT_HILOGW("vendor driver is null");
449 return false;
450 }
451 return vendorDriver->MonitorPrinterStatus(printerId, on);
452 }
453
IsConnectingPrinter(const std::string &id, const std::string &uri)454 bool VendorManager::IsConnectingPrinter(const std::string &id, const std::string &uri)
455 {
456 std::lock_guard<std::mutex> lock(simpleObjectMutex);
457 if (isConnecting && !connectingPrinter.empty()) {
458 if (connectingMethod == ID_AUTO) {
459 return id == connectingPrinter;
460 } else {
461 return uri.find(connectingPrinter) != std::string::npos;
462 }
463 }
464 return false;
465 }
466
SetConnectingPrinter(ConnectMethod method, const std::string &printer)467 void VendorManager::SetConnectingPrinter(ConnectMethod method, const std::string &printer)
468 {
469 std::lock_guard<std::mutex> lock(simpleObjectMutex);
470 connectingMethod = method;
471 connectingPrinter = printer;
472 isConnecting = true;
473 }
474
ClearConnectingPrinter()475 void VendorManager::ClearConnectingPrinter()
476 {
477 PRINT_HILOGD("ClearConnectingPrinter");
478 std::lock_guard<std::mutex> lock(simpleObjectMutex);
479 isConnecting = false;
480 }
481
QueryPrinterCapabilityByUri(const std::string &uri, PrinterCapability &printerCap)482 bool VendorManager::QueryPrinterCapabilityByUri(const std::string &uri, PrinterCapability &printerCap)
483 {
484 if (printServiceAbility == nullptr) {
485 PRINT_HILOGW("printServiceAbility is null");
486 return false;
487 }
488 return printServiceAbility->QueryPrinterCapabilityByUri(uri, printerCap);
489 }
490
QueryPrinterStatusByUri(const std::string &uri, PrinterStatus &status)491 bool VendorManager::QueryPrinterStatusByUri(const std::string &uri, PrinterStatus &status)
492 {
493 if (printServiceAbility == nullptr) {
494 PRINT_HILOGW("printServiceAbility is null");
495 return false;
496 }
497 return printServiceAbility->QueryPrinterStatusByUri(uri, status);
498 }
499