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