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 wifi from '@ohos.wifi'; 17import { WIFI_POWER_CLOSED, P2P_DISCOVERY_DELAY } from '@ohos/common'; 18import type { Listener } from './discovery/Discovery'; 19import type DiscoveredPrinter from './discovery/DiscoveredPrinter'; 20import P2pUtils from './utils/P2pUtils'; 21import { Log } from '@ohos/common'; 22import type { PrintServiceAdapter } from './PrintServiceAdapter'; 23import LocalPrinter from './LocalPrinter'; 24import { print } from '@kit.BasicServicesKit'; 25import type { WifiListener } from './model/WifiModel'; 26import CommonEventManager from '@ohos.commonEventManager'; 27import HashSet from '@ohos.util.HashSet'; 28import taskpool from '@ohos.taskpool'; 29import type { PrinterInfo } from '@ohos/common'; 30 31const TAG = 'LocalDiscoverySession'; 32 33export class LocalDiscoverySession implements Listener, WifiListener { 34 35 // Printers are removed after not being seen for this long 36 private readonly mPrintServiceAdapter: PrintServiceAdapter; 37 private readonly mPrinters: Map<string, LocalPrinter> = new Map(); 38 private readonly connectingIds: HashSet<string> = new HashSet<string>(); 39 40 constructor(printServiceAdapter: PrintServiceAdapter) { 41 this.mPrintServiceAdapter = printServiceAdapter; 42 this.mPrintServiceAdapter.wifiModel.addListener(this); 43 } 44 45 /** 46 * 开始扫描打印机 47 */ 48 public startPrinterDiscovery(): void { 49 Log.info(TAG, 'startPrinterDiscovery() '); 50 this.mPrintServiceAdapter.mdnsDiscovery.addListener(this); 51 setTimeout(() => { 52 this.mPrintServiceAdapter.p2pDiscovery.addListener(this); 53 }, P2P_DISCOVERY_DELAY); 54 } 55 56 /** 57 * 停止扫描打印机 58 */ 59 public stopPrinterDiscovery(): void { 60 Log.info(TAG, 'stopPrinterDiscovery() '); 61 this.mPrintServiceAdapter.p2pDiscovery.removeListener(this); 62 this.mPrintServiceAdapter.mdnsDiscovery.removeListener(this); 63 if (!this.connectingIds.isEmpty()) { 64 Log.info(TAG, 'p2p printer is connecting, close'); 65 for (let id of this.connectingIds) { 66 let localPrinter: LocalPrinter = this.mPrinters.get(<string>id); 67 if (localPrinter !== undefined && P2pUtils.isP2p(localPrinter.getDiscoveryPrinter())) { 68 localPrinter.stopTracking(); 69 } 70 } 71 this.connectingIds.clear(); 72 } 73 } 74 75 /** 76 * 开始连接打印机 77 * @param path 78 */ 79 public startConnectPrinter(path: string): void { 80 Log.info(TAG, 'start Connect Printer enter...'); 81 82 if (!this.mPrinters.has(path)) { 83 Log.error(TAG, 'printer is not exist'); 84 return; 85 } 86 let localPrinter: LocalPrinter = this.mPrinters.get(path); 87 localPrinter.startTracking(); 88 } 89 90 /** 91 * 将正常连接中的p2p打印机存放到ids中 92 * @param printerId 93 */ 94 public addConnectingId(printerId: string): void { 95 this.connectingIds.add(printerId); 96 } 97 98 /** 99 * 删除连接成功或者连接失败的printerId 100 * @param printerId 101 */ 102 public removeConnectedId(printerId: string): void { 103 if (!this.connectingIds.has(printerId)) { 104 Log.error(TAG, 'removeConnectedId failed, printerId is not exist'); 105 return; 106 } 107 this.connectingIds.remove(printerId); 108 } 109 110 public stopConnectPrinter(printerId: string): void { 111 Log.info(TAG, 'stop Connect Printer enter...'); 112 113 if (!this.mPrinters.has(printerId)) { 114 Log.error(TAG, 'printer is not exist'); 115 return; 116 } 117 let localPrinter: LocalPrinter = this.mPrinters.get(printerId); 118 localPrinter.stopTracking(); 119 } 120 121 public getCapabilities(printerId: string): void { 122 Log.info(TAG, 'get capabilities enter...'); 123 124 if (!this.mPrinters.has(printerId)) { 125 Log.error(TAG, 'printerId is not exist'); 126 return; 127 } 128 129 let localPrinter: LocalPrinter = this.mPrinters.get(printerId); 130 localPrinter.getCapabilities(); 131 } 132 133 /** 134 * getDiscoveryPrinterInfo 135 * 136 * @param printerId printer Id 137 */ 138 public getDiscoveryPrinterInfo(printerId: string): DiscoveredPrinter { 139 Log.debug(TAG, 'getDiscoveryPrinterInfo enter'); 140 let printerKey: string = undefined; 141 let printer = undefined; 142 for (let key of this.mPrinters.keys()) { 143 if (printerId.indexOf(<string>key) > 0) { 144 printerKey = key; 145 } 146 } 147 if (printerKey === undefined) { 148 Log.info(TAG, 'printerId is not exist'); 149 return undefined; 150 } 151 printer = this.mPrinters.get(printerKey); 152 if (printer !== undefined) { 153 // @ts-ignore 154 return <object> printer.getDiscoveryPrinter(); 155 } 156 return undefined; 157 } 158 159 public updateLocalPrinter(printer: DiscoveredPrinter): void { 160 Log.debug(TAG, 'updateLocalPrinter enter'); 161 let localPrinter = this.mPrinters.get(printer.getPath()); 162 localPrinter.setDiscoveryPrinter(printer); 163 this.mPrinters.set(printer.getPath(), localPrinter); 164 } 165 166 public close(): void { 167 this.mPrinters.clear(); 168 this.mPrintServiceAdapter.p2pDiscovery.clearPrinterMap(false); 169 this.mPrintServiceAdapter.mdnsDiscovery.clearPrinterMap(false); 170 this.mPrintServiceAdapter.wifiModel.removeListener(this); 171 } 172 173 /** 174 * 打印机发现的回调 175 * @param discoveredPrinter 176 */ 177 onPrinterFound(printer: DiscoveredPrinter): void { 178 Log.info(TAG, 'onPrinterFound() enter, cache printer length: ' + this.mPrinters.size); 179 if (P2pUtils.isUnavailable(printer)) { 180 return; 181 } 182 let localPrinter: LocalPrinter = undefined; 183 localPrinter = new LocalPrinter(this.mPrintServiceAdapter, this, printer); 184 this.mPrinters.set(<string>printer.getPath(), localPrinter); 185 186 // 构建printerInfo 187 const printerInfo = localPrinter.createPrinterInfo(); 188 let task = new taskpool.Task(addPrinters, [printerInfo]); 189 taskpool.execute(task); 190 }; 191 192 193 /** 194 * A previously-found printer is no longer discovered. 195 * 196 * @param printer DiscoveredPrinter 197 */ 198 onPrinterLost(printer: DiscoveredPrinter): void { 199 // this.mPrinters.delete(<string>printer.getPath()); 200 // 打印机丢失 201 let task = new taskpool.Task(removePrinters, [printer.getId()]); 202 taskpool.execute(task); 203 }; 204 205 onConnectionStateChanged(data): void { 206 if (data.event === CommonEventManager.Support.COMMON_EVENT_WIFI_POWER_STATE && data.code === WIFI_POWER_CLOSED) { 207 // 上报wifi关闭事件 208 Log.error(TAG, 'wifi state is closed'); 209 this.mPrintServiceAdapter.p2pDiscovery.clearPrinterMap(true); 210 this.mPrintServiceAdapter.mdnsDiscovery.clearPrinterMap(true); 211 this.mPrintServiceAdapter.p2pDiscovery.removeListener(this); 212 this.mPrintServiceAdapter.mdnsDiscovery.removeListener(this); 213 } else if (data.event === CommonEventManager.Support.COMMON_EVENT_WIFI_CONN_STATE && data.code === wifi.ConnState.DISCONNECTING) { 214 Log.info(TAG, 'wifi state Disconnecting event: ' + JSON.stringify(data)); 215 this.mPrintServiceAdapter.mdnsDiscovery.clearPrinterMap(true); 216 } 217 } 218} 219 220function addPrinters(printerInfos :PrinterInfo[]): void { 221 'use concurrent'; 222 print.addPrinters(printerInfos); 223} 224 225function removePrinters(printerIds :string[]): void { 226 'use concurrent'; 227 print.removePrinters(printerIds); 228}