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