1/* 2 * Copyright (c) 2023-2023 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 16import print from '@ohos.print'; 17import commonEvent from '@ohos.commonEventManager'; 18import { 19 AppCommonEvent, 20 AppStorageKeyName, 21 convertToPrinterInfo, 22 PrintErrorCode 23} from '@ohos/common'; 24import AppStorageHelper from '../Common/Adapter/AppStorageHelper'; 25import WifiP2pHelper from '../Common/Adapter/WifiP2pHelper'; 26import { Log } from '@ohos/common'; 27import { PrinterDiscModel } from '../Model/PrinterDiscModel'; 28import emitter from '@ohos.events.emitter'; 29import { StringUtil } from '@ohos/common'; 30import { PrinterCapability, PrinterInfo } from '@ohos/common'; 31 32const TAG = '[PrinterDiscController]:'; 33 34/** 35 * PrinterDiscController 36 */ 37export class PrinterDiscController { 38 private mPrinterDiscModel: PrinterDiscModel = new PrinterDiscModel(); 39 private eventSubscriber = null; 40 41 /** 42 * create print Job 43 * 44 * @param jobId printJob id 45 * @return job state 46 */ 47 public init(): void { 48 Log.info(TAG, 'PrinterDiscController init'); 49 AppStorageHelper.createValue<Array<PrinterInfo>>(this.getModel().mPrinters, AppStorageKeyName.PRINTER_QUEUE_NAME); 50 this.registerPrinterCallback(); 51 this.subscribeCommonEvent(); 52 } 53 54 /** 55 * on destroy 56 */ 57 public destroy(): void { 58 Log.info(TAG, 'PrinterDiscController destroy'); 59 this.unregisterPrinterCallback(); 60 } 61 62 /** 63 * start discovery 64 * 65 * @param jobId job id 66 * @param extensionList extension list 67 */ 68 public startDiscovery(jobId: string, extensionList: Array<string>): void { 69 Log.info(TAG, 'startDiscovery, jobId = ' + JSON.stringify(jobId) + ', extensionList ' + JSON.stringify(extensionList)); 70 this.mPrinterDiscModel.reset(); 71 print.queryAllPrinterExtensionInfos().then((extensionInfos: object[]) => { 72 Log.info(TAG, 'queryExtensionAbilityInfos success : ' + JSON.stringify(extensionInfos)); 73 print.startDiscoverPrinter(extensionList).then((data) => { 74 Log.info(TAG, 'start Discovery success data : ' + JSON.stringify(data)); 75 }).catch((err) => { 76 Log.error(TAG, 'failed to start Discovery because : ' + JSON.stringify(err)); 77 }); 78 }).catch((error) => { 79 Log.error(TAG, 'start discovery fail because :' + JSON.stringify(error)); 80 }); 81 } 82 83 /** 84 * register printer callback 85 */ 86 private registerPrinterCallback(): void { 87 Log.info(TAG, 'registerPrinterCallback'); 88 print.on('printerStateChange', this.onPrinterStateChanged); 89 } 90 91 /** 92 * printer state change callback 93 * 94 * @param state printer state 95 * @param info printer info 96 */ 97 private onPrinterStateChanged = (state: print.PrinterState, printerInfo: print.PrinterInfo): void => { 98 if (state === null || printerInfo === null) { 99 Log.error(TAG, 'printer state changed state is null or info is null'); 100 return; 101 } 102 103 let info: PrinterInfo = convertToPrinterInfo(printerInfo); 104 Log.info(TAG, 'on printer state changed, state = ' + JSON.stringify(state) + ' ,info =' + info?.toString()); 105 switch (state) { 106 case print.PrinterState.PRINTER_ADDED: 107 this.onPrinterFound(info); 108 break; 109 case print.PrinterState.PRINTER_REMOVED: 110 this.onPrinterOffline(info); 111 break; 112 case print.PrinterState.PRINTER_CAPABILITY_UPDATED: 113 this.onPrinterUpdateCapability(info); 114 break; 115 case print.PrinterState.PRINTER_CONNECTED: 116 case print.PrinterState.PRINTER_DISCONNECTED: 117 case print.PrinterState.PRINTER_RUNNING: 118 this.onPrinterStateChange(info); 119 break; 120 default: 121 break; 122 } 123 }; 124 125 /** 126 * deal printer offline 127 * 128 * @param info printer info 129 */ 130 private onPrinterOffline(info: print.PrinterInfo): void { 131 if (info === null) { 132 Log.error(TAG, 'onPrinterOffline for null info'); 133 return; 134 } 135 Log.info(TAG, 'on printer offline, printer = ' + StringUtil.splitMac(<string> info.printerId)); 136 this.mPrinterDiscModel.removePrinter(<string> info.printerId); 137 } 138 139 /** 140 * deal printer find 141 * 142 * @param info printer info 143 */ 144 private onPrinterFound(info: PrinterInfo): void { 145 Log.info(TAG, 'enter onPrinterFound'); 146 if (info === null) { 147 Log.error(TAG, 'onPrinterFound for null data'); 148 return; 149 } 150 this.mPrinterDiscModel.addPrinter(info); 151 Log.info(TAG, 'foundPrinter = ' + StringUtil.encodeCommonString(info.printerName)); 152 } 153 154 /** 155 * find printer 156 * 157 * @param printerId printerId 158 */ 159 public findPrinter(printerId: string): boolean { 160 Log.debug(TAG, 'findPrinter = ' + StringUtil.splitMac(printerId)); 161 let res: boolean = this.mPrinterDiscModel.findPrinter(printerId); 162 return res; 163 } 164 165 /** 166 * deal printer state change 167 * 168 * @param info printer info 169 */ 170 private onPrinterStateChange(info: PrinterInfo): void { 171 if (info === null) { 172 Log.error(TAG, 'onPrinterStateChange for null data'); 173 return; 174 } 175 Log.error(TAG, 'onPrinterStateChange, info = ' + info?.toString()); 176 this.mPrinterDiscModel.printerStateChange(<string> info.printerId, <number> info.printerState); 177 } 178 179 /** 180 * deal printer capability update 181 * 182 * @param info printer info 183 */ 184 private onPrinterUpdateCapability(info: PrinterInfo): void { 185 if (info === null) { 186 Log.error(TAG, 'onPrinterUpdateCapability for null data'); 187 return; 188 } 189 Log.info(TAG, 'onPrinterUpdateCapability, info = ' + info?.toString()); 190 this.mPrinterDiscModel.printerUpdateCapability(info.printerId, info.capability, info.options, info.description); 191 } 192 193 /** 194 * stop discovery 195 * 196 * @param jobId job id 197 */ 198 public stopDiscovery(jobId: string): void { 199 Log.info(TAG, 'stopDiscovery'); 200 print.stopDiscoverPrinter().then((data) => { 201 Log.info(TAG, 'stop Discovery success data : ' + JSON.stringify(data)); 202 }).catch((err) => { 203 Log.error(TAG, 'failed to stop Discovery because ' + JSON.stringify(err)); 204 }); 205 } 206 207 /** 208 * register printer callback 209 */ 210 private unregisterPrinterCallback(): void { 211 Log.info(TAG, 'unregisterPrinterCallback'); 212 print.off('printerStateChange', (data) => { 213 console.info('off printerStateChange data : ' + JSON.stringify(data)); 214 }); 215 } 216 217 /** 218 * connect Printer 219 * 220 * @param printerId printer id 221 */ 222 public connectPrinter(printer: PrinterInfo): void { 223 let printerId: string = printer.printerId; 224 Log.debug(TAG, 'connectPrinter printerId = ' + StringUtil.splitMac(printerId)); 225 print.connectPrinter(printerId).then((data) => { 226 Log.debug(TAG, 'start connect Printer success data : ' + JSON.stringify(data)); 227 }).catch((err) => { 228 Log.error(TAG, 'failed to connect Printer because ' + JSON.stringify(err)); 229 if (err === PrintErrorCode.E_PRINT_INVALID_PRINTER) { 230 let innerEvent = { 231 eventId: AppCommonEvent.PRINTER_INVALID_EVENT, 232 priority: emitter.EventPriority.HIGH 233 }; 234 let eventData = { 235 data: { 236 'printerId': printerId 237 } 238 }; 239 emitter.emit(innerEvent, eventData); 240 Log.error(TAG, 'delete invalid printer printerId = ' + JSON.stringify(printerId)); 241 this.mPrinterDiscModel.removePrinter(printerId); 242 this.startDiscovery('', []); 243 } 244 }); 245 } 246 247 /** 248 * disconnect Printer 249 * 250 * @param printerId printer id 251 */ 252 public async disconnectPrinter(printerId: string): Promise<void> { 253 Log.info(TAG, 'disconnectPrinter'); 254 await print.disconnectPrinter(printerId).then((data) => { 255 Log.info(TAG, 'start disconnect Printer success data : ' + JSON.stringify(data)); 256 }).catch((err) => { 257 Log.error(TAG, 'failed to disconnect Printer because ' + JSON.stringify(err)); 258 }); 259 } 260 261 /** 262 * query Printer Capability 263 * 264 * @param printerId printer id 265 * @return printer capability 266 */ 267 public async queryPrinterCapability(printerId: string): Promise<void> { 268 Log.info(TAG, 'queryPrinterCapability'); 269 print.queryPrinterCapability(printerId); 270 } 271 272 /** 273 * get model 274 * 275 * @return PrinterDiscModel 276 */ 277 public getModel(): PrinterDiscModel { 278 return this.mPrinterDiscModel; 279 } 280 281 /** 282 * subscribe CommonEvent 283 */ 284 public subscribeCommonEvent(): void { 285 Log.info(TAG, 'subscribeCommonEvent'); 286 let subscribeInfo = { 287 events: [commonEvent.Support.COMMON_EVENT_WIFI_POWER_STATE], 288 }; 289 commonEvent.createSubscriber(subscribeInfo).then((subscriber) => { 290 Log.info(TAG, 'start createSubscriber subscriber : ' + JSON.stringify(subscriber)); 291 this.eventSubscriber = subscriber; 292 commonEvent.subscribe(this.eventSubscriber, (err, commonEventData) => { 293 Log.error(TAG, 'subscribe callback : ' + JSON.stringify(commonEventData)); 294 if (commonEventData.event === commonEvent.Support.COMMON_EVENT_WIFI_POWER_STATE) { 295 if (!WifiP2pHelper.checkWifiActive()) { 296 Log.error(TAG, 'wifi inactive '); 297 this.mPrinterDiscModel.reset(); 298 let innerEvent = { 299 eventId: AppCommonEvent.WLAN_INACTIVE_EVENT, 300 priority: emitter.EventPriority.HIGH 301 }; 302 emitter.emit(innerEvent); 303 } else { 304 let innerEvent = { 305 eventId: AppCommonEvent.WLAN_ACTIVE_EVENT, 306 priority: emitter.EventPriority.HIGH 307 }; 308 emitter.emit(innerEvent); 309 } 310 } 311 }); 312 }).catch((err) => { 313 Log.error(TAG, 'failed createSubscriber because ' + JSON.stringify(err)); 314 }); 315 } 316}