1/* 2 * Copyright (c) 2022 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 inputMethod from '@ohos.inputMethod'; 19import commonEvent from '@ohos.commonEventManager'; 20import Want from '@ohos.app.ability.Want'; 21import { BusinessError } from '@ohos.base'; 22 23let TAG: string = '[InputMethodChooseDialog]'; 24let PACKAGE_ADDED: string = 'usual.event.PACKAGE_ADDED'; 25let PACKAGE_REMOVED: string = 'usual.event.PACKAGE_REMOVED'; 26let subscribeInfo: commonEvent.CommonEventSubscribeInfo = { 27 events: [PACKAGE_ADDED, PACKAGE_REMOVED] 28}; 29 30interface DialogRect { 31 left: number; 32 top: number; 33 width: number; 34 height: number; 35} 36 37export default class ServiceExtAbility extends ServiceExtensionAbility { 38 private extensionWin: window.Window | undefined = undefined; 39 private mContext: common.ServiceExtensionContext | undefined = undefined; 40 private windowNum: number = 0; 41 42 onCreate(want: Want): void { 43 console.log(TAG, 'onCreate'); 44 this.windowNum = 0; 45 this.mContext = this.context; 46 } 47 48 onRequest(want: Want, startId: number): void { 49 console.log(TAG, 'onRequest execute'); 50 let dialogRect: DialogRect = { 51 left: 50, 52 top: 900, 53 width: 300, 54 height: 300, 55 }; 56 let windowConfig: window.Configuration = { 57 name: 'inputmethod Dialog', 58 windowType: window.WindowType.TYPE_FLOAT, 59 ctx: this.mContext 60 }; 61 this.getInputMethods().then(() => { 62 this.createWindow(windowConfig, dialogRect); 63 }); 64 65 commonEvent.createSubscriber(subscribeInfo, (error: BusinessError, subcriber: commonEvent.CommonEventSubscriber) => { 66 commonEvent.subscribe(subcriber, (error: BusinessError, commonEventData: commonEvent.CommonEventData) => { 67 if (error) { 68 console.log(TAG + `commonEvent subscribe error, errorCode: ${error}`); 69 return; 70 } 71 console.log(TAG + 'commonEvent:' + JSON.stringify(commonEventData?.event)); 72 if (commonEventData?.event === PACKAGE_ADDED || commonEventData?.event === PACKAGE_REMOVED) { 73 this.updateImeList(); 74 } 75 }); 76 }); 77 } 78 79 onDestroy(): void { 80 console.log(TAG + 'ServiceExtAbility destroyed'); 81 this.releaseContext(); 82 } 83 84 private async createWindow(config: window.Configuration, rect: DialogRect): Promise<void> { 85 console.log(TAG + 'createWindow execute'); 86 try { 87 if (this.windowNum > 0) { 88 this.updateImeList(); 89 return; 90 } 91 try { 92 this.extensionWin = await window.createWindow(config); 93 console.info(TAG + 'Succeeded in creating the window. Data: ' + JSON.stringify(this.extensionWin)); 94 this.extensionWin.on('windowEvent', async (data: window.WindowEventType) => { 95 console.log(TAG + 'windowEvent:' + JSON.stringify(data)); 96 if (data === window.WindowEventType.WINDOW_INACTIVE) { 97 await this.releaseContext(); 98 } 99 }); 100 await this.extensionWin.moveWindowTo(rect.left, rect.top); 101 await this.extensionWin.resize(rect.width, rect.height); 102 await this.extensionWin.setUIContent('pages/index'); 103 await this.extensionWin.showWindow(); 104 this.windowNum++; 105 console.log(TAG + 'window create successfully'); 106 } catch (exception) { 107 console.error('Failed to create the window. Cause: ' + JSON.stringify(exception)); 108 } 109 } catch { 110 console.info(TAG + 'window create failed'); 111 } 112 } 113 114 private async getInputMethods(): Promise<void> { 115 let inputMethodList: Array<inputMethod.InputMethodProperty> = []; 116 try { 117 let enableList = await inputMethod.getSetting().getInputMethods(true); 118 let disableList = await inputMethod.getSetting().getInputMethods(false); 119 inputMethodList = enableList.concat(disableList); 120 AppStorage.setOrCreate('inputMethodList', inputMethodList); 121 } catch { 122 console.log(TAG + 'getInputMethods failed'); 123 } 124 } 125 126 private async updateImeList(): Promise<void> { 127 await this.getInputMethods().then(async () => { 128 if (this.extensionWin) { 129 await this.extensionWin.setUIContent('pages/index'); 130 if (!this.extensionWin.isWindowShowing()) { 131 await this.extensionWin.showWindow(); 132 } 133 } 134 }); 135 } 136 137 public async releaseContext(): Promise<void> { 138 await this.extensionWin?.destroyWindow(); 139 await this.mContext?.terminateSelf(); 140 } 141};