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 16 #ifndef FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_INPUT_METHOD_CONTROLLER_H 17 #define FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_INPUT_METHOD_CONTROLLER_H 18 19 #include <atomic> 20 #include <condition_variable> 21 #include <mutex> 22 #include <thread> 23 24 #include "controller_listener.h" 25 #include "event_handler.h" 26 #include "event_status_manager.h" 27 #include "global.h" 28 #include "i_input_method_agent.h" 29 #include "i_input_method_system_ability.h" 30 #include "input_client_info.h" 31 #include "input_method_property.h" 32 #include "input_method_setting_listener.h" 33 #include "input_method_status.h" 34 #include "input_method_utils.h" 35 #include "ipc_skeleton.h" 36 #include "iremote_object.h" 37 #include "key_event.h" 38 #include "message_handler.h" 39 #include "visibility.h" 40 41 namespace OHOS { 42 namespace MiscServices { 43 class OnTextChangedListener : public virtual RefBase { 44 public: 45 virtual void InsertText(const std::u16string &text) = 0; 46 virtual void DeleteForward(int32_t length) = 0; 47 virtual void DeleteBackward(int32_t length) = 0; 48 virtual void SendKeyEventFromInputMethod(const KeyEvent &event) = 0; 49 virtual void SendKeyboardStatus(const KeyboardStatus &keyboardStatus) = 0; 50 virtual void SendFunctionKey(const FunctionKey &functionKey) = 0; 51 virtual void SetKeyboardStatus(bool status) = 0; 52 virtual void MoveCursor(const Direction direction) = 0; 53 virtual void HandleSetSelection(int32_t start, int32_t end) = 0; 54 virtual void HandleExtendAction(int32_t action) = 0; 55 virtual void HandleSelect(int32_t keyCode, int32_t cursorMoveSkip) = 0; 56 virtual std::u16string GetLeftTextOfCursor(int32_t number) = 0; 57 virtual std::u16string GetRightTextOfCursor(int32_t number) = 0; 58 virtual int32_t GetTextIndexAtCursor() = 0; 59 }; 60 61 class InputMethodController : public RefBase { 62 public: 63 /** 64 * @brief Get the instance of InputMethodController. 65 * 66 * This function is used to get the instance of InputMethodController. 67 * 68 * @return The instance of InputMethodController. 69 * @since 6 70 */ 71 IMF_API static sptr<InputMethodController> GetInstance(); 72 73 /** 74 * @brief Show soft keyboard, set listener and bind IMSA with default states and attribute. 75 * 76 * This function is used to show soft keyboard, set listener and bind IMSA, 77 * default state is 'true', default attribute is 'InputAttribute::PATTERN_TEXT'. 78 * 79 * @param listener Indicates the listener in order to manipulate text. 80 * @return Returns 0 for success, others for failure. 81 * @since 6 82 */ 83 IMF_API int32_t Attach(sptr<OnTextChangedListener> &listener); 84 85 /** 86 * @brief Set listener and bind IMSA with given states and default attribute. 87 * 88 * This function is used to set listener and bind IMSA, 89 * default attribute is 'InputAttribute::PATTERN_TEXT'. Show soft keyboard when state is true. 90 * 91 * @param listener Indicates the listener in order to manipulate text. 92 * @param isShowKeyboard Indicates the state, if you want to show soft keyboard, please pass in true. 93 * @return Returns 0 for success, others for failure. 94 * @since 8 95 */ 96 IMF_API int32_t Attach(sptr<OnTextChangedListener> &listener, bool isShowKeyboard); 97 98 /** 99 * @brief Set listener and bind IMSA with given states and attribute. 100 * 101 * This function is used to set listener and bind IMSA. 102 * Show soft keyboard when state is true, and customized attribute. 103 * 104 * @param listener Indicates the listener in order to manipulate text. 105 * @param isShowKeyboard Indicates the state, if you want to show soft keyboard, please pass in true. 106 * @param attribute Indicates the attribute, such as input pattern, enter eyType, input option. 107 * @return Returns 0 for success, others for failure. 108 * @since 8 109 */ 110 IMF_API int32_t Attach(sptr<OnTextChangedListener> &listener, bool isShowKeyboard, const InputAttribute &attribute); 111 112 /** 113 * @brief Set listener and bind IMSA with given states and textConfig. 114 * 115 * This function is used to set listener and bind IMSA. 116 * Show soft keyboard when state is true, and customized attribute. 117 * 118 * @param listener Indicates the listener in order to manipulate text. 119 * @param isShowKeyboard Indicates the state, if you want to show soft keyboard, please pass in true. 120 * @param textConfig Indicates the textConfig, such as input attribute, cursorInfo, range of text selection, 121 * windowId. 122 * @return Returns 0 for success, others for failure. 123 * @since 10 124 */ 125 IMF_API int32_t Attach(sptr<OnTextChangedListener> &listener, bool isShowKeyboard, const TextConfig &textConfig); 126 127 /** 128 * @brief Show soft keyboard. 129 * 130 * This function is used to show soft keyboard of current client. 131 * 132 * @return Returns 0 for success, others for failure. 133 * @since 6 134 */ 135 IMF_API int32_t ShowTextInput(); 136 137 /** 138 * @brief Hide soft keyboard. 139 * 140 * This function is used to hide soft keyboard of current client, and keep binding. 141 * 142 * @return Returns 0 for success, others for failure. 143 * @since 6 144 */ 145 IMF_API int32_t HideTextInput(); 146 147 /** 148 * @brief Hide current input method, clear text listener and unbind IMSA. 149 * 150 * This function is used to stop input, whick will set listener to nullptr, 151 * hide current soft keyboard and unbind IMSA. 152 * 153 * @return Returns 0 for success, others for failure. 154 * @since 6 155 */ 156 IMF_API int32_t Close(); 157 158 /** 159 * @brief A callback function when the cursor changes. 160 * 161 * This function is the callback when the cursor changes. 162 * 163 * @param cursorInfo Indicates the information of current cursor changes. 164 * @return Returns 0 for success, others for failure. 165 * @since 6 166 */ 167 IMF_API int32_t OnCursorUpdate(CursorInfo cursorInfo); 168 169 /** 170 * @brief A callback function when the cursor changes. 171 * 172 * This function is the callback when the cursor changes. 173 * 174 * @param text Indicates the currently selected text. 175 * @param start Indicates the coordinates of the current start. 176 * @param end Indicates the coordinates of the current end. 177 * @return Returns 0 for success, others for failure. 178 * @since 6 179 */ 180 IMF_API int32_t OnSelectionChange(std::u16string text, int start, int end); 181 182 /** 183 * @brief Changing the configuration of soft keyboard. 184 * 185 * This function is used to change the configuration of soft keyboard. 186 * 187 * @param info Indicates the current configuration. 188 * @return Returns 0 for success, others for failure. 189 * @since 6 190 */ 191 IMF_API int32_t OnConfigurationChange(Configuration info); 192 193 /** 194 * @brief Set InputMethodSettingListener listener. 195 * 196 * This function is used to set InputMethodSettingListener listener to facilitate listening input method changes. 197 * 198 * @param listener Indicates the listener to be set. 199 * @since 6 200 */ 201 IMF_API void SetSettingListener(std::shared_ptr<InputMethodSettingListener> listener); 202 IMF_API int32_t UpdateListenEventFlag(const std::string &type, bool isOn); 203 IMF_API void SetControllerListener(std::shared_ptr<ControllerListener> controllerListener); 204 205 /** 206 * @brief Dispatch keyboard event. 207 * 208 * This function is used to Dispatch events of keyboard. 209 * 210 * @param keyEvent Indicates the events keyboard. 211 * @return Returns true for success otherwise for failure. 212 * @since 6 213 */ 214 IMF_API bool DispatchKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent); 215 216 /** 217 * @brief List input methods. 218 * 219 * This function is used to list all of input methods. 220 * 221 * @param props Indicates the input methods that will be listed. 222 * @return Returns 0 for success, others for failure. 223 * @since 6 224 */ 225 IMF_API int32_t ListInputMethod(std::vector<Property> &props); 226 227 /** 228 * @brief List input methods. 229 * 230 * This function is used to list enabled or disabled input methods. 231 * 232 * @param props Indicates the input methods that will be listed. 233 * @param enable Indicates the state of input method. 234 * @return Returns 0 for success, others for failure. 235 * @since 6 236 */ 237 IMF_API int32_t ListInputMethod(bool enable, std::vector<Property> &props); 238 239 /** 240 * @brief List input method subtypes. 241 * 242 * This function is used to list specified input method subtypes. 243 * 244 * @param property Indicates the specified input method property. 245 * @param subProperties Indicates the subtypes of specified input method that will be listed. 246 * @return Returns 0 for success, others for failure. 247 * @since 6 248 */ 249 IMF_API int32_t ListInputMethodSubtype(const Property &property, std::vector<SubProperty> &subProperties); 250 251 /** 252 * @brief List current input method subtypes. 253 * 254 * This function is used to list current input method subtypes. 255 * 256 * @param subProperties Indicates the subtypes of current input method that will be listed. 257 * @return Returns 0 for success, others for failure. 258 * @since 6 259 */ 260 IMF_API int32_t ListCurrentInputMethodSubtype(std::vector<SubProperty> &subProperties); 261 262 /** 263 * @brief Get enter key type. 264 * 265 * This function is used to get enter key type of current client. 266 * 267 * @param keyType Indicates the enter key type of current client that will be obtained, such as SEND, SEARCH... 268 * @return Returns 0 for success, others for failure. 269 * @since 6 270 */ 271 IMF_API int32_t GetEnterKeyType(int32_t &keyType); 272 273 /** 274 * @brief Get input pattern. 275 * 276 * This function is used to get text input type of current client. 277 * 278 * @param inputPattern Indicates the text input type of current client that will be obtained, such as TEXT, URL... 279 * @return Returns 0 for success, others for failure. 280 * @since 6 281 */ 282 IMF_API int32_t GetInputPattern(int32_t &inputPattern); 283 284 /** 285 * @brief Get text config. 286 * 287 * This function is used to get text config of current client. 288 * 289 * @param textConfig Indicates the text config of current client that will be obtained. 290 * @return Returns 0 for success, others for failure. 291 * @since 10 292 */ 293 IMF_API int32_t GetTextConfig(TextTotalConfig &config); 294 295 /** 296 * @brief Get current input method property. 297 * 298 * This function is used to get current input method property. 299 * 300 * @return The property of current input method. 301 * @since 6 302 */ 303 IMF_API std::shared_ptr<Property> GetCurrentInputMethod(); 304 305 /** 306 * @brief Get current input method subtypes. 307 * 308 * This function is used to get current input method's current subtype. 309 * 310 * @return The subtypes of current input method. 311 * @since 6 312 */ 313 IMF_API std::shared_ptr<SubProperty> GetCurrentInputMethodSubtype(); 314 315 /** 316 * @brief Set calling window id. 317 * 318 * This function is used to set calling window id to input method. 319 * 320 * @param windowId Indicates the window id. 321 * @return Returns 0 for success, others for failure. 322 * @since 6 323 */ 324 IMF_API int32_t SetCallingWindow(uint32_t windowId); 325 326 /** 327 * @brief Switch input method or subtype. 328 * 329 * This function is used to switch input method or subtype. 330 * 331 * @param name Indicates the id of target input method. 332 * @param subName Optional parameter. Indicates the subtype of target input method. 333 * @return Returns 0 for success, others for failure. 334 * @since 8 335 */ 336 IMF_API int32_t SwitchInputMethod(const std::string &name, const std::string &subName = ""); 337 338 /** 339 * @brief Show soft keyboard. 340 * 341 * This function is used to show soft keyboard of current client. 342 * 343 * @return Returns 0 for success, others for failure. 344 * @since 6 345 */ 346 IMF_API int32_t ShowSoftKeyboard(); 347 348 /** 349 * @brief Hide soft keyboard. 350 * 351 * This function is used to hide soft keyboard of current client, and keep binding. 352 * 353 * @return Returns 0 for success, others for failure. 354 * @since 6 355 */ 356 IMF_API int32_t HideSoftKeyboard(); 357 358 /** 359 * @brief Stop current input session. 360 * 361 * This function is used to stop current input session. 362 * 363 * @return Returns 0 for success, others for failure. 364 * @since 6 365 */ 366 IMF_API int32_t StopInputSession(); 367 368 /** 369 * @brief Show input method setting extension dialog. 370 * 371 * This function is used to show input method setting extension dialog. 372 * 373 * @return Returns 0 for success, others for failure. 374 * @since 8 375 */ 376 IMF_API int32_t ShowOptionalInputMethod(); 377 378 // Deprecated innerkits with no permission check, kept for compatibility 379 380 /** 381 * @brief Show soft keyboard. 382 * 383 * This function is used to show soft keyboard of current client. 384 * 385 * @return Returns 0 for success, others for failure. 386 * @deprecated since 9 387 * @since 6 388 */ 389 IMF_API int32_t ShowCurrentInput(); 390 391 /** 392 * @brief Hide soft keyboard. 393 * 394 * This function is used to hide soft keyboard of current client, and keep binding. 395 * 396 * @return Returns 0 for success, others for failure. 397 * @deprecated since 9 398 * @since 6 399 */ 400 IMF_API int32_t HideCurrentInput(); 401 402 /** 403 * @brief Show input method setting extension dialog. 404 * 405 * This function is used to show input method setting extension dialog. 406 * 407 * @return Returns 0 for success, others for failure. 408 * @deprecated since 9 409 * @since 6 410 */ 411 IMF_API int32_t DisplayOptionalInputMethod(); 412 413 /** 414 * @brief Get attach status. 415 * 416 * This function is used to get status of attach. 417 * 418 * @return Returns true for attached otherwise for detached. 419 * @since 10 420 */ 421 IMF_API bool WasAttached(); 422 423 /** 424 * @brief Set agent which will be used to communicate with IMA. 425 * 426 * This function is used to Set agent. 427 * 428 * @since 10 429 */ 430 IMF_API void OnInputReady(sptr<IRemoteObject> agentObject); 431 432 private: 433 InputMethodController(); 434 ~InputMethodController(); 435 436 int32_t Initialize(); 437 sptr<IInputMethodSystemAbility> GetSystemAbilityProxy(); 438 int32_t PrepareInput(InputClientInfo &inputClientInfo); 439 int32_t StartInput(sptr<IInputClient> &client, bool isShowKeyboard, bool attachFlag); 440 int32_t StopInput(sptr<IInputClient> &client); 441 int32_t ReleaseInput(sptr<IInputClient> &client); 442 void OnSwitchInput(const Property &property, const SubProperty &subProperty); 443 void OnPanelStatusChange(const InputWindowStatus &status, const std::vector<InputWindowInfo> &windowInfo); 444 void WorkThread(); 445 void QuitWorkThread(); 446 int32_t ListInputMethodCommon(InputMethodStatus status, std::vector<Property> &props); 447 void ClearEditorCache(); 448 void OnSelectByRange(int32_t start, int32_t end); 449 void OnSelectByMovement(int32_t direction, int32_t cursorMoveSkip); 450 void HandleExtendAction(int32_t action); 451 void OnRemoteSaDied(const wptr<IRemoteObject> &object); 452 void RestoreListenInfoInSaDied(); 453 void RestoreAttachInfoInSaDied(); 454 int32_t RestoreListenEventFlag(); 455 void UpdateNativeEventFlag(EventType eventType, bool isOn); 456 void SaveTextConfig(const TextConfig &textConfig); 457 void GetText(const Message *msg); 458 void GetTextIndexAtCursor(const Message *msg); 459 sptr<OnTextChangedListener> GetTextListener(); 460 void SetTextListener(sptr<OnTextChangedListener> listener); 461 462 std::shared_ptr<InputMethodSettingListener> settingListener_; 463 std::shared_ptr<ControllerListener> controllerListener_; 464 std::mutex abilityLock_; 465 sptr<IInputMethodSystemAbility> abilityManager_ = nullptr; 466 sptr<InputDeathRecipient> deathRecipient_; 467 std::mutex agentLock_; 468 sptr<IRemoteObject> agentObject_ = nullptr; 469 std::shared_ptr<IInputMethodAgent> agent_ = nullptr; 470 std::mutex textListenerLock_; 471 sptr<OnTextChangedListener> textListener_ = nullptr; 472 std::atomic_bool isDiedAttached_{ false }; 473 474 std::mutex cursorInfoMutex_; 475 CursorInfo cursorInfo_; 476 477 std::mutex editorContentLock_; 478 std::u16string textString_; 479 int selectOldBegin_ = 0; 480 int selectOldEnd_ = 0; 481 int selectNewBegin_ = 0; 482 int selectNewEnd_ = 0; 483 484 static std::mutex instanceLock_; 485 static sptr<InputMethodController> instance_; 486 static std::shared_ptr<AppExecFwk::EventHandler> handler_; 487 std::thread workThreadHandler; 488 MessageHandler *msgHandler_; 489 bool stop_; 490 491 std::atomic_bool isEditable_{ false }; 492 std::atomic_bool isBound_{ false }; 493 494 std::recursive_mutex clientInfoLock_; 495 InputClientInfo clientInfo_; 496 497 static constexpr int CURSOR_DIRECTION_BASE_VALUE = 2011; 498 std::atomic_bool isDiedRestoreListen_{ false }; 499 500 std::mutex textConfigLock_; 501 TextConfig textConfig_; 502 }; 503 } // namespace MiscServices 504 } // namespace OHOS 505 #endif // FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_INPUT_METHOD_CONTROLLER_H 506