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