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 window from '@ohos.window'; 17import display from '@ohos.display'; 18import inputMethod from '@ohos.inputMethod'; 19import prompt from '@ohos.prompt'; 20import type Want from './@ohos.app.ab'; 21import commonEvent from '@ohos.commonEvent'; 22 23let TAG = '[InputMethodChooseDialog]'; 24let commonEvent1 = 'usual.event.PACKAGE_ADDED'; 25let commonEvent2 = 'usual.event.PACKAGE_REMOVED'; 26let subscribeInfo = { 27 events: [commonEvent1, commonEvent2] 28}; 29const EXIT_TIME = 1000; 30 31export default class ServiceExtAbility extends ServiceExtensionAbility { 32 onCreate(want): void { 33 console.log(TAG, 'onCreate'); 34 globalThis.windowNum = 0; 35 } 36 37 onRequest(want: Want, startId: number): void { 38 console.log(TAG, 'onRequest execute'); 39 globalThis.abilityWant = want; 40 display.getDefaultDisplay().then(() => { 41 let dialogRect = { 42 left: 50, 43 top: 900, 44 width: 300, 45 height: 300, 46 }; 47 let windowConfig = { 48 name: 'inputmethod Dialog', 49 windowType: window.WindowType.TYPE_FLOAT, 50 ctx: this.context 51 }; 52 this.getInputMethods().then(() => { 53 this.createWindow(windowConfig, dialogRect); 54 }); 55 }).catch((err) => { 56 console.log(TAG + 'getDefaultDisplay err:' + JSON.stringify(err)); 57 }); 58 59 commonEvent.createSubscriber(subscribeInfo, (error, subcriber) => { 60 commonEvent.subscribe(subcriber, (error, commonEventData) => { 61 if (commonEventData.event === commonEvent1 || commonEventData.event === commonEvent2) { 62 console.log(TAG + 'commonEvent:' + JSON.stringify(commonEvent1)); 63 this.updateImeList(); 64 } 65 }); 66 }); 67 68 globalThis.chooseInputMethods = ((prop: inputMethod.InputMethodProperty): void => { 69 inputMethod.switchInputMethod(prop).then((err) => { 70 if (!err) { 71 console.log(TAG + 'switchInputMethod failed,' + JSON.stringify(err)); 72 prompt.showToast({ 73 message: 'switch failed', duration: 200 74 }); 75 } else { 76 console.log(TAG + 'switchInputMethod success'); 77 prompt.showToast({ 78 message: 'switch success', duration: 200 79 }); 80 } 81 setTimeout(() => { 82 this.releaseContext(); 83 }, EXIT_TIME); 84 }); 85 }); 86 } 87 88 onDestroy(): void { 89 console.log(TAG + 'ServiceExtAbility destroyed'); 90 this.releaseContext(); 91 } 92 93 private async createWindow(config: window.Configuration, rect): Promise<void> { 94 console.log(TAG + 'createWindow execute'); 95 try { 96 if (globalThis.windowNum > 0) { 97 this.updateImeList(); 98 return; 99 } 100 try { 101 await window.createWindow(config, async (err, data) => { 102 if (err.code) { 103 console.error('Failed to create the window. Cause: ' + JSON.stringify(err)); 104 return; 105 } 106 const win = data; 107 globalThis.extensionWin = win; 108 console.info('Succeeded in creating the window. Data: ' + JSON.stringify(data)); 109 win.on('windowEvent', async (data) => { 110 console.log(TAG + 'windowEvent:' + JSON.stringify(data)); 111 if (data === window.WindowEventType.WINDOW_INACTIVE) { 112 await this.releaseContext(); 113 } 114 }); 115 await win.moveTo(rect.left, rect.top); 116 await win.resetSize(rect.width, rect.height); 117 await win.loadContent('pages/index'); 118 await win.show(); 119 globalThis.windowNum++; 120 console.log(TAG + 'window create successfully'); 121 }); 122 } catch (exception) { 123 console.error('Failed to create the window. Cause: ' + JSON.stringify(exception)); 124 } 125 globalThis.context = this.context; 126 } catch { 127 console.info(TAG + 'window create failed'); 128 } 129 } 130 131 private async getInputMethods(): Promise<void> { 132 globalThis.inputMethodList = []; 133 try { 134 let enableList = await inputMethod.getSetting().getInputMethods(true); 135 let disableList = await inputMethod.getSetting().getInputMethods(false); 136 globalThis.inputMethodList = [...enableList, ...disableList]; 137 } catch { 138 console.log(TAG + 'getInputMethods failed'); 139 } 140 } 141 142 private async updateImeList(): Promise<void> { 143 await this.getInputMethods().then(async () => { 144 await globalThis.extensionWin.loadContent('pages/index'); 145 if (!globalThis.extensionWin.isWindowShowing()) { 146 await globalThis.extensionWin.show(); 147 } 148 }); 149 } 150 151 private async releaseContext(): Promise<void> { 152 if (globalThis.context !== null) { 153 await globalThis.extensionWin.destroy(); 154 await globalThis.context.terminateSelf(); 155 globalThis.context = null; 156 } 157 } 158};