• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
15
16import commonEventManager from '@ohos.commonEventManager';
17import display from '@ohos.display';
18import inputMethodEngine from '@ohos.inputMethodEngine';
19import InputMethodExtensionContext from '@ohos.InputMethodExtensionContext';
20
21// Call the getInputMethodAbility method of the input method framework to get the instance
22const inputMethodAbility: inputMethodEngine.InputMethodAbility = inputMethodEngine.getInputMethodAbility();
23const DEFAULT_DIRECTION: number = 1;
24const DEFAULT_LENGTH: number = 1;
25const DEFAULT_SELECT_RANGE: number = 10;
26
27enum TEST_RESULT_CODE {
28  SUCCESS,
29  FAILED
30}
31
32enum TEST_FUNCTION {
33  INSERT_TEXT_SYNC,
34  MOVE_CURSOR_SYNC,
35  GET_ATTRIBUTE_SYNC,
36  SELECT_BY_RANGE_SYNC,
37  SELECT_BY_MOVEMENT_SYNC,
38  GET_INDEX_AT_CURSOR_SYNC,
39  DELETE_FORWARD_SYNC,
40  DELETE_BACKWARD_SYNC,
41  GET_FORWARD_SYNC,
42  GET_BACKWARD_SYNC,
43  CHANGE_FLAG_TO_FIXED,
44  CHANGE_FLAG_TO_FLOATING,
45  SETPRIVACYMODE_WITHOUT_PERMISSION,
46  SETPRIVACYMODE_ERROR_PARAM,
47}
48
49export class KeyboardController {
50  private TAG: string = 'inputDemo: KeyboardController ';
51  private mContext: InputMethodExtensionContext | undefined = undefined; // save the context property of InputMethodExtensionAbility
52  private panel: inputMethodEngine.Panel | undefined = undefined;
53  private subscriber = undefined;
54
55  constructor() {
56  }
57
58  public onCreate(context: InputMethodExtensionContext): void {
59    this.mContext = context;
60    this.initWindow(); // init window
61    this.registerListener(); //register input listener
62  }
63
64  public onDestroy(): void {
65    this.unRegisterListener();
66    if (this.panel) {
67      this.panel.hide();
68      inputMethodAbility.destroyPanel(this.panel);
69    }
70    this.mContext.destroy();
71  }
72
73  private initWindow(): void {
74    if (this.mContext === undefined) {
75      return;
76    }
77    let dis = display.getDefaultDisplaySync();
78    let dWidth = dis.width;
79    let dHeight = dis.height;
80    let keyHeightRate = 0.47;
81    let keyHeight = dHeight * keyHeightRate;
82    let nonBarPosition = dHeight - keyHeight;
83    let panelInfo: inputMethodEngine.PanelInfo = {
84      type: inputMethodEngine.PanelType.SOFT_KEYBOARD,
85      flag: inputMethodEngine.PanelFlag.FLG_FIXED
86    };
87    inputMethodAbility.createPanel(this.mContext, panelInfo).then(async (inputPanel: inputMethodEngine.Panel) => {
88      this.panel = inputPanel;
89      if (this.panel) {
90        await this.panel.resize(dWidth, keyHeight);
91        await this.panel.moveTo(0, nonBarPosition);
92        await this.panel.setUiContent('pages/Index');
93      }
94    });
95  }
96
97  publishCommonEvent(event: string, codeNumber: number): void {
98    this.addLog(`[inputDemo] publish event, event= ${event}, codeNumber= ${codeNumber}`);
99    commonEventManager.publish(event, { code: codeNumber }, (err) => {
100      if (err) {
101        this.addLog(`inputDemo publish ${event} failed, err = ${JSON.stringify(err)}`);
102      } else {
103        this.addLog(`inputDemo publish ${event} success`);
104      }
105    })
106  }
107
108  private registerListener(): void {
109    this.registerInputListener();
110    let subscribeInfo = {
111      events: ['syncTestFunction']
112    }
113    commonEventManager.createSubscriber(subscribeInfo).then((data) => {
114      this.subscriber = data;
115      commonEventManager.subscribe(this.subscriber, (err, eventData) => {
116        this.addLog(`[inputDemo] subscribe, eventData.code = ${eventData.code}`);
117        if (globalThis.textInputClient === undefined) {
118          return;
119        }
120        switch (eventData.code) {
121          case TEST_FUNCTION.INSERT_TEXT_SYNC:
122            globalThis.textInputClient.insertTextSync("text");
123            break;
124          case TEST_FUNCTION.MOVE_CURSOR_SYNC:
125            globalThis.textInputClient.moveCursorSync(DEFAULT_DIRECTION);
126            break;
127          case TEST_FUNCTION.GET_ATTRIBUTE_SYNC:
128            this.getAttributeSync();
129            break;
130          case TEST_FUNCTION.SELECT_BY_RANGE_SYNC:
131            globalThis.textInputClient.selectByRangeSync({ start: 0, end: DEFAULT_SELECT_RANGE });
132            break;
133          case TEST_FUNCTION.SELECT_BY_MOVEMENT_SYNC:
134            globalThis.textInputClient.selectByMovementSync({ direction: inputMethodEngine.CURSOR_LEFT });
135            break;
136          case TEST_FUNCTION.GET_INDEX_AT_CURSOR_SYNC:
137            this.getIndexAtCursorSync()
138            break;
139          case TEST_FUNCTION.DELETE_FORWARD_SYNC:
140            globalThis.textInputClient.deleteForwardSync(DEFAULT_LENGTH);
141            break;
142          case TEST_FUNCTION.DELETE_BACKWARD_SYNC:
143            globalThis.textInputClient.deleteBackwardSync(DEFAULT_LENGTH);
144            break;
145          case TEST_FUNCTION.GET_FORWARD_SYNC:
146            this.getForwardSync();
147            break;
148          case TEST_FUNCTION.GET_BACKWARD_SYNC:
149            this.getBackwardSync();
150            break;
151          case TEST_FUNCTION.CHANGE_FLAG_TO_FIXED:
152            this.changePanelFlag(inputMethodEngine.PanelFlag.FLG_FIXED);
153            break;
154          case TEST_FUNCTION.CHANGE_FLAG_TO_FLOATING:
155            this.changePanelFlag(inputMethodEngine.PanelFlag.FLG_FLOATING);
156            break;
157          case TEST_FUNCTION.SETPRIVACYMODE_WITHOUT_PERMISSION:
158            this.setPrivacyModeWithoutPermission();
159            break;
160          case TEST_FUNCTION.SETPRIVACYMODE_ERROR_PARAM:
161            this.setPrivacyModeErrorParam();
162            break;
163          default:
164            break;
165        }
166      })
167    })
168  }
169
170  private registerInputListener(): void { // 注册对输入法框架服务的开启及停止事件监听
171    inputMethodAbility.on('inputStart', (kbController, textInputClient) => {
172      globalThis.textInputClient = textInputClient; // 此为输入法客户端实例,由此调用输入法框架提供给输入法应用的功能接口
173      globalThis.keyboardController = kbController;
174    })
175    inputMethodAbility.on('inputStop', () => {
176      this.onDestroy();
177    });
178  }
179
180  private unRegisterListener(): void {
181    inputMethodAbility.off('inputStart');
182    inputMethodAbility.off('inputStop', () => {
183    });
184  }
185
186  getBackwardSync() {
187    let backward: string = globalThis.textInputClient.getBackwardSync(1);
188    if (backward.length >= 0) {
189      this.publishCommonEvent('getBackwardSyncResult', TEST_RESULT_CODE.SUCCESS);
190    } else {
191      this.publishCommonEvent('getBackwardSyncResult', TEST_RESULT_CODE.FAILED);
192    }
193  }
194
195  getForwardSync() {
196    let forward: string = globalThis.textInputClient.getForwardSync(1);
197    if (forward.length >= 0) {
198      this.publishCommonEvent('getForwardSyncResult', TEST_RESULT_CODE.SUCCESS);
199    } else {
200      this.publishCommonEvent('getForwardSyncResult', TEST_RESULT_CODE.FAILED);
201    }
202  }
203
204  async getAttributeSync() {
205    try {
206      let editAttribute = globalThis.textInputClient.getEditorAttributeSync();
207      let editAttribute1 = await globalThis.textInputClient.getEditorAttribute();
208      this.addLog(`[inputDemo] publish getEditorAttributeSync editAttribute= ${JSON.stringify(editAttribute)}`);
209      if(editAttribute.inputPattern == editAttribute1.inputPattern && editAttribute.enterKeyType == editAttribute1.enterKeyType) {
210        this.publishCommonEvent('getEditorAttributeSyncResult', TEST_RESULT_CODE.SUCCESS);
211      } else{
212        this.publishCommonEvent('getEditorAttributeSyncResult', TEST_RESULT_CODE.FAILED);
213      }
214    } catch (err) {
215      this.publishCommonEvent('getEditorAttributeSyncResult', TEST_RESULT_CODE.FAILED);
216    }
217  }
218
219  getIndexAtCursorSync() {
220    try {
221      let index = globalThis.textInputClient.getTextIndexAtCursorSync();
222      this.addLog(`[inputDemo] publish getTextIndexAtCursorSync index= ${index}`);
223      this.publishCommonEvent('getTextIndexAtCursorSyncResult', TEST_RESULT_CODE.SUCCESS);
224    } catch (err) {
225      this.publishCommonEvent('getTextIndexAtCursorSyncResult', TEST_RESULT_CODE.FAILED);
226    }
227  }
228
229  changePanelFlag(panelFlag: inputMethodEngine.PanelFlag) {
230    try {
231      this.panel.hide((err) => {
232        if (err) {
233          this.addLog(`Failed to hide panel: ${JSON.stringify(err)}`);
234          this.publishCommonEvent('changeFlag', TEST_RESULT_CODE.FAILED);
235          return;
236        }
237        this.panel.changeFlag(panelFlag);
238        this.panel.show((err) => {
239          this.addLog(`Failed to show panel: ${JSON.stringify(err)}`);
240          this.publishCommonEvent('changeFlag', TEST_RESULT_CODE.SUCCESS);
241        });
242      });
243    } catch (err) {
244      this.addLog(`failed: ${JSON.stringify(err)}`);
245      this.publishCommonEvent('changeFlag', TEST_RESULT_CODE.FAILED);
246    }
247  }
248
249  setPrivacyModeWithoutPermission() {
250    try {
251      let isSetPrivacyMode: boolean = true;
252      this.panel.setPrivacyMode(isSetPrivacyMode);
253      this.publishCommonEvent('setPrivacyModeWithoutPermissionResult', TEST_RESULT_CODE.FAILED);
254    } catch (err) {
255      this.addLog(`failed: ${JSON.stringify(err)}`);
256      if (err.code === 201) {
257        this.publishCommonEvent('setPrivacyModeWithoutPermissionResult', TEST_RESULT_CODE.SUCCESS);
258        return;
259      }
260    }
261  }
262
263  setPrivacyModeErrorParam() {
264    try {
265      this.panel.setPrivacyMode(undefined);
266      this.publishCommonEvent('setPrivacyModeErrorParamResult', TEST_RESULT_CODE.FAILED);
267    } catch (err) {
268      this.addLog(`failed: ${JSON.stringify(err)}`);
269      if (err.code === 401) {
270        this.publishCommonEvent('setPrivacyModeErrorParamResult', TEST_RESULT_CODE.SUCCESS);
271        return;
272      }
273    }
274  }
275
276  private addLog(message): void {
277    console.log(this.TAG + message)
278  }
279}
280
281const keyboardController = new KeyboardController();
282
283export default keyboardController;