1/* 2 * Copyright (c) 2024 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 */ 15import ServiceExtensionAbility from '@ohos.app.ability.ServiceExtensionAbility'; 16import common from '@ohos.app.ability.common'; 17import window from '@ohos.window'; 18import Want from '@ohos.app.ability.Want'; 19import display from '@ohos.display'; 20import GlobalContext from './GlobalContext'; 21import { BusinessError } from '@ohos.base'; 22 23const TAG = 'PasteboardProgressAbility: '; 24const BG_COLOR = '#00000000'; 25let createWindowStatus = 'created'; 26 27interface IRect { 28 left: number; 29 top: number; 30 width: number; 31 height: number; 32} 33 34interface StorageItem { 35 want: Want, 36 win: window.Window, 37 serviceContext: common.ServiceExtensionContext, 38 globalContext: GlobalContext 39} 40 41export default class PasteboardProgressAbility extends ServiceExtensionAbility { 42 onCreate(want: Want): void { 43 console.info(TAG + 'PasteboardProgressAbility onCreate, ability name is ' + want.abilityName); 44 } 45 46 async onRequest(want: Want, startId: number) { 47 try { 48 console.info(TAG + 'PasteboardProgressAbility onRequest, startId is' + startId); 49 console.info(TAG + 'want: ' + JSON.stringify(want)); 50 if (!this.checkWantParamsValid(want)) { 51 return; 52 } 53 let displayClass = display.getDefaultDisplaySync(); 54 let navigationBarRect: IRect = { 55 left: 0, 56 top: 0, 57 width: displayClass.width, 58 height: displayClass.height, 59 }; 60 if (canIUse('SystemCapability.Window.SessionManager')) { 61 await window.getVisibleWindowInfo().then((infos: window.WindowInfo[]) => { 62 const targetWindowId = want.parameters?.windowId as number; 63 const targetWindowInfo = infos.find(info => info.windowId === targetWindowId); 64 navigationBarRect = targetWindowInfo?.rect as IRect; 65 console.info(TAG + `targetWindowInfo rect is ${JSON.stringify(navigationBarRect)}`); 66 }).catch((err: BusinessError) => { 67 console.error(TAG + 'Failed to getWindowInfo. Cause: ' + JSON.stringify(err)); 68 }); 69 } 70 this.createWindow(`PasteboardProgressDialog${startId}`, navigationBarRect, want); 71 } catch (exception) { 72 console.error(TAG + 'Failed to obtain the default display object. Code:' + JSON.stringify(exception)) 73 } 74 } 75 76 onDestroy(): void { 77 console.info(TAG + 'PasteboardProgressAbility onDestroy.') 78 } 79 80 private checkWantParamsValid(want: Want): boolean { 81 let validParam = true; 82 const requiredParams = ['windowId', 'progressKey', 'tokenKey', 'promptText', 'ipcCallback']; 83 const missingParams = requiredParams.filter(param =>!(Reflect.has((want.parameters || {}), param))); 84 if (missingParams.length) { 85 validParam = false; 86 console.error(TAG + `params missing valid: ${missingParams.join(', ')}`); 87 } 88 return validParam; 89 } 90 91 private async createWindow(name: string, rect: IRect, want: Want): Promise<void> { 92 if (createWindowStatus === 'created') { 93 createWindowStatus = 'creating'; 94 console.info(TAG + 'create progressWindow'); 95 } else { 96 console.warn(TAG + 'window is creating'); 97 return; 98 } 99 const progressKey = want.parameters?.['progressKey'] as string; 100 if (GlobalContext.getInstance().dialogSet.has(progressKey)) { 101 console.info(TAG + 'window already exists'); 102 return; 103 } 104 try { 105 const win = await window.createWindow({ 106 ctx: this.context, 107 name, 108 windowType: window.WindowType.TYPE_DIALOG 109 }); 110 await win.bindDialogTarget((want.parameters?.['tokenKey'] as ESObject).value, () => { 111 win.destroyWindow(); 112 console.info(TAG + 'destroyWindow'); 113 GlobalContext.getInstance().dialogSet.delete(progressKey); 114 if (GlobalContext.getInstance().dialogSet.size === 0) { 115 this.context.terminateSelf(); 116 } 117 }); 118 let storageItem: StorageItem = { 119 want, 120 win, 121 globalContext: GlobalContext.getInstance(), 122 serviceContext: this.context 123 } 124 let storage: LocalStorage = new LocalStorage(storageItem); 125 await win.moveWindowTo(rect.left, rect.top); 126 await win.resize(rect.width, rect.height); 127 await win.loadContent('pages/PasteboardProgress', storage); 128 win.setWindowBackgroundColor(BG_COLOR); 129 await win.showWindow(); 130 GlobalContext.getInstance().dialogSet.add(progressKey); 131 console.info(TAG + `dialogSet add, size is ${GlobalContext.getInstance().dialogSet.size}`); 132 } catch (err) { 133 console.error(TAG + `window create failed! code is ${err.code}, message is ${err.message}`); 134 } finally { 135 createWindowStatus = 'created'; 136 } 137 } 138}