1/* 2 * Copyright (c) 2021-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 ServiceExtensionAbility from '@ohos.app.ability.ServiceExtensionAbility'; 17import Want from '@ohos.app.ability.Want'; 18import display from '@ohos.display'; 19import window from '@ohos.window'; 20import rpc from '@ohos.rpc'; 21import Log from '../../../../../../../common/src/main/ets/default/Log'; 22import Constants, { ServiceStubCode } from '../common/Constants'; 23import SystemDialogController from '../controller/Controller'; 24import type { IDialogParameters } from '../controller/Controller'; 25 26const TAG = 'Dialog-ServiceExtensionAbility'; 27 28const getConnectId = (...args) => { 29 return args.join('-'); 30}; 31 32const REPLY_SUCCESS_CODE = 0; 33 34class Stub extends rpc.RemoteObject { 35 onRemoteRequest(code: number, data, reply, option) { 36 const connectId = getConnectId(rpc.IPCSkeleton.getCallingPid(), rpc.IPCSkeleton.getCallingTokenId()); 37 Log.showInfo(TAG, `onRemoteRequest start ${connectId}`); 38 39 if (code === ServiceStubCode.COMMAND_SEND_REMOTE_OBJECT) { 40 Log.showInfo(TAG, `onRemoteRequest code:${ServiceStubCode.COMMAND_SEND_REMOTE_OBJECT} start ${connectId}`); 41 const controller = globalThis[Constants.SYSTEM_DIALOG_CONTROLLER]; 42 const remoteObject = data.readRemoteObject(); 43 Log.showDebug(TAG, `onRemoteRequest code:${ServiceStubCode.COMMAND_SEND_REMOTE_OBJECT} ${remoteObject}`); 44 45 if (remoteObject) { 46 controller.addDataByKey(connectId, { remoteObject }); 47 Log.showDebug(TAG, `onRemoteRequest code:${ServiceStubCode.COMMAND_SEND_REMOTE_OBJECT} end`); 48 49 reply.writeInt(REPLY_SUCCESS_CODE); 50 return true; 51 } 52 53 return false; 54 } 55 56 if (code === ServiceStubCode.COMMAND_START_DIALOG) { 57 Log.showInfo(TAG, `onRemoteRequest code:${ServiceStubCode.COMMAND_START_DIALOG} ${connectId}`); 58 const size = data.readInt(); 59 const parameters: { [key: string]: any } = {}; 60 61 for (let i = 0; i < size; i++) { 62 const key = data.readString(); 63 const value = data.readString(); 64 parameters[key] = value; 65 } 66 67 if (parameters.parameters) { 68 try { 69 const parse = JSON.parse(parameters.parameters); 70 if (typeof parse === 'object') { 71 parameters.parameters = parse; 72 Log.showDebug(TAG, `onRemoteRequest parameters ${parameters.parameters}`); 73 } 74 } catch { 75 parameters.parameters = undefined; 76 } 77 } 78 79 this.createWindow(connectId, parameters); 80 81 reply.writeInt(REPLY_SUCCESS_CODE); 82 return true; 83 } 84 85 return false; 86 } 87 88 async createWindow(connectId: string, parameters: IDialogParameters) { 89 const controller = globalThis[Constants.SYSTEM_DIALOG_CONTROLLER]; 90 const current = controller.getData().get(connectId); 91 if (current && current.windowName) { 92 Log.showInfo(TAG, `createWindow <this same> connectId:${connectId}`); 93 controller.destroyWindow(connectId, false); 94 } 95 96 const windowName = `SystemDialog${++controller.count}`; 97 Log.showInfo(TAG, `createWindow <start> windowName:${windowName} connectId:${connectId} parameters:${JSON.stringify(parameters)}`); 98 99 controller.addDataByKey(connectId, { windowName, parameters }); 100 101 const navigationBarRect = await display.getDefaultDisplay().then(dis => { 102 return { 103 left: 0, 104 top: 0, 105 width: dis.width, 106 height: dis.height 107 }; 108 }); 109 Log.showInfo(TAG, `createWindow <getDefaultDisplay> ${JSON.stringify(navigationBarRect)}`); 110 const win = await window.createWindow({ 111 ctx: controller.getContext(), 112 name: windowName, 113 windowType: window.WindowType.TYPE_FLOAT 114 }); 115 Log.showDebug(TAG, 'createWindow <window.createWindow>'); 116 117 const localStorage = new LocalStorage({ windowName, connectId, parameters }); 118 119 await win.moveWindowTo(navigationBarRect.left, navigationBarRect.top); 120 await win.resize(navigationBarRect.width, navigationBarRect.height); 121 await win.loadContent('pages/ExtIndex', localStorage); 122 await win.setWindowBackgroundColor('#00000000'); 123 await win.showWindow(); 124 125 Log.showDebug(TAG, `createWindow end`); 126 } 127} 128 129export default class DialogServiceExtAbility extends ServiceExtensionAbility { 130 onCreate(want: Want) { 131 Log.showInfo(TAG, 'onCreate'); 132 globalThis[Constants.SYSTEM_DIALOG_CONTROLLER] = new SystemDialogController(this.context); 133 } 134 135 onConnect() { 136 Log.showInfo(TAG, 'onConnect'); 137 return new Stub('SystemDialog'); 138 } 139 140 onDisconnect() { 141 Log.showInfo(TAG, 'onDisconnect'); 142 } 143 144 onDestroy() { 145 const controller = globalThis[Constants.SYSTEM_DIALOG_CONTROLLER]; 146 controller.destroyAllWindow(); 147 globalThis[Constants.SYSTEM_DIALOG_CONTROLLER] = undefined; 148 149 Log.showInfo(TAG, 'onDestroy end'); 150 } 151} 152