1/* 2 * Copyright (c) 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 */ 15import rpc from '@ohos.rpc'; 16import hilog from '@ohos.hilog'; 17import window from '@ohos.window'; 18import display from '@ohos.display'; 19import ServiceExtensionAbility from '@ohos.app.ability.ServiceExtensionAbility'; 20import type Want from '@ohos.application.Want'; 21 22interface IRect { 23 left: number; 24 top: number; 25 width: number; 26 height: number; 27} 28 29const DISTANCE_NUMBER = 68; 30const TAG = 'ToastExtensionAbility'; 31 32class ToastStub extends rpc.RemoteObject { 33 constructor(des: string) { 34 super(des); 35 } 36} 37 38export default class ToastExtensionAbility extends ServiceExtensionAbility { 39 onCreate(want: Want): void { 40 hilog.info(0, TAG, 'onCreate'); 41 globalThis.context = this.context; 42 } 43 44 onConnect(want: Want): ToastStub { 45 hilog.info(0, TAG, 'onConnect'); 46 display 47 .getDefaultDisplay() 48 .then((display: display.Display) => { 49 const toastRect = { 50 left: 0, 51 top: 0, 52 width: display.width, 53 height: display.height, 54 }; 55 globalThis.toastInfo = { 56 fromAppName: want.parameters.fromAppName, 57 toAppName: want.parameters.toAppName, 58 displayHeight:display.height / display.densityPixels - DISTANCE_NUMBER, 59 }; 60 this.createToastWindow('PasteboardToast' + new Date().getTime(), toastRect); 61 }) 62 .catch((err) => { 63 hilog.info(0, TAG, 'getDefaultDisplay err: ' + JSON.stringify(err)); 64 }); 65 return new ToastStub('PasteboardToast'); 66 } 67 68 onRequest(want: Want, startId: number): void { 69 hilog.info(0, TAG, 'onRequest'); 70 this.onConnect(want); 71 } 72 73 onDisconnet(): void { 74 hilog.info(0, TAG, 'onDisconnet'); 75 this.onDestroy(); 76 } 77 78 onDestroy(): void { 79 hilog.info(0, TAG, 'onDestroy'); 80 globalThis.extensionWin.destroyWindow(); 81 globalThis.context.terminateSelf(); 82 } 83 84 private async createToastWindow(name: string, rect: IRect): Promise<void> { 85 hilog.info(0, TAG, 'create toast begin'); 86 87 if (globalThis.windowNum > 0) { 88 globalThis.windowNum = 0; 89 this.onDestroy(); 90 } 91 let windowClass = null; 92 let config = { 93 name, 94 windowType: window.WindowType.TYPE_FLOAT, 95 ctx: this.context, 96 }; 97 try { 98 window.createWindow(config, (err, data) => { 99 if (err.code) { 100 hilog.error(0, TAG, 'Failed to create the window. Cause: ' + JSON.stringify(err)); 101 return; 102 } 103 windowClass = data; 104 globalThis.extensionWin = data; 105 hilog.info(0, TAG, 'Succeeded in creating the window. Data: ' + JSON.stringify(data)); 106 try { 107 windowClass.setUIContent('pages/toastIndex', (err) => { 108 if (err.code) { 109 hilog.error(0, TAG, 'Failed to load the content. Cause:' + JSON.stringify(err)); 110 return; 111 } 112 windowClass.moveWindowTo(rect.left, rect.top); 113 windowClass.resize(rect.width, rect.height); 114 windowClass.setBackgroundColor('#00000000'); 115 windowClass.setWindowTouchable(false); 116 windowClass.showWindow(); 117 globalThis.windowNum++; 118 hilog.info(0, TAG, 'Create window successfully'); 119 }); 120 } catch (exception) { 121 hilog.error(0, TAG, 'Failed to load the content. Cause:' + JSON.stringify(exception)); 122 } 123 }); 124 } catch (exception) { 125 hilog.error(0, TAG, 'Failed to create the window. Cause: ' + JSON.stringify(exception)); 126 } 127 } 128} 129