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