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