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 type DiscoveredPrinter from './DiscoveredPrinter'; 17import ArrayList from '@ohos.util.ArrayList'; 18import { Log } from '@ohos/common'; 19import CommonUtils from '../utils/CommonUtils'; 20import CheckEmptyUtils from '@ohos/common'; 21 22const TAG = 'Discovery'; 23 24export default abstract class Discovery { 25 mCachePrinters: Map<string, DiscoveredPrinter> = new Map<string, DiscoveredPrinter>(); 26 private mListeners: ArrayList<Listener> = new ArrayList<Listener>(); 27 private mStarted: boolean = false; 28 29 constructor() { 30 31 } 32 33 /** 34 * 开始查找打印机 35 */ 36 abstract onStartDiscovery(): void; 37 38 /** 39 * 停止搜索打印机,释放所有与搜索相关的资源 40 */ 41 abstract onStopDiscovery(): void; 42 43 /** 44 * 任何Discovery对象找到打印机, 就添加监听器 45 * @param listener 监听器 46 */ 47 public addListener(listener: Listener): void { 48 if (!this.mListeners.has(listener)) { 49 Log.info(TAG, 'addListener ' + typeof listener); 50 this.mListeners.add(listener); 51 } 52 this.start(); 53 } 54 55 /** 56 * Remove a listener so that it no longer receives notifications of found printers. 57 * Discovery will continue for other listeners until the last one is removed. 58 * 59 * @param listener listener 60 */ 61 public removeListener(listener: Listener): void { 62 if (!this.mListeners.has(listener)) { 63 Log.error(TAG, 'listener is not exist'); 64 } else { 65 this.mListeners.remove(listener); 66 } 67 if (this.mListeners.isEmpty()) { 68 this.stop(); 69 } 70 } 71 72 /** 73 * Start if not already started 74 */ 75 private start(): void { 76 if (!this.mStarted) { 77 Log.info(TAG, 'discovery is not started, now start'); 78 this.mStarted = true; 79 this.onStartDiscovery(); 80 } else { 81 this.reportCachePrinters(); 82 } 83 } 84 85 private async reportCachePrinters(): Promise<void> { 86 Log.debug(TAG, 'discovery is started, no need start'); 87 if (this.mCachePrinters.size > 0) { 88 let printers: DiscoveredPrinter[] = Array.from(this.mCachePrinters.values()); 89 this.mListeners.forEach((listener: Listener) => { 90 for (let printer of printers) { 91 listener.onPrinterFound(printer); 92 } 93 }); 94 } 95 } 96 97 public stop(): void { 98 if (this.mStarted) { 99 Log.info(TAG, 'discovery is started, now stop'); 100 this.mStarted = false; 101 this.onStopDiscovery(); 102 this.mCachePrinters.clear(); 103 } else { 104 Log.debug(TAG, 'discovery is not started, no need stop'); 105 } 106 } 107 108 /** 109 * 发现了打印机列表 110 * 111 * @param printerArray 112 */ 113 public printerFound(printer: DiscoveredPrinter): void { 114 if (CheckEmptyUtils.isEmpty<DiscoveredPrinter>(printer)) { 115 Log.error(TAG, 'printer is empty'); 116 return; 117 } 118 if (this.mCachePrinters.has(<string>printer.getPath()) ) { 119 Log.info(TAG, 'Already reported the printer, ignoring'); 120 return; 121 } 122 Log.info(TAG, `found printer: ${CommonUtils.getSecurityPrinterName(printer.getDeviceName())}`); 123 this.mCachePrinters.set(<string>printer.getPath(), printer); 124 for (let listener of this.mListeners) { 125 listener.onPrinterFound(printer); 126 } 127 } 128 129 /** 130 * 打印丢失, 上报并删除缓存的打印机 131 * 132 * @param uri 133 */ 134 public printerLost(path: string): void { 135 if (!this.mCachePrinters.has(path)) { 136 Log.error(TAG, `${path} is not exist`); 137 return; 138 } 139 let printer = this.mCachePrinters.get(path); 140 141 let result = this.mCachePrinters.delete(path); 142 if (!result) { 143 Log.error(TAG, 'remove result is false'); 144 return; 145 } 146 Log.info(TAG, `${CommonUtils.getSecurityPrinterName(printer.getDeviceName())} lost`); 147 for (let listener of this.mListeners) { 148 listener.onPrinterLost(printer); 149 } 150 } 151 152 /** 153 * 删除map中的所有打印机信息 154 */ 155 clearPrinterMap(isReported: boolean): void { 156 Log.info(TAG, 'clear printer map'); 157 if (this.mCachePrinters.size === 0) { 158 return; 159 } 160 if (isReported) { 161 for (let key of this.mCachePrinters.keys()) { 162 this.printerLost(<string>key); 163 } 164 } else { 165 this.mCachePrinters.clear(); 166 } 167 } 168 169 /** 170 * this object is in a started state 171 * 172 * @return Return true if this object is in a started state 173 */ 174 isStarted(): boolean { 175 return this.mStarted; 176 } 177} 178 179 180export interface Listener { 181 182 /** 183 * A new printer has been discovered, or an existing printer has been updated 184 * 185 * @param printer DiscoveredPrinter 186 */ 187 onPrinterFound(printer: DiscoveredPrinter): void; 188 189 /** 190 * A previously-found printer is no longer discovered. 191 * 192 * @param printer DiscoveredPrinter 193 */ 194 onPrinterLost(printer: DiscoveredPrinter): void; 195} 196 197export interface P2PDiscoveryListener { 198 onPeerFound(p2pDevice): void; 199 onPeerLost(p2pDevice): void; 200}