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