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_wlan_group.h"
17 #include "print_log.h"
18 #include "print_utils.h"
19 #include "file_ex.h"
20
21 using namespace OHOS::Print;
22 namespace {
23 const std::string VENDOR_BSUNI_URI_START = "://";
24 const std::string VENDOR_BSUNI_URI_END = ":";
25 const std::string VENDOR_CONVERTED_PRINTERID = "uuid";
26 const std::string VENDOR_BSUNI_GS_PATH = "/system/bin/uni_print_driver/ghostscript/bin/gs";
27 }
28
VendorWlanGroup(VendorManager * vendorManager)29 VendorWlanGroup::VendorWlanGroup(VendorManager *vendorManager) : parentVendorManager(vendorManager)
30 {
31 hasGs = FileExists(VENDOR_BSUNI_GS_PATH);
32 }
33
GetVendorName()34 std::string VendorWlanGroup::GetVendorName()
35 {
36 return VENDOR_WLAN_GROUP;
37 }
38
OnQueryCapability(const std::string & printerId,int timeout)39 bool VendorWlanGroup::OnQueryCapability(const std::string &printerId, int timeout)
40 {
41 PRINT_HILOGI("OnQueryCapability enter.");
42 if (parentVendorManager == nullptr) {
43 PRINT_HILOGE("VendorManager is null.");
44 return false;
45 }
46 auto ppdDriver = parentVendorManager->FindDriverByVendorName(VENDOR_PPD_DRIVER);
47 if (ppdDriver != nullptr) {
48 printerVendorGroupList_[printerId] = VENDOR_PPD_DRIVER;
49 auto printerInfo = parentVendorManager->QueryDiscoveredPrinterInfoById(GetVendorName(), printerId);
50 if (printerInfo != nullptr && ppdDriver->OnQueryProperties(printerId, std::vector<std::string>(1,
51 printerInfo->GetPrinterMake()))) {
52 if (ppdDriver->OnQueryCapability(printerId, timeout)) {
53 PRINT_HILOGI("on query capability on ppd vendor seccess.");
54 return true;
55 }
56 }
57 RemovePrinterVendorGroupById(printerId);
58 }
59 if (IsBsunidriverSupport(printerId)) {
60 printerVendorGroupList_[printerId] = VENDOR_BSUNI_DRIVER;
61 auto bsuniDriver = parentVendorManager->FindDriverByVendorName(VENDOR_BSUNI_DRIVER);
62 auto printerInfo = parentVendorManager->QueryDiscoveredPrinterInfoById(GetVendorName(), printerId);
63 if (bsuniDriver != nullptr && printerInfo != nullptr &&
64 bsuniDriver->OnQueryCapability(ExtractBsUniPrinterIdByPrinterInfo(*printerInfo), timeout)) {
65 PRINT_HILOGI("on query capability on bsuni vendor seccess.");
66 return true;
67 }
68 RemovePrinterVendorGroupById(printerId);
69 } else {
70 printerVendorGroupList_[printerId] = VENDOR_IPP_EVERYWHERE;
71 auto ippEverywhereDriver = parentVendorManager->FindDriverByVendorName(VENDOR_IPP_EVERYWHERE);
72 if (ippEverywhereDriver != nullptr && ippEverywhereDriver->OnQueryCapabilityByIp(printerId, "auto")) {
73 PRINT_HILOGI("on query capability on ipp everywhere seccess.");
74 return true;
75 }
76 RemovePrinterVendorGroupById(printerId);
77 }
78 PRINT_HILOGE("no vendor can query capability.");
79 return false;
80 }
81
OnQueryCapabilityByIp(const std::string & printerIp,const std::string & protocol)82 bool VendorWlanGroup::OnQueryCapabilityByIp(const std::string &printerIp, const std::string &protocol)
83 {
84 PRINT_HILOGI("OnQueryCapabilityByIp enter.");
85 if (parentVendorManager == nullptr) {
86 PRINT_HILOGE("VendorManager is null.");
87 return false;
88 }
89 auto bsuniDriver = parentVendorManager->FindDriverByVendorName(VENDOR_BSUNI_DRIVER);
90 printerVendorGroupList_[printerIp] = VENDOR_BSUNI_DRIVER;
91 if (bsuniDriver != nullptr && bsuniDriver->OnQueryCapabilityByIp(printerIp, protocol)) {
92 PRINT_HILOGI("on query capability by ip on bsuni vendor seccess.");
93 return true;
94 }
95 RemovePrinterVendorGroupById(printerIp);
96 printerVendorGroupList_[printerIp] = VENDOR_IPP_EVERYWHERE;
97 auto ippEverywhereDriver = parentVendorManager->FindDriverByVendorName(VENDOR_IPP_EVERYWHERE);
98 if (ippEverywhereDriver != nullptr && ippEverywhereDriver->OnQueryCapabilityByIp(printerIp, protocol)) {
99 PRINT_HILOGI("on query capability by ip on ipp everywhere seccess.");
100 return true;
101 }
102 RemovePrinterVendorGroupById(printerIp);
103 PRINT_HILOGE("no vendor can query capability by ip.");
104 return false;
105 }
106
OnPrinterDiscovered(const std::string & vendorName,const PrinterInfo & printerInfo)107 int32_t VendorWlanGroup::OnPrinterDiscovered(const std::string &vendorName, const PrinterInfo &printerInfo)
108 {
109 if (vendorManager == nullptr) {
110 PRINT_HILOGE("VendorManager is null.");
111 return EXTENSION_ERROR_CALLBACK_NULL;
112 }
113 return vendorManager->AddPrinterToDiscovery(GetVendorName(), ConvertPrinterInfoId(printerInfo));
114 }
115
OnUpdatePrinterToDiscovery(const std::string & vendorName,const PrinterInfo & printerInfo)116 int32_t VendorWlanGroup::OnUpdatePrinterToDiscovery(const std::string &vendorName, const PrinterInfo &printerInfo)
117 {
118 if (vendorManager == nullptr) {
119 PRINT_HILOGE("VendorManager is null.");
120 return EXTENSION_ERROR_CALLBACK_NULL;
121 }
122 return vendorManager->UpdatePrinterToDiscovery(GetVendorName(), ConvertPrinterInfoId(printerInfo));
123 }
124
OnPrinterRemoved(const std::string & vendorName,const std::string & printerId)125 int32_t VendorWlanGroup::OnPrinterRemoved(const std::string &vendorName, const std::string &printerId)
126 {
127 if (vendorManager == nullptr) {
128 PRINT_HILOGE("VendorManager is null.");
129 return EXTENSION_ERROR_CALLBACK_NULL;
130 }
131 RemovePrinterVendorGroupById(printerId);
132 std::string id(VendorManager::ExtractPrinterId(printerId));
133 QueryBsUniPrinterIdByUuidPrinterId(id);
134 return vendorManager->RemovePrinterFromDiscovery(GetVendorName(), id);
135 }
136
IsConnectingPrinter(const std::string & globalPrinterIdOrIp,const std::string & uri)137 bool VendorWlanGroup::IsConnectingPrinter(const std::string &globalPrinterIdOrIp, const std::string &uri)
138 {
139 if (vendorManager == nullptr) {
140 PRINT_HILOGE("VendorManager is null.");
141 return false;
142 }
143 std::string printerId(VendorManager::ExtractPrinterId(globalPrinterIdOrIp));
144 QueryBsUniPrinterIdByUuidPrinterId(printerId);
145 printerId = GetGlobalPrinterId(printerId);
146 return vendorManager->IsConnectingPrinter(printerId, uri);
147 }
148
SetConnectingPrinter(ConnectMethod method,const std::string & globalPrinterIdOrIp)149 void VendorWlanGroup::SetConnectingPrinter(ConnectMethod method, const std::string &globalPrinterIdOrIp)
150 {
151 if (vendorManager == nullptr) {
152 PRINT_HILOGE("VendorManager is null.");
153 return;
154 }
155 std::string printerId(VendorManager::ExtractPrinterId(globalPrinterIdOrIp));
156 QueryBsUniPrinterIdByUuidPrinterId(printerId);
157 printerId = GetGlobalPrinterId(printerId);
158 vendorManager->SetConnectingPrinter(method, printerId);
159 }
160
OnPrinterPpdQueried(const std::string & vendorName,const std::string & printerId,const std::string & ppdData)161 bool VendorWlanGroup::OnPrinterPpdQueried(const std::string &vendorName, const std::string &printerId,
162 const std::string &ppdData)
163 {
164 if (vendorManager == nullptr) {
165 PRINT_HILOGE("VendorManager is null.");
166 return false;
167 }
168 std::string id(printerId);
169 QueryBsUniPrinterIdByUuidPrinterId(id);
170 return vendorManager->OnPrinterPpdQueried(GetVendorName(), id, ppdData);
171 }
172
173
IsGroupDriver(const std::string & bothPrinterId)174 bool VendorWlanGroup::IsGroupDriver(const std::string &bothPrinterId)
175 {
176 if (bothPrinterId.find(VENDOR_CONVERTED_PRINTERID) != std::string::npos) {
177 PRINT_HILOGD("printerId has be converted whit uuid, is group driver!.");
178 return true;
179 }
180 std::string printerId(VendorManager::ExtractPrinterId(bothPrinterId));
181 auto iter = printerVendorGroupList_.find(printerId);
182 return (iter != printerVendorGroupList_.end() && !iter->second.empty());
183 }
184
ConvertGroupDriver(std::string & printerId,std::string & vendorName)185 bool VendorWlanGroup::ConvertGroupDriver(std::string &printerId, std::string &vendorName)
186 {
187 printerId = VendorManager::ExtractPrinterId(printerId);
188 if (vendorName == VENDOR_BSUNI_DRIVER) {
189 QueryBsUniPrinterIdByUuidPrinterId(printerId);
190 return false;
191 }
192 auto iter = printerVendorGroupList_.find(printerId);
193 if (iter != printerVendorGroupList_.end() && !iter->second.empty()) {
194 vendorName = VENDOR_WLAN_GROUP;
195 return true;
196 }
197 return false;
198 }
199
IsBsunidriverSupport(const std::string & printerId)200 bool VendorWlanGroup::IsBsunidriverSupport(const std::string &printerId)
201 {
202 PRINT_HILOGD("IsBsunidriverSupport enter");
203 auto printerInfo = parentVendorManager->QueryDiscoveredPrinterInfoById(GetVendorName(), printerId);
204 if (printerInfo == nullptr) {
205 return false;
206 }
207 std::string supportValue;
208 if (printerInfo->HasOption() && nlohmann::json::accept(printerInfo->GetOption())) {
209 nlohmann::json option = nlohmann::json::parse(printerInfo->GetOption());
210 if (option.contains("bsunidriverSupport") && option["bsunidriverSupport"].is_string()) {
211 supportValue = option["bsunidriverSupport"].get<std::string>();
212 }
213 }
214 PRINT_HILOGD("IsBsunidriverSupport bsunidriverSupport=%{public}s", supportValue.c_str());
215 if (supportValue == "true") {
216 return true;
217 } else if (supportValue == "need_gs") {
218 return hasGs;
219 } else {
220 return false;
221 }
222 }
223
RemovePrinterVendorGroupById(const std::string & printerId)224 void VendorWlanGroup::RemovePrinterVendorGroupById(const std::string &printerId)
225 {
226 auto iter = printerVendorGroupList_.find(printerId);
227 if (iter != printerVendorGroupList_.end()) {
228 PRINT_HILOGD("remove printer from vendor group list");
229 printerVendorGroupList_.erase(printerId);
230 }
231 }
232
ConvertGroupGlobalPrinterId(const std::string & bothPrinterId)233 std::string VendorWlanGroup::ConvertGroupGlobalPrinterId(const std::string &bothPrinterId)
234 {
235 std::string printerId(VendorManager::ExtractPrinterId(bothPrinterId));
236 return PrintUtils::GetGlobalId(VendorManager::GetGlobalVendorName(GetVendorName()), printerId);
237 }
238
QueryBsUniPrinterIdByUuidPrinterId(std::string & bsUniPrinterId)239 void VendorWlanGroup::QueryBsUniPrinterIdByUuidPrinterId(std::string &bsUniPrinterId)
240 {
241 std::lock_guard<std::mutex> lock(uuidMapMutex);
242 auto item = printerIdToUuidMap_.find(bsUniPrinterId);
243 if (item != printerIdToUuidMap_.end() && !item->second.empty()) {
244 bsUniPrinterId = std::string(item->second);
245 }
246 }
247
UpdateMappedPrinterId(const std::string & bsUniPrinterId,const std::string printerId)248 void VendorWlanGroup::UpdateMappedPrinterId(const std::string &bsUniPrinterId, const std::string printerId)
249 {
250 std::lock_guard<std::mutex> lock(uuidMapMutex);
251 printerIdToUuidMap_[bsUniPrinterId] = printerId;
252 }
253
ConvertPrinterInfoId(const PrinterInfo & printerInfo)254 PrinterInfo VendorWlanGroup::ConvertPrinterInfoId(const PrinterInfo &printerInfo)
255 {
256 PrinterInfo info(printerInfo);
257 if (printerInfo.HasOption() && nlohmann::json::accept(std::string(printerInfo.GetOption()))) {
258 nlohmann::json option = nlohmann::json::parse(std::string(printerInfo.GetOption()));
259 if (option != nullptr && option.contains("printer-uuid") && option["printer-uuid"].is_string()) {
260 info.SetPrinterId(std::string(option["printer-uuid"]));
261 UpdateMappedPrinterId(printerInfo.GetPrinterId(), std::string(option["printer-uuid"]));
262 PRINT_HILOGD("Convert PrinterId with uuid");
263 return info;
264 }
265 }
266 return printerInfo;
267 }
268
ExtractBsUniPrinterIdByPrinterInfo(const PrinterInfo & printerInfo)269 std::string VendorWlanGroup::ExtractBsUniPrinterIdByPrinterInfo(const PrinterInfo &printerInfo)
270 {
271 std::string uri(printerInfo.GetUri());
272 if (uri.empty()) {
273 return "";
274 }
275 auto pos_start = uri.find_first_of(VENDOR_BSUNI_URI_START);
276 auto pos_end = uri.find_last_of(VENDOR_BSUNI_URI_END);
277 if (pos_start == std::string::npos || uri.length() <= pos_start + 1 ||
278 pos_start == std::string::npos || uri.length() <= pos_start + 1) {
279 return "";
280 }
281 return uri.substr(pos_start + VENDOR_BSUNI_URI_START.length(),
282 pos_end - pos_start - VENDOR_BSUNI_URI_START.length());
283 }
284