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 { MessageEvent } from '@ohos/common'; 17import CheckEmptyUtils, { 18 GET_CAPS_ERROR, 19 Log, 20} from '@ohos/common'; 21import LocalPrinterCapabilities from '../napi/LocalPrinterCapabilities'; 22import type { OnLocalPrinterCapabilities } from '../ipp/CapabilitiesCache'; 23import type uri from '@ohos.uri'; 24// @ts-ignore 25import { print } from '@kit.BasicServicesKit'; 26import CommonUtils from '../utils/CommonUtils'; 27import { WorkerUtil } from '../utils/WorkerUtil'; 28import type { WorkerResponse } from '../model/WorkerData'; 29import { RequestCode, ResponseCode, WorkerRequest } from '../model/WorkerData'; 30import worker from '@ohos.worker'; 31import { PrinterCapability } from '@ohos/common'; 32 33const TAG = 'Backend'; 34 35export class Backend { 36 private requestCallback: () => void; 37 private mWorker: worker.ThreadWorker; 38 private onCapabilitiesCallback: OnLocalPrinterCapabilities; 39 40 constructor() { 41 let initResult: boolean = this.initPrintWorker(); 42 if (!initResult) { 43 return; 44 } 45 } 46 47 /** 48 * 获取打印机能力 49 * 50 * @param uri 51 * @param timeout 52 * @param onLocalPrinterCapabilities 53 */ 54 public getCapabilities(uri: uri.URI, printerName: string, onLocalPrinterCapabilities: OnLocalPrinterCapabilities, requestCallback: () => void): void { 55 Log.debug(TAG, `getCapabilities, uri is: ${uri.scheme}://${CommonUtils.getSecurityIp(uri.host)}:**${uri.path}`); 56 if (uri === undefined) { 57 Log.error(TAG, 'uri is undefined'); 58 return; 59 } 60 this.onCapabilitiesCallback = onLocalPrinterCapabilities; 61 this.requestCallback = requestCallback; 62 let getCapsRequest: WorkerRequest = new WorkerRequest(RequestCode.GET_CAPS); 63 getCapsRequest.data = { 64 uri: uri.toString(), 65 printerName: printerName 66 }; 67 WorkerUtil.postMessageToWorkerThread(this.mWorker, getCapsRequest); 68 } 69 70 /** 71 * 退出程序, 释放资源 72 */ 73 public close(): void { 74 Log.info(TAG, 'close'); 75 this.mWorker.terminate(); 76 } 77 78 private handleGetCapsResult(responseCode: ResponseCode, result: PrinterCapability): void { 79 Log.debug(TAG, 'handleGetCapsResult enter'); 80 if (ResponseCode.ERROR === responseCode) { 81 //获取打印机能力失败,上报错误 82 this.onCapabilitiesCallback.onCapabilities(null); 83 this.requestCallback(); 84 return; 85 } 86 this.onCapabilitiesCallback.onCapabilities(result); 87 this.requestCallback(); 88 } 89 90 /** 91 * init print worker 92 */ 93 private initPrintWorker(): boolean { 94 if (this.mWorker === undefined) { 95 this.mWorker = new worker.ThreadWorker('entry/ets/workers/PrintWorker.ts', { 96 type: 'classic', 97 name: 'PrintWorkerOfExtension' 98 }); 99 if (this.mWorker === undefined) { 100 Log.error(TAG, 'initWorker failed'); 101 return false; 102 } 103 this.mWorker.onmessage = this.onMessage; 104 this.mWorker.onmessageerror = (messageEvent: MessageEvent<object>): void => { 105 Log.error(TAG, 'onMessageError : ' + JSON.stringify(messageEvent)); 106 }; 107 this.mWorker.onerror = (errorEvent: object): void => { 108 Log.error(TAG, 'onError : ' + JSON.stringify(errorEvent)); 109 }; 110 this.mWorker.onexit = (code: number): void => { 111 Log.info(TAG, 'onExit : ' + code); 112 this.mWorker = undefined; 113 }; 114 Log.info(TAG, 'initWorker success'); 115 return true; 116 } 117 return false; 118 } 119 120 /** 121 * receive message from worker thread 122 * 123 * @param messageEvent 124 */ 125 private onMessage = (messageEvent: MessageEvent<WorkerResponse>): void => { 126 Log.info(TAG, 'printWorker response'); 127 if (CheckEmptyUtils.isEmpty(messageEvent)) { 128 Log.error(TAG, 'print worker response is empty'); 129 return; 130 } 131 if (!messageEvent.hasOwnProperty('data')) { 132 Log.error(TAG, 'messageEvent has not data'); 133 return; 134 } 135 let workerResponse: WorkerResponse = messageEvent.data; 136 if (workerResponse === undefined || workerResponse === null) { 137 Log.error(TAG, 'workerResponse is empty'); 138 return; 139 } 140 if (!workerResponse.hasOwnProperty('requestCode') || !workerResponse.hasOwnProperty('responseCode')) { 141 Log.error(TAG, 'workerResponse is error'); 142 return; 143 } 144 let requestCode = workerResponse.requestCode; 145 let responseCode = workerResponse.responseCode; 146 Log.info(TAG, `requestCode: ${WorkerUtil.getStringByWorkerCode(requestCode)}, responseCode: ${responseCode}`); 147 switch (requestCode) { 148 case RequestCode.GET_CAPS: 149 this.handleGetCapsResult(<ResponseCode> responseCode, <PrinterCapability> workerResponse.data); 150 break; 151 default: 152 Log.error(TAG, 'onMessage response. error code'); 153 } 154 }; 155}