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_bsuni_driver.h"
17 #include <dlfcn.h>
18 #include "parameter.h"
19 #include "print_log.h"
20 #include "vendor_helper.h"
21
22 using namespace OHOS::Print;
23 namespace {
24 std::mutex g_driverMutex;
25 VendorBsuniDriver *g_driverWrapper = nullptr;
26 }
27
SetDriverWrapper(VendorBsuniDriver * driver)28 void VendorBsuniDriver::SetDriverWrapper(VendorBsuniDriver *driver)
29 {
30 std::lock_guard<std::mutex> lock(g_driverMutex);
31 g_driverWrapper = driver;
32 }
33
CheckVendorExtension(Print_VendorExtension * extension)34 bool VendorBsuniDriver::CheckVendorExtension(Print_VendorExtension *extension)
35 {
36 if (extension == nullptr) {
37 PRINT_HILOGW("extension is null");
38 return false;
39 }
40 if (extension->onCreate == nullptr || extension->onDestroy == nullptr || extension->onStartDiscovery == nullptr ||
41 extension->onStopDiscovery == nullptr || extension->onConnectPrinter == nullptr ||
42 extension->onDisconnectPrinter == nullptr || extension->onQueryCapability == nullptr ||
43 extension->onQueryCapabilityByIp == nullptr || extension->onQueryProperties == nullptr) {
44 PRINT_HILOGW("invalid extension");
45 return false;
46 }
47 return true;
48 }
LoadDriverExtension()49 bool VendorBsuniDriver::LoadDriverExtension()
50 {
51 vendorExtension = nullptr;
52 if (bsUniDriverHandler != nullptr) {
53 dlclose(bsUniDriverHandler);
54 bsUniDriverHandler = nullptr;
55 }
56 const std::string DRIVER_SO_PATH = "print.libbsUniDiscovery.so.path";
57 constexpr int BUFFER_SIZE = 96;
58 char value[BUFFER_SIZE] = {0};
59 GetParameter(DRIVER_SO_PATH.c_str(), "", value, BUFFER_SIZE - 1);
60 bsUniDriverHandler = dlopen(value, RTLD_LAZY | RTLD_NODELETE);
61 if (bsUniDriverHandler == nullptr) {
62 PRINT_HILOGW("dlopen failed");
63 return false;
64 }
65 do {
66 typedef Print_VendorExtension *(*GetPrintVendorExtensionFunc)();
67 GetPrintVendorExtensionFunc func =
68 reinterpret_cast<GetPrintVendorExtensionFunc>(dlsym(bsUniDriverHandler, "GetPrintVendorExtension"));
69 if (func == nullptr) {
70 PRINT_HILOGW("dlsym GetPrintVendorExtension failed");
71 break;
72 }
73 Print_VendorExtension *extension = func();
74 if (!CheckVendorExtension(extension)) {
75 break;
76 }
77 vendorExtension = extension;
78 return true;
79 } while (false);
80 if (bsUniDriverHandler != nullptr) {
81 dlclose(bsUniDriverHandler);
82 bsUniDriverHandler = nullptr;
83 }
84 return false;
85 }
86
AddPrinterToDiscovery(const Print_DiscoveryItem * discoveryItem)87 int32_t VendorBsuniDriver::AddPrinterToDiscovery(const Print_DiscoveryItem *discoveryItem)
88 {
89 PRINT_HILOGI("BsUni callback AddPrinterToDiscovery");
90 LogDiscoveryItem(discoveryItem);
91 auto info = std::make_shared<PrinterInfo>();
92 if (!UpdatePrinterInfoWithDiscovery(*info, discoveryItem)) {
93 PRINT_HILOGW("fail to convert discoveryItem to printer info");
94 return EXTENSION_INVALID_PARAMETER;
95 }
96 std::lock_guard<std::mutex> lock(g_driverMutex);
97 if (g_driverWrapper == nullptr) {
98 PRINT_HILOGW("driver released");
99 return EXTENSION_ERROR_CALLBACK_NULL;
100 }
101 auto op = std::bind(&VendorBsuniDriver::OnDiscoveredPrinterAdd, g_driverWrapper, info);
102 if (!g_driverWrapper->opQueue.Push(op)) {
103 PRINT_HILOGW("fail to add discovered printer");
104 return EXTENSION_ERROR_CALLBACK_FAIL;
105 }
106 return EXTENSION_ERROR_NONE;
107 }
108
RemovePrinterFromDiscovery(const char * printerId)109 int32_t VendorBsuniDriver::RemovePrinterFromDiscovery(const char *printerId)
110 {
111 PRINT_HILOGI("BsUni callback RemovePrinterFromDiscovery");
112 if (printerId == nullptr) {
113 PRINT_HILOGW("printerId is null");
114 return EXTENSION_INVALID_PARAMETER;
115 }
116 auto vendorPrinterId = std::make_shared<std::string>(printerId);
117 std::lock_guard<std::mutex> lock(g_driverMutex);
118 if (g_driverWrapper == nullptr) {
119 PRINT_HILOGW("driver released");
120 return EXTENSION_ERROR_CALLBACK_NULL;
121 }
122 auto op = std::bind(&VendorBsuniDriver::OnDiscoveredPrinterRemove, g_driverWrapper, vendorPrinterId);
123 if (!g_driverWrapper->opQueue.Push(op)) {
124 PRINT_HILOGW("fail to remove discovered printer");
125 return EXTENSION_ERROR_CALLBACK_FAIL;
126 }
127 return EXTENSION_ERROR_NONE;
128 }
129
AddPrinterToCups(const Print_DiscoveryItem * printer,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue,const char * ppdData)130 int32_t VendorBsuniDriver::AddPrinterToCups(const Print_DiscoveryItem *printer,
131 const Print_PrinterCapability *capability,
132 const Print_DefaultValue *defaultValue, const char *ppdData)
133 {
134 PRINT_HILOGI("BsUni callback AddPrinterToCups");
135 auto info = std::make_shared<PrinterInfo>();
136 if (!UpdatePrinterInfoWithDiscovery(*info, printer)) {
137 PRINT_HILOGW("update printer info fail");
138 return EXTENSION_INVALID_PARAMETER;
139 }
140 if (!UpdatePrinterInfoWithCapability(*info, printer, capability, defaultValue)) {
141 PRINT_HILOGW("update printer capability fail");
142 return EXTENSION_INVALID_PARAMETER;
143 }
144 std::shared_ptr<std::string> ppdContent;
145 if (ppdData != nullptr) {
146 ppdContent = std::make_shared<std::string>(ppdData);
147 }
148 std::lock_guard<std::mutex> lock(g_driverMutex);
149 if (g_driverWrapper == nullptr) {
150 PRINT_HILOGW("driver released");
151 return EXTENSION_ERROR_CALLBACK_NULL;
152 }
153 auto op = std::bind(&VendorBsuniDriver::OnCupsPrinterAdd, g_driverWrapper, info, ppdContent);
154 if (!g_driverWrapper->opQueue.Push(op)) {
155 PRINT_HILOGW("fail to add cups printer");
156 return EXTENSION_ERROR_CALLBACK_FAIL;
157 }
158 return EXTENSION_ERROR_NONE;
159 }
160
RemovePrinterFromCups(const char * printerId)161 int32_t VendorBsuniDriver::RemovePrinterFromCups(const char *printerId)
162 {
163 PRINT_HILOGI("BsUni callback RemovePrinterFromCups");
164 if (printerId == nullptr) {
165 PRINT_HILOGW("printer id to remove is null");
166 return EXTENSION_INVALID_PARAMETER;
167 }
168 auto vendorPrinterId = std::make_shared<std::string>(printerId);
169 std::lock_guard<std::mutex> lock(g_driverMutex);
170 if (g_driverWrapper == nullptr) {
171 PRINT_HILOGW("driver released");
172 return EXTENSION_ERROR_CALLBACK_NULL;
173 }
174 auto op = std::bind(&VendorBsuniDriver::OnCupsPrinterRemove, g_driverWrapper, vendorPrinterId);
175 if (!g_driverWrapper->opQueue.Push(op)) {
176 PRINT_HILOGW("fail to remove cups printer");
177 return EXTENSION_ERROR_CALLBACK_FAIL;
178 }
179 return EXTENSION_ERROR_NONE;
180 }
181
OnCapabilityQueried(const Print_DiscoveryItem * printer,const Print_PrinterCapability * capability,const Print_DefaultValue * defaultValue)182 int32_t VendorBsuniDriver::OnCapabilityQueried(const Print_DiscoveryItem *printer,
183 const Print_PrinterCapability *capability,
184 const Print_DefaultValue *defaultValue)
185 {
186 PRINT_HILOGI("BsUni callback OnCapabilityQueried");
187 LogDiscoveryItem(printer);
188 LogPageCapability(capability);
189 LogOtherCapability(capability);
190 LogDefaultValue(defaultValue);
191 auto printerInfo = ConvertVendorCapabilityToPrinterInfo(printer, capability, defaultValue);
192 if (printerInfo == nullptr) {
193 PRINT_HILOGW("printerInfo is null");
194 return EXTENSION_INVALID_PARAMETER;
195 }
196 std::lock_guard<std::mutex> lock(g_driverMutex);
197 if (g_driverWrapper == nullptr) {
198 PRINT_HILOGW("driver released");
199 return EXTENSION_ERROR_CALLBACK_NULL;
200 }
201 auto op = std::bind(&VendorBsuniDriver::OnPrinterCapabilityQueried, g_driverWrapper, printerInfo);
202 if (!g_driverWrapper->opQueue.Push(op)) {
203 PRINT_HILOGW("fail to queue capability");
204 return EXTENSION_ERROR_CALLBACK_FAIL;
205 }
206 return EXTENSION_ERROR_NONE;
207 }
208
OnPropertiesQueried(const char * printerId,const Print_PropertyList * propertyList)209 int32_t VendorBsuniDriver::OnPropertiesQueried(const char *printerId, const Print_PropertyList *propertyList)
210 {
211 PRINT_HILOGI("BsUni callback OnPropertiesQueried");
212 if (printerId == nullptr || propertyList == nullptr) {
213 PRINT_HILOGW("printerId is null");
214 return EXTENSION_INVALID_PARAMETER;
215 }
216 LogProperties(propertyList);
217 auto vendorPrinterId = std::make_shared<std::string>(printerId);
218 std::lock_guard<std::mutex> lock(g_driverMutex);
219 if (g_driverWrapper == nullptr) {
220 PRINT_HILOGW("driver released");
221 return EXTENSION_ERROR_CALLBACK_NULL;
222 }
223 std::string key = PRINTER_PROPERTY_KEY_CUPS_PPD_FILE;
224 auto ppdData = FindPropertyFromPropertyList(propertyList, key);
225 if (ppdData != nullptr) {
226 auto op = std::bind(&VendorBsuniDriver::OnPpdQueried, g_driverWrapper, vendorPrinterId, ppdData);
227 if (!g_driverWrapper->opQueue.Push(op)) {
228 PRINT_HILOGW("fail to queue ppd");
229 return EXTENSION_ERROR_CALLBACK_FAIL;
230 }
231 }
232 key = PRINTER_PROPERTY_KEY_DEVICE_STATE;
233 auto stateData = FindPropertyFromPropertyList(propertyList, key);
234 if (stateData != nullptr) {
235 auto op = std::bind(&VendorBsuniDriver::OnStateQueried, g_driverWrapper, vendorPrinterId, stateData);
236 if (!g_driverWrapper->opQueue.Push(op)) {
237 PRINT_HILOGW("fail to queue state");
238 return EXTENSION_ERROR_CALLBACK_FAIL;
239 }
240 }
241 return EXTENSION_ERROR_NONE;
242 }
243
VendorBsuniDriver()244 VendorBsuniDriver::VendorBsuniDriver() {}
245
~VendorBsuniDriver()246 VendorBsuniDriver::~VendorBsuniDriver() {}
247
Init(IPrinterVendorManager * manager)248 bool VendorBsuniDriver::Init(IPrinterVendorManager *manager)
249 {
250 PRINT_HILOGD("Init enter");
251 if (!VendorDriverBase::Init(manager)) {
252 PRINT_HILOGD("VendorDriverBase init fail");
253 return false;
254 }
255 if (!LoadDriverExtension()) {
256 PRINT_HILOGD("Init fail");
257 return false;
258 }
259 PRINT_HILOGD("Init quit");
260 return true;
261 }
UnInit()262 void VendorBsuniDriver::UnInit()
263 {
264 SetDriverWrapper(nullptr);
265 vendorExtension = nullptr;
266 if (bsUniDriverHandler != nullptr) {
267 dlclose(bsUniDriverHandler);
268 bsUniDriverHandler = nullptr;
269 }
270 VendorDriverBase::UnInit();
271 }
272
OnCreate()273 void VendorBsuniDriver::OnCreate()
274 {
275 PRINT_HILOGD("OnCreate enter");
276 VendorDriverBase::OnCreate();
277 if (vendorExtension == nullptr) {
278 PRINT_HILOGW("vendorExtension is null");
279 return;
280 }
281 if (vendorExtension->onCreate == nullptr) {
282 PRINT_HILOGW("onCreate is null");
283 return;
284 }
285 opQueue.Run();
286 SetDriverWrapper(this);
287 printServiceAbility.addPrinterToDiscovery = AddPrinterToDiscovery;
288 printServiceAbility.removePrinterFromDiscovery = RemovePrinterFromDiscovery;
289 printServiceAbility.addPrinterToCups = AddPrinterToCups;
290 printServiceAbility.removePrinterFromCups = RemovePrinterFromCups;
291 printServiceAbility.onCapabilityQueried = OnCapabilityQueried;
292 printServiceAbility.onPropertiesQueried = OnPropertiesQueried;
293 int32_t result = vendorExtension->onCreate(&printServiceAbility);
294 PRINT_HILOGI("OnCreate quit: %{public}d", result);
295 }
OnDestroy()296 void VendorBsuniDriver::OnDestroy()
297 {
298 PRINT_HILOGD("OnDestroy enter");
299 syncWait.Notify();
300 VendorDriverBase::OnDestroy();
301 if (vendorExtension == nullptr) {
302 PRINT_HILOGW("vendorExtension is null");
303 return;
304 }
305 if (vendorExtension->onDestroy == nullptr) {
306 PRINT_HILOGW("onDestroy is null");
307 return;
308 }
309 int32_t result = vendorExtension->onDestroy();
310 SetDriverWrapper(nullptr);
311 opQueue.Stop();
312 PRINT_HILOGI("OnDestroy quit: %{public}d", result);
313 }
314
OnStartDiscovery()315 void VendorBsuniDriver::OnStartDiscovery()
316 {
317 PRINT_HILOGD("OnStartDiscovery enter");
318 VendorDriverBase::OnStartDiscovery();
319 if (vendorExtension == nullptr) {
320 PRINT_HILOGW("vendorExtension is null");
321 return;
322 }
323 if (vendorExtension->onStartDiscovery == nullptr) {
324 PRINT_HILOGW("onStartDiscovery is null");
325 return;
326 }
327 int32_t result = vendorExtension->onStartDiscovery();
328 PRINT_HILOGI("OnStartDiscovery quit: %{public}d", result);
329 }
OnStopDiscovery()330 void VendorBsuniDriver::OnStopDiscovery()
331 {
332 PRINT_HILOGD("OnStopDiscovery enter");
333 VendorDriverBase::OnStopDiscovery();
334 if (vendorExtension == nullptr) {
335 PRINT_HILOGW("vendorExtension is null");
336 return;
337 }
338 if (vendorExtension->onStopDiscovery == nullptr) {
339 PRINT_HILOGW("onStopDiscovery is null");
340 return;
341 }
342 int32_t result = vendorExtension->onStopDiscovery();
343 PRINT_HILOGI("OnStopDiscovery quit: %{public}d", result);
344 }
345
GetVendorName()346 std::string VendorBsuniDriver::GetVendorName()
347 {
348 return VENDOR_BSUNI_DRIVER;
349 }
350
OnQueryCapability(const std::string & printerId,int timeout)351 bool VendorBsuniDriver::OnQueryCapability(const std::string &printerId, int timeout)
352 {
353 PRINT_HILOGD("OnQueryCapability enter");
354 if (vendorExtension == nullptr) {
355 PRINT_HILOGW("vendorExtension is null");
356 return false;
357 }
358 if (vendorExtension->onQueryCapability == nullptr) {
359 PRINT_HILOGW("onQueryCapability is null");
360 return false;
361 }
362 int32_t result = vendorExtension->onQueryCapability(printerId.c_str());
363 PRINT_HILOGI("OnQueryCapability result: %{public}d", result);
364 if (result == 0) {
365 syncWait.Wait(timeout);
366 PRINT_HILOGD("OnQueryCapability quit");
367 return true;
368 }
369 PRINT_HILOGD("OnQueryCapability quit");
370 return false;
371 }
372
OnQueryCapabilityByIp(const std::string & printerIp,const std::string & protocol)373 bool VendorBsuniDriver::OnQueryCapabilityByIp(const std::string &printerIp, const std::string &protocol)
374 {
375 PRINT_HILOGD("OnQueryCapabilityByIp enter");
376 if (vendorExtension == nullptr) {
377 PRINT_HILOGW("vendorExtension is null");
378 return false;
379 }
380 if (vendorExtension->onQueryCapabilityByIp == nullptr) {
381 PRINT_HILOGW("OnQueryCapabilityByIp is null");
382 return false;
383 }
384 int32_t result = vendorExtension->onQueryCapabilityByIp(printerIp.c_str(), protocol.c_str());
385 PRINT_HILOGI("OnQueryCapabilityByIp quit: %{public}d", result);
386 return result == 0;
387 }
388
OnQueryProperties(const std::string & printerId,const std::vector<std::string> & propertyKeys)389 bool VendorBsuniDriver::OnQueryProperties(const std::string &printerId, const std::vector<std::string> &propertyKeys)
390 {
391 PRINT_HILOGD("OnQueryProperties enter");
392 bool ret = false;
393 if (vendorExtension == nullptr) {
394 PRINT_HILOGW("vendorExtension is null");
395 return ret;
396 }
397 if (vendorExtension->onQueryProperties == nullptr) {
398 PRINT_HILOGW("onQueryProperties is null");
399 return ret;
400 }
401 Print_StringList propertyKeyList = { 0 };
402 if (ConvertStringVectorToStringList(propertyKeys, propertyKeyList)) {
403 int32_t result = vendorExtension->onQueryProperties(printerId.c_str(), &propertyKeyList);
404 PRINT_HILOGI("OnQueryProperties quit: %{public}d", result);
405 if (result == 0) {
406 ret = true;
407 }
408 }
409 ReleaseStringList(propertyKeyList);
410 PRINT_HILOGD("OnQueryProperties quit");
411 return ret;
412 }
413
OnDiscoveredPrinterAdd(std::shared_ptr<PrinterInfo> printerInfo)414 void VendorBsuniDriver::OnDiscoveredPrinterAdd(std::shared_ptr<PrinterInfo> printerInfo)
415 {
416 if (printerInfo == nullptr) {
417 PRINT_HILOGW("printerInfo is null");
418 return;
419 }
420 if (vendorManager == nullptr) {
421 PRINT_HILOGW("vendorManager is null");
422 return;
423 }
424 vendorManager->AddPrinterToDiscovery(GetVendorName(), *printerInfo);
425 }
426
OnDiscoveredPrinterRemove(std::shared_ptr<std::string> printerId)427 void VendorBsuniDriver::OnDiscoveredPrinterRemove(std::shared_ptr<std::string> printerId)
428 {
429 if (printerId == nullptr) {
430 PRINT_HILOGW("printerId is null");
431 return;
432 }
433 if (vendorManager == nullptr) {
434 PRINT_HILOGW("vendorManager is null");
435 return;
436 }
437 vendorManager->RemovePrinterFromDiscovery(GetVendorName(), *printerId);
438 }
439
OnCupsPrinterAdd(std::shared_ptr<PrinterInfo> printerInfo,std::shared_ptr<std::string> ppdData)440 void VendorBsuniDriver::OnCupsPrinterAdd(std::shared_ptr<PrinterInfo> printerInfo,
441 std::shared_ptr<std::string> ppdData)
442 {
443 if (printerInfo == nullptr) {
444 PRINT_HILOGW("printerInfo is null");
445 return;
446 }
447 if (vendorManager == nullptr) {
448 PRINT_HILOGW("vendorManager is null");
449 return;
450 }
451 std::string vendorName = GetVendorName();
452 if (vendorManager->UpdatePrinterToDiscovery(vendorName, *printerInfo) != EXTENSION_ERROR_NONE) {
453 PRINT_HILOGW("update printer to discovery fail");
454 return;
455 }
456 if (ppdData == nullptr || ppdData->empty()) {
457 PRINT_HILOGW("ppdData is null");
458 return;
459 }
460 vendorManager->AddPrinterToCupsWithPpd(vendorName, printerInfo->GetPrinterId(), BSUNI_PPD_NAME, *ppdData);
461 }
462
OnCupsPrinterRemove(std::shared_ptr<std::string> printerId)463 void VendorBsuniDriver::OnCupsPrinterRemove(std::shared_ptr<std::string> printerId)
464 {
465 if (printerId == nullptr) {
466 PRINT_HILOGW("printerId is null");
467 return;
468 }
469 if (vendorManager == nullptr) {
470 PRINT_HILOGW("vendorManager is null");
471 return;
472 }
473 vendorManager->RemovePrinterFromCups(GetVendorName(), *printerId);
474 }
475
OnPpdQueried(std::shared_ptr<std::string> printerId,std::shared_ptr<std::string> ppdData)476 void VendorBsuniDriver::OnPpdQueried(std::shared_ptr<std::string> printerId, std::shared_ptr<std::string> ppdData)
477 {
478 if (printerId == nullptr || ppdData == nullptr || ppdData->empty()) {
479 PRINT_HILOGW("invalid parameters");
480 return;
481 }
482 if (vendorManager == nullptr) {
483 PRINT_HILOGW("vendorManager is null");
484 return;
485 }
486 PRINT_HILOGI("ppdData queried");
487 if (vendorManager->OnPrinterPpdQueried(GetVendorName(), *printerId, BSUNI_PPD_NAME, *ppdData)) {
488 if (vendorExtension != nullptr && vendorExtension->onConnectPrinter != nullptr) {
489 vendorExtension->onConnectPrinter(printerId->c_str());
490 }
491 }
492 }
493
OnStateQueried(std::shared_ptr<std::string> printerId,std::shared_ptr<std::string> stateData)494 void VendorBsuniDriver::OnStateQueried(std::shared_ptr<std::string> printerId, std::shared_ptr<std::string> stateData)
495 {
496 if (printerId == nullptr || stateData == nullptr || stateData->empty()) {
497 PRINT_HILOGW("invalid parameters");
498 return;
499 }
500 if (vendorManager == nullptr) {
501 PRINT_HILOGW("vendorManager is null");
502 return;
503 }
504 PRINT_HILOGI("stateData queried");
505 Print_PrinterState state = PRINTER_UNAVAILABLE;
506 if (ConvertStringToPrinterState(*stateData, state)) {
507 OnPrinterStateQueried(*printerId, state);
508 }
509 }
510
OnPrinterCapabilityQueried(std::shared_ptr<PrinterInfo> printerInfo)511 void VendorBsuniDriver::OnPrinterCapabilityQueried(std::shared_ptr<PrinterInfo> printerInfo)
512 {
513 PRINT_HILOGD("OnPrinterCapabilityQueried enter");
514 if (printerInfo == nullptr) {
515 PRINT_HILOGW("printerInfo is null");
516 return;
517 }
518 if (vendorManager == nullptr) {
519 PRINT_HILOGW("vendorManager is null");
520 return;
521 }
522 vendorManager->UpdatePrinterToDiscovery(GetVendorName(), *printerInfo);
523 vendorManager->OnPrinterCapabilityQueried(GetVendorName(), *printerInfo);
524 syncWait.Notify();
525 PRINT_HILOGD("OnPrinterCapabilityQueried quit");
526 }
527