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