diff --git a/README.md b/README.md index 9e01cbfaab10405f46413e01c6111295aadf6f27..1f57d1434dd33bcb46d1b68d821059d239814097 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,50 @@ # miscservices_inputmethod -#### 介绍 -输入法框架 +####Introduction +Input Method Framework, is used to connect the application and input method. the application can input text through the input method -#### 安装教程 +####Warehouse path -1. 随版本烧录即可带上 +/base/miscservices/inputmethod -#### 使用说明 +####Introduction to framework code -1. 在编辑属性的控件中进行点击操作,即可通过输入法框架调起默认输入法应用 -2. 通过输入法应用可以进行打字,并上屏输入字符到应用客户端 +The input method framework currently has four modules, as follows: -#### 参与贡献 +1. Application client -1. Fork 本仓库 -2. 新建 Feat_master 分支 -3. 提交代码 -4. 新建 Pull Request +Path: /base/miscservices/inputmethod/frameworks/inputmethod_controller +Function: realize the service delivery of application and input method framework, including the binding between application and input method service, application display and hiding request for input method, etc + +2. Input method client + +Path: /base/miscservices/inputmethod/frameworks/inputmethod_ability + +Function: the intermediate bridge between input method framework service and input method delivery, including monitoring the current status of input method, etc + +3. Input method service + +Path: /base/miscservices/inputmethod/services + +Function: as the core of the input method framework, the main processing logic of the input method is completed here + +4. Input method JS interface + +Path: /base/miscservices/inputmethod/interfaces/kits/JS + +Function: the temporarily exposed JS interface is mainly reserved for calling input methods + +####Main functions supported by the framework + +1. Click in the edit attribute control to invoke the default input method application through the input method framework + +2. Typing can be carried out through the input method application, and characters can be input to the application client on the screen + +####Participation contribution + +1. Fork warehouse +2. Submission code +3. Create a new pull request +4. Commit is complete diff --git a/README_zh.md b/README_zh.md new file mode 100644 index 0000000000000000000000000000000000000000..0406b4d9453f8ba0810a4b36235f90b2d4cc23be --- /dev/null +++ b/README_zh.md @@ -0,0 +1,48 @@ +# miscservices_inputmethod + +#### 介绍 +输入法框架,主要作用是拉通应用和输入法,保证应用可以通过输入法进行文本输入 + +#### 仓路径 +/base/miscservices/inputmethod + +#### 框架代码介绍 +输入法框架目前有四大模块,具体如下: + +1. 应用客户端 + +路径:/base/miscservices/inputmethod/frameworks/inputmethod_controller + +作用:实现应用和输入法框架服务交付,包括应用与输入法服务的绑定、应用对输入法的显示和隐藏请求等等 + +2. 输入法客户端 + +路径:/base/miscservices/inputmethod/frameworks/inputmethod_ability + +作用:实现输入法框架服务与输入法交付的中间桥梁,包括监听输入法当前的状态等等 + +3. 输入法服务 + +路径:/base/miscservices/inputmethod/services + +作用:作为输入法框架的核心,输入法的主要处理逻辑都是在这里完成 + +4. 输入法Js接口 + +路径:/base/miscservices/inputmethod/interfaces/kits/js + +作用:暂时对外暴露的js接口,主要是留给输入法进行调用使用的 + +#### 框架主要支持功能 + +1.在编辑属性的控件中进行点击操作,即可通过输入法框架调起默认输入法应用 + +2.通过输入法应用可以进行打字,并上屏输入字符到应用客户端 + +#### 参与贡献 + +1. Fork 本仓库 +2. 提交代码 +3. 新建 Pull Request +4. commit完成即可 + diff --git a/frameworks/inputmethod_controller/include/input_method_controller.h b/frameworks/inputmethod_controller/include/input_method_controller.h index 474c7de45d44f0f87059738f55b419ef67f046e9..c21b54ff867a4d44881764ffbfd24e65199f9a13 100644 --- a/frameworks/inputmethod_controller/include/input_method_controller.h +++ b/frameworks/inputmethod_controller/include/input_method_controller.h @@ -71,7 +71,7 @@ namespace MiscServices { sptr mImms; sptr deathRecipient_; sptr mAgent; - sptr textListener; + OnTextChangedListener* textListener; InputAttribute mAttribute; static std::mutex instanceLock_; diff --git a/frameworks/inputmethod_controller/src/input_method_controller.cpp b/frameworks/inputmethod_controller/src/input_method_controller.cpp index 153bcd6e0f0ba92d1c7fac80a71fdf37a36f6334..29a476f5db338c942a8bc33548ac71f878b6be4a 100644 --- a/frameworks/inputmethod_controller/src/input_method_controller.cpp +++ b/frameworks/inputmethod_controller/src/input_method_controller.cpp @@ -139,6 +139,7 @@ using namespace MessageID; case MSG_ID_EXIT_SERVICE:{ MessageParcel* data = msg->msgContent_; int32_t ret = data->ReadInt32(); + textListener = nullptr; IMSA_HILOGI("MSG_ID_EXIT_SERVICE : %{public}d", ret); break; } diff --git a/services/include/peruser_session.h b/services/include/peruser_session.h index e8e3f0be6b2bebe6d1c958778c67639b18b808d6..64e9daa2f99c7c8a2e9eecd025b22927ffe2c505 100644 --- a/services/include/peruser_session.h +++ b/services/include/peruser_session.h @@ -41,156 +41,149 @@ #include "input_method_ability.h" namespace OHOS { - namespace MiscServices { - - - class RemoteObjectDeathRecipient : public IRemoteObject::DeathRecipient { - public: - RemoteObjectDeathRecipient(int userId, int msgId); - ~RemoteObjectDeathRecipient(); - void OnRemoteDied(const wptr& who) override; - private : - int userId_; //!< the id of the user to whom the object is linking - int msgId_; //!< the message id can be MessageID::MSG_ID_CLIENT_DIED and MessageID::MSG_ID_IMS_DIED - }; - - /*! \class ClientInfo - \brief The class defines the details of an input client. - */ - class ClientInfo { - public: - int pid; //!< the process id of the process in which the input client is running - int uid; //!< the uid of the process in which the input client is running - int userId; //!< the user if of the user under which the input client is running - int displayId; //!< the display id on which the input client is showing - sptr client; //!< the remote object handler for the service to callback to the input client - sptr channel; //!< the remote object handler for input method service callback to input client - InputAttribute attribute; //!< the input attribute of the input client - - ClientInfo(int pid, int uid, int userId, int displayId, const sptr& client, - const sptr& channel, const InputAttribute& attribute) - { - this->pid = pid; - this->uid = uid; - this->userId = userId; - this->displayId = displayId; - this->client = client; - this->channel = channel; - this->attribute = attribute; - }; - - ~ClientInfo() - { - this->client = nullptr; - this->channel = nullptr; - }; - }; - - /*! \class PerUserSession - \brief The class provides session management in input method management service - - This class manages the sessions between input clients and input method engines for each unlocked user. - */ - class PerUserSession { - enum { - DEFAULT_IME = 0, //!< index for default input method service - SECURITY_IME = 1, //!< index for security input method service - MAX_IME = 2, //!< the maximum count of ims started for a user - }; - - public: - explicit PerUserSession(int userId); - ~PerUserSession(); - - void SetCurrentIme(InputMethodProperty* ime); - void SetSecurityIme(InputMethodProperty* ime); - void SetInputMethodSetting(InputMethodSetting* setting); - void ResetIme(InputMethodProperty* defaultIme, InputMethodProperty* securityIme); - void OnPackageRemoved(const std::u16string& packageName); - - int GetDisplayMode(); - int GetKeyboardWindowHeight(int *retHeight); - KeyboardType* GetCurrentKeyboardType(); - - int OnSettingChanged(const std::u16string& key, const std::u16string& value); - void Dump(int fd); - void CreateWorkThread(MessageHandler& handler); - void JoinWorkThread(); - void SetInputMethodAbility(sptr &inputMethodAbility); - static void BindInputAbility(); - private: - int userId_; //!< the id of the user to whom the object is linking - int userState; //!< the state of the user to whom the object is linking - int displayId; //!< the id of the display screen on which the user is - int currentIndex; - std::map, ClientInfo*> mapClients; //!< a map to manage the input clients connected to the service - /*!< \n key is the remote IInputClient handler - \n value is an object of an ClientInfo */ - - InputMethodProperty* currentIme[MAX_IME]; //!< 0 - the default ime. 1 - security ime - /*!< \n The pointers are referred to the objects in the PerUserSetting */ - - InputControlChannelStub* localControlChannel[MAX_IME]; //!< inputControlChannel object used by the local process - sptr inputControlChannel[MAX_IME]; //!< channels between the service and input method service - sptr imsCore[MAX_IME]; //!< the remote handlers of input method service - sptr inputMethodToken[MAX_IME]; //!< the window token of keyboard - int currentKbdIndex[MAX_IME]; //!< current keyboard index - int lastImeIndex; //!< The last ime which showed keyboard - InputMethodSetting* inputMethodSetting; //!< The pointer referred to the object in PerUserSetting - int currentDisplayMode; //!< the display mode of the current keyboard - - sptr imsAgent; - InputChannel* imsChannel; //!< the write channel created by input method service - sptr currentClient; //!< the current input client - sptr needReshowClient; //!< the input client for which keyboard need to re-show - - sptr clientDeathRecipient; //!< remote object death monitor for input client - sptr imsDeathRecipient; //!< remote object death monitor for input method service - MessageHandler* msgHandler = nullptr; //!< message handler working with Work Thread - std::thread workThreadHandler; //!< work thread handler - std::mutex mtx; //!< mutex to lock the operations among multi work threads - sptr connCallback; - sptr inputMethodAbility_; - - PerUserSession(const PerUserSession&); - PerUserSession& operator= (const PerUserSession&); - PerUserSession(const PerUserSession&&); - PerUserSession& operator= (const PerUserSession&&); - int IncreaseOrResetImeError(bool resetFlag, int imeIndex); - KeyboardType* GetKeyboardType(int imeIndex, int typeIndex); - void ResetCurrentKeyboardType(int imeIndex); - int OnCurrentKeyboardTypeChanged(int index, const std::u16string& value); - void DumpClientInfo(int fd, const ClientInfo& clientInfo); - void DumpCurrentSession(int fd); - void CopyInputMethodService(int imeIndex); - ClientInfo* GetClientInfo(const sptr& inputClient); - void WorkThread(); - void OnPrepareInput(Message* msg); - void OnReleaseInput(Message* msg); - void OnStartInput(Message* msg); - void OnStopInput(Message* msg); - void OnClientDied(const wptr& who); - void OnImsDied(const wptr& who); - void OnHideKeyboardSelf(int flags); - void OnAdvanceToNext(); - void OnSetDisplayMode(int mode); - void OnRestartIms(int index, const std::u16string& imeId); - void OnUserLocked(); - int AddClient(int pid, int uid, int displayId, const sptr& inputClient, - const sptr& channel, - const InputAttribute& attribute); - int RemoveClient(const sptr& inputClient, int *retClientNum); - int StartInputMethod(int index); - int StopInputMethod(int index); - int ShowKeyboard(const sptr& inputClient); - int HideKeyboard(const sptr& inputClient); - void SetDisplayId(int displayId); - int GetImeIndex(const sptr& inputClient); - static sptr GetAbilityManagerService(); - void onSetInputMethodCore(Message* msg); - - }; - } +namespace MiscServices { + class RemoteObjectDeathRecipient : public IRemoteObject::DeathRecipient { + public: + RemoteObjectDeathRecipient(int userId, int msgId); + ~RemoteObjectDeathRecipient(); + void OnRemoteDied(const wptr& who) override; + private : + int userId_; //!< the id of the user to whom the object is linking + int msgId_; //!< the message id can be MessageID::MSG_ID_CLIENT_DIED and MessageID::MSG_ID_IMS_DIED + }; + + /*! \class ClientInfo + \brief The class defines the details of an input client. + */ + class ClientInfo { + public: + int pid; //!< the process id of the process in which the input client is running + int uid; //!< the uid of the process in which the input client is running + int userId; //!< the user if of the user under which the input client is running + int displayId; //!< the display id on which the input client is showing + sptr client; //!< the remote object handler for the service to callback to the input client + sptr channel; //!< the remote object handler for input method service callback to input client + InputAttribute attribute; //!< the input attribute of the input client + + ClientInfo(int pid, int uid, int userId, int displayId, const sptr& client, + const sptr& channel, const InputAttribute& attribute) + { + this->pid = pid; + this->uid = uid; + this->userId = userId; + this->displayId = displayId; + this->client = client; + this->channel = channel; + this->attribute = attribute; + }; + + ~ClientInfo() + { + this->client = nullptr; + this->channel = nullptr; + }; + }; + + /*! \class PerUserSession + \brief The class provides session management in input method management service + + This class manages the sessions between input clients and input method engines for each unlocked user. + */ + class PerUserSession { + enum { + DEFAULT_IME = 0, //!< index for default input method service + SECURITY_IME = 1, //!< index for security input method service + MAX_IME = 2, //!< the maximum count of ims started for a user + }; + + public: + explicit PerUserSession(int userId); + ~PerUserSession(); + + void SetCurrentIme(InputMethodProperty* ime); + void SetSecurityIme(InputMethodProperty* ime); + void SetInputMethodSetting(InputMethodSetting* setting); + void ResetIme(InputMethodProperty* defaultIme, InputMethodProperty* securityIme); + void OnPackageRemoved(const std::u16string& packageName); + + int GetDisplayMode(); + int GetKeyboardWindowHeight(int *retHeight); + KeyboardType* GetCurrentKeyboardType(); + + int OnSettingChanged(const std::u16string& key, const std::u16string& value); + void Dump(int fd); + void CreateWorkThread(MessageHandler& handler); + void JoinWorkThread(); + void SetInputMethodAbility(sptr &inputMethodAbility); + static void BindInputAbility(); + private: + int userId_; //!< the id of the user to whom the object is linking + int userState; //!< the state of the user to whom the object is linking + int displayId; //!< the id of the display screen on which the user is + int currentIndex; + std::map, ClientInfo*> mapClients; //!< a map to manage the input clients connected to the service + + InputMethodProperty* currentIme[MAX_IME]; //!< 0 - the default ime. 1 - security ime + + InputControlChannelStub* localControlChannel[MAX_IME]; //!< inputControlChannel object used by the local process + sptr inputControlChannel[MAX_IME]; //!< channels between the service and input method service + sptr imsCore[MAX_IME]; //!< the remote handlers of input method service + sptr inputMethodToken[MAX_IME]; //!< the window token of keyboard + int currentKbdIndex[MAX_IME]; //!< current keyboard index + int lastImeIndex; //!< The last ime which showed keyboard + InputMethodSetting* inputMethodSetting; //!< The pointer referred to the object in PerUserSetting + int currentDisplayMode; //!< the display mode of the current keyboard + + sptr imsAgent; + InputChannel* imsChannel; //!< the write channel created by input method service + sptr currentClient; //!< the current input client + sptr needReshowClient; //!< the input client for which keyboard need to re-show + + sptr clientDeathRecipient; //!< remote object death monitor for input client + sptr imsDeathRecipient; //!< remote object death monitor for input method service + MessageHandler* msgHandler = nullptr; //!< message handler working with Work Thread + std::thread workThreadHandler; //!< work thread handler + std::mutex mtx; //!< mutex to lock the operations among multi work threads + sptr connCallback; + sptr inputMethodAbility_; + + PerUserSession(const PerUserSession&); + PerUserSession& operator= (const PerUserSession&); + PerUserSession(const PerUserSession&&); + PerUserSession& operator= (const PerUserSession&&); + int IncreaseOrResetImeError(bool resetFlag, int imeIndex); + KeyboardType* GetKeyboardType(int imeIndex, int typeIndex); + void ResetCurrentKeyboardType(int imeIndex); + int OnCurrentKeyboardTypeChanged(int index, const std::u16string& value); + void DumpClientInfo(int fd, const ClientInfo& clientInfo); + void DumpCurrentSession(int fd); + void CopyInputMethodService(int imeIndex); + ClientInfo* GetClientInfo(const sptr& inputClient); + void WorkThread(); + void OnPrepareInput(Message* msg); + void OnReleaseInput(Message* msg); + void OnStartInput(Message* msg); + void OnStopInput(Message* msg); + void OnClientDied(const wptr& who); + void OnImsDied(const wptr& who); + void OnHideKeyboardSelf(int flags); + void OnAdvanceToNext(); + void OnSetDisplayMode(int mode); + void OnRestartIms(int index, const std::u16string& imeId); + void OnUserLocked(); + int AddClient(int pid, int uid, int displayId, const sptr& inputClient, + const sptr& channel, + const InputAttribute& attribute); + int RemoveClient(const sptr& inputClient, int *retClientNum); + int StartInputMethod(int index); + int StopInputMethod(int index); + int ShowKeyboard(const sptr& inputClient); + int HideKeyboard(const sptr& inputClient); + void SetDisplayId(int displayId); + int GetImeIndex(const sptr& inputClient); + static sptr GetAbilityManagerService(); + void onSetInputMethodCore(Message* msg); + }; +} } - #endif // FM_IMMS_PROJECT_PERUSERSESSION_H diff --git a/services/src/peruser_session.cpp b/services/src/peruser_session.cpp index db7f4524dbc8da2942ccdace37c0aeb90871d0f4..8f200a609ae9a270a8a2dfe7726009c053a77965 100644 --- a/services/src/peruser_session.cpp +++ b/services/src/peruser_session.cpp @@ -115,639 +115,645 @@ namespace MiscServices { inputMethodAbility_ = inputMethodAbility; } - /*! Work thread for this user - */ - void PerUserSession::WorkThread() - { - if (msgHandler == nullptr) { - return ; - } - while(1){ - Message* msg = msgHandler->GetMessage(); - std::unique_lock lock(mtx); - switch(msg->msgId_) { - case MSG_ID_USER_LOCK: - case MSG_ID_EXIT_SERVICE: { - OnUserLocked(); - delete msg; - return; - } - case MSG_ID_PREPARE_INPUT: { - OnPrepareInput(msg); - break; - } - case MSG_ID_RELEASE_INPUT: { - OnReleaseInput(msg); - break; - } - case MSG_ID_START_INPUT: { - OnStartInput(msg); - break; - } - case MSG_ID_STOP_INPUT: { - OnStopInput(msg); - break; - } - case MSG_ID_SET_INPUT_METHOD_CORE:{ - onSetInputMethodCore(msg); - break; - } - case MSG_ID_CLIENT_DIED: { - wptr who = msg->msgContent_->ReadRemoteObject(); - OnClientDied(who); - break; - } - case MSG_ID_IMS_DIED: { - wptr who = msg->msgContent_->ReadRemoteObject(); - OnImsDied(who); - break; - } - case MSG_ID_HIDE_KEYBOARD_SELF: { - int flag = msg->msgContent_->ReadInt32(); - OnHideKeyboardSelf(flag); - break; - } - case MSG_ID_ADVANCE_TO_NEXT: { - OnAdvanceToNext(); - break; - } - case MSG_ID_SET_DISPLAY_MODE: { - int mode = msg->msgContent_->ReadInt32(); - OnSetDisplayMode(mode); - break; - } - case MSG_ID_RESTART_IMS: { - int index = msg->msgContent_->ReadInt32(); - std::u16string imeId = msg->msgContent_->ReadString16(); - OnRestartIms(index, imeId); - break; - } - default: { - break; - } + /*! Work thread for this user + */ + void PerUserSession::WorkThread() + { + if (msgHandler == nullptr) { + return ; + } + while(1){ + Message* msg = msgHandler->GetMessage(); + std::unique_lock lock(mtx); + switch(msg->msgId_) { + case MSG_ID_USER_LOCK: + case MSG_ID_EXIT_SERVICE: { + OnUserLocked(); + delete msg; + return; + } + case MSG_ID_PREPARE_INPUT: { + OnPrepareInput(msg); + break; + } + case MSG_ID_RELEASE_INPUT: { + OnReleaseInput(msg); + break; + } + case MSG_ID_START_INPUT: { + OnStartInput(msg); + break; + } + case MSG_ID_STOP_INPUT: { + OnStopInput(msg); + break; + } + case MSG_ID_SET_INPUT_METHOD_CORE:{ + onSetInputMethodCore(msg); + break; + } + case MSG_ID_CLIENT_DIED: { + wptr who = msg->msgContent_->ReadRemoteObject(); + OnClientDied(who); + break; + } + case MSG_ID_IMS_DIED: { + wptr who = msg->msgContent_->ReadRemoteObject(); + OnImsDied(who); + break; + } + case MSG_ID_HIDE_KEYBOARD_SELF: { + int flag = msg->msgContent_->ReadInt32(); + OnHideKeyboardSelf(flag); + break; + } + case MSG_ID_ADVANCE_TO_NEXT: { + OnAdvanceToNext(); + break; + } + case MSG_ID_SET_DISPLAY_MODE: { + int mode = msg->msgContent_->ReadInt32(); + OnSetDisplayMode(mode); + break; + } + case MSG_ID_RESTART_IMS: { + int index = msg->msgContent_->ReadInt32(); + std::u16string imeId = msg->msgContent_->ReadString16(); + OnRestartIms(index, imeId); + break; + } + default: { + break; } - delete msg; } + delete msg; } + } - /*! Set display Id - \param displayId the Id of display screen on which the input method keyboard show. - */ - void PerUserSession::SetDisplayId(int displayId) - { - this->displayId = displayId; - } - - /*! Set the current input method engine - \param ime the current (default) IME pointer referred to the instance in PerUserSetting. - */ - void PerUserSession::SetCurrentIme(InputMethodProperty* ime) - { - currentIme[DEFAULT_IME] = ime; - userState = UserState::USER_STATE_UNLOCKED; - } + /*! Set display Id + \param displayId the Id of display screen on which the input method keyboard show. + */ + void PerUserSession::SetDisplayId(int displayId) + { + this->displayId = displayId; + } - /*! Set the system security input method engine - \param ime system security IME pointer referred to the instance in PerUserSetting. - */ - void PerUserSession::SetSecurityIme(InputMethodProperty* ime) - { - currentIme[SECURITY_IME] = ime; - } + /*! Set the current input method engine + \param ime the current (default) IME pointer referred to the instance in PerUserSetting. + */ + void PerUserSession::SetCurrentIme(InputMethodProperty* ime) + { + currentIme[DEFAULT_IME] = ime; + userState = UserState::USER_STATE_UNLOCKED; + } - /*! Set the input method setting data - \param setting InputMethodSetting pointer referred to the instance in PerUserSetting. - */ - void PerUserSession::SetInputMethodSetting(InputMethodSetting* setting) - { - inputMethodSetting = setting; - } + /*! Set the system security input method engine + \param ime system security IME pointer referred to the instance in PerUserSetting. + */ + void PerUserSession::SetSecurityIme(InputMethodProperty* ime) + { + currentIme[SECURITY_IME] = ime; + } - /*! Reset input method engine - \param defaultIme default ime pointer referred to the instance in PerUserSetting - \param security security ime pointer referred to the instance in PerUserSetting - \n Two input method engines can be running at the same time for one user. - \n One is the default ime, another is security ime - */ - void PerUserSession::ResetIme(InputMethodProperty* defaultIme, InputMethodProperty* securityIme) - { - IMSA_HILOGI("PerUserSession::ResetIme"); - std::unique_lock lock(mtx); - InputMethodProperty* ime[] = {defaultIme, securityIme}; - for(int i=0; i<2; i++) { - if (currentIme[i] == ime[i] && ime[i] != nullptr) { - continue; - } - if (imsCore[i]) { - StopInputMethod(i); - } - IncreaseOrResetImeError(true, i); - currentIme[i] = ime[i]; - if (currentIme[i]==nullptr) { - if (needReshowClient && GetImeIndex(needReshowClient)==i) { - needReshowClient = nullptr; - } - continue; - } + /*! Set the input method setting data + \param setting InputMethodSetting pointer referred to the instance in PerUserSetting. + */ + void PerUserSession::SetInputMethodSetting(InputMethodSetting* setting) + { + inputMethodSetting = setting; + } - std::map, ClientInfo*>::const_iterator it; - bool flag = false; - for(it=mapClients.cbegin(); it!=mapClients.cend(); ++it) { - if ((i == DEFAULT_IME && it->second->attribute.GetSecurityFlag() == false) || - (i == SECURITY_IME && it->second->attribute.GetSecurityFlag() == true)) { - flag = true; - break; - } - } - if (flag) { - int ret = StartInputMethod(i); - if (needReshowClient && GetImeIndex(needReshowClient)==i) { - if (ret==ErrorCode::NO_ERROR) { - ShowKeyboard(needReshowClient); - } - needReshowClient = nullptr; - } + /*! Reset input method engine + \param defaultIme default ime pointer referred to the instance in PerUserSetting + \param security security ime pointer referred to the instance in PerUserSetting + \n Two input method engines can be running at the same time for one user. + \n One is the default ime, another is security ime + */ + void PerUserSession::ResetIme(InputMethodProperty* defaultIme, InputMethodProperty* securityIme) + { + IMSA_HILOGI("PerUserSession::ResetIme"); + std::unique_lock lock(mtx); + InputMethodProperty* ime[] = {defaultIme, securityIme}; + for(int i=0; i<2; i++) { + if (currentIme[i] == ime[i] && ime[i] != nullptr) { + continue; + } + if (imsCore[i]) { + StopInputMethod(i); + } + IncreaseOrResetImeError(true, i); + currentIme[i] = ime[i]; + if (currentIme[i]==nullptr) { + if (needReshowClient && GetImeIndex(needReshowClient)==i) { + needReshowClient = nullptr; } + continue; } - } - /*! Called when a package is removed - \param packageName the name of package removed - */ - void PerUserSession::OnPackageRemoved(const std::u16string& packageName) - { - IMSA_HILOGI("PerUserSession::OnPackageRemoved"); - InputMethodSetting tmpSetting; + std::map, ClientInfo*>::const_iterator it; bool flag = false; - std::unique_lock lock(mtx); - for(int i=0; imPackageName == packageName) { - if (currentClient && GetImeIndex(currentClient)==i) { - needReshowClient = currentClient; - HideKeyboard(currentClient); - } - StopInputMethod(i); - currentIme[i] = nullptr; - if (i==DEFAULT_IME) { - tmpSetting.SetCurrentKeyboardType(-1); - inputMethodSetting->SetCurrentKeyboardType(-1); - } else if (i==SECURITY_IME) { - tmpSetting.SetCurrentSysKeyboardType(-1); - inputMethodSetting->SetCurrentSysKeyboardType(-1); - } - currentKbdIndex[i] = 0; + for(it=mapClients.cbegin(); it!=mapClients.cend(); ++it) { + if ((i == DEFAULT_IME && it->second->attribute.GetSecurityFlag() == false) || + (i == SECURITY_IME && it->second->attribute.GetSecurityFlag() == true)) { flag = true; + break; } } if (flag) { - Platform::Instance()->SetInputMethodSetting(userId_, tmpSetting); + int ret = StartInputMethod(i); + if (needReshowClient && GetImeIndex(needReshowClient)==i) { + if (ret==ErrorCode::NO_ERROR) { + ShowKeyboard(needReshowClient); + } + needReshowClient = nullptr; + } } - } + } - /*! Add an input client - \param pid the process pid of the input client - \param uid the uid of the the input client - \param displayId the display id of the input client - \param inputClient the remote object handler of the input client - \param channel the remote InputDataChannel object handler for the input client. - \n It will be transferred to input method service - \param attribute the input attribute of the input client. - \return \li ErrorCode::NO_ERROR no error - \return \li ErrorCode::ERROR_CLIENT_DUPLICATED client is duplicated - */ - int PerUserSession::AddClient(int pid, int uid, int displayId, const sptr& inputClient, - const sptr& channel, - const InputAttribute& attribute) - { - IMSA_HILOGI("PerUserSession::AddClient"); - ClientInfo* clientInfo = GetClientInfo(inputClient); - if (clientInfo != nullptr) { - IMSA_HILOGE("PerUserSession::AddClient clientInfo is not nullptr"); - return ErrorCode::ERROR_CLIENT_DUPLICATED; + /*! Called when a package is removed + \param packageName the name of package removed + */ + void PerUserSession::OnPackageRemoved(const std::u16string& packageName) + { + IMSA_HILOGI("PerUserSession::OnPackageRemoved"); + InputMethodSetting tmpSetting; + bool flag = false; + std::unique_lock lock(mtx); + for(int i=0; imPackageName == packageName) { + if (currentClient && GetImeIndex(currentClient)==i) { + needReshowClient = currentClient; + HideKeyboard(currentClient); + } + StopInputMethod(i); + currentIme[i] = nullptr; + if (i==DEFAULT_IME) { + tmpSetting.SetCurrentKeyboardType(-1); + inputMethodSetting->SetCurrentKeyboardType(-1); + } else if (i==SECURITY_IME) { + tmpSetting.SetCurrentSysKeyboardType(-1); + inputMethodSetting->SetCurrentSysKeyboardType(-1); + } + currentKbdIndex[i] = 0; + flag = true; } + } + if (flag) { + Platform::Instance()->SetInputMethodSetting(userId_, tmpSetting); + } + } - sptr obj = inputClient->AsObject(); - if (obj == nullptr) { - IMSA_HILOGE("PerUserSession::AddClient inputClient AsObject is nullptr"); - return ErrorCode::ERROR_REMOTE_CLIENT_DIED; - } - clientInfo = new ClientInfo(pid, uid, userId_, displayId, inputClient, channel, attribute); - mapClients.insert(std::pair, ClientInfo*>(obj, clientInfo)); - int ret = obj->AddDeathRecipient(clientDeathRecipient); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("PerUserSession::AddClient AddDeathRecipient return : %{public}s [%{public}d]", ErrorCode::ToString(ret), userId_); - } - return ErrorCode::NO_ERROR; + /*! Add an input client + \param pid the process pid of the input client + \param uid the uid of the the input client + \param displayId the display id of the input client + \param inputClient the remote object handler of the input client + \param channel the remote InputDataChannel object handler for the input client. + \n It will be transferred to input method service + \param attribute the input attribute of the input client. + \return \li ErrorCode::NO_ERROR no error + \return \li ErrorCode::ERROR_CLIENT_DUPLICATED client is duplicated + */ + int PerUserSession::AddClient(int pid, int uid, int displayId, const sptr& inputClient, + const sptr& channel, + const InputAttribute& attribute) + { + IMSA_HILOGI("PerUserSession::AddClient"); + ClientInfo* clientInfo = GetClientInfo(inputClient); + if (clientInfo != nullptr) { + IMSA_HILOGE("PerUserSession::AddClient clientInfo is not nullptr"); + return ErrorCode::ERROR_CLIENT_DUPLICATED; } - /*! Remove an input client - \param inputClient remote object handler of the input client - \param[out] remainClientNum remained count of the same kinds of clients for this user - \n (i.e. if inputClient is an normal client, remainClientNum is the count of remained normal clients. - \n if inputClient is a security client, remainClientNum is the count of remained security clients.) - \return ErrorCode::NO_ERROR no error - \return ErrorCode::ERROR_CLIENT_NOT_FOUND client is not found - */ - int PerUserSession::RemoveClient(const sptr& inputClient, int *remainClientNum) - { - IMSA_HILOGE("PerUserSession::RemoveClient"); - sptr b = inputClient->AsObject(); - std::map, ClientInfo*>::iterator it = mapClients.find(b); - if (it == mapClients.end()) { - IMSA_HILOGE("PerUserSession::RemoveClient %{public}s [%{public}d]", ErrorCode::ToString(ErrorCode::ERROR_CLIENT_NOT_FOUND), userId_); - return ErrorCode::ERROR_CLIENT_NOT_FOUND; - } - ClientInfo* clientInfo = it->second; - bool flag = clientInfo->attribute.GetSecurityFlag(); - int ret = b->RemoveDeathRecipient(clientDeathRecipient); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("PerUserSession::RemoveClient RemoveDeathRecipient return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); - } - ret = clientInfo->client->onInputReleased(0); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("PerUserSession::RemoveClient onInputReleased return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); - } - delete clientInfo; - mapClients.erase(it); - - if(remainClientNum!=nullptr) { - *remainClientNum = 0; - for(it=mapClients.begin(); it!=mapClients.end(); ++it) { - if (it->second->attribute.GetSecurityFlag() == flag) { - (*remainClientNum)++; - } + sptr obj = inputClient->AsObject(); + if (obj == nullptr) { + IMSA_HILOGE("PerUserSession::AddClient inputClient AsObject is nullptr"); + return ErrorCode::ERROR_REMOTE_CLIENT_DIED; + } + clientInfo = new ClientInfo(pid, uid, userId_, displayId, inputClient, channel, attribute); + mapClients.insert(std::pair, ClientInfo*>(obj, clientInfo)); + int ret = obj->AddDeathRecipient(clientDeathRecipient); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("PerUserSession::AddClient AddDeathRecipient return : %{public}s [%{public}d]", ErrorCode::ToString(ret), userId_); + } + return ErrorCode::NO_ERROR; + } + + /*! Remove an input client + \param inputClient remote object handler of the input client + \param[out] remainClientNum remained count of the same kinds of clients for this user + \n (i.e. if inputClient is an normal client, remainClientNum is the count of remained normal clients. + \n if inputClient is a security client, remainClientNum is the count of remained security clients.) + \return ErrorCode::NO_ERROR no error + \return ErrorCode::ERROR_CLIENT_NOT_FOUND client is not found + */ + int PerUserSession::RemoveClient(const sptr& inputClient, int *remainClientNum) + { + IMSA_HILOGE("PerUserSession::RemoveClient"); + sptr b = inputClient->AsObject(); + std::map, ClientInfo*>::iterator it = mapClients.find(b); + if (it == mapClients.end()) { + IMSA_HILOGE("PerUserSession::RemoveClient %{public}s [%{public}d]", ErrorCode::ToString(ErrorCode::ERROR_CLIENT_NOT_FOUND), userId_); + return ErrorCode::ERROR_CLIENT_NOT_FOUND; + } + ClientInfo* clientInfo = it->second; + bool flag = clientInfo->attribute.GetSecurityFlag(); + int ret = b->RemoveDeathRecipient(clientDeathRecipient); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("PerUserSession::RemoveClient RemoveDeathRecipient return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); + } + ret = clientInfo->client->onInputReleased(0); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("PerUserSession::RemoveClient onInputReleased return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); + } + delete clientInfo; + mapClients.erase(it); + + if(remainClientNum!=nullptr) { + *remainClientNum = 0; + for(it=mapClients.begin(); it!=mapClients.end(); ++it) { + if (it->second->attribute.GetSecurityFlag() == flag) { + (*remainClientNum)++; } } - return ErrorCode::NO_ERROR; } + return ErrorCode::NO_ERROR; + } - /*! Start input method service - \param index it can be 0 or 1. 0 - default ime, 1 - security ime - \return ErrorCode::NO_ERROR no error - \return ErrorCode::ERROR_IME_BIND_FAILED failed to bind ime - \return ErrorCode::ERROR_IME_NOT_AVAILABLE no ime is available - \return ErrorCode::ERROR_SECURITY_IME_NOT_AVAILABLE no security ime is available - \return ErrorCode::ERROR_TOKEN_CREATE_FAILED failed to create window token - \return other errors returned by binder driver - */ - int PerUserSession::StartInputMethod(int index) - { - IMSA_HILOGI("PerUserSession::StartInputMethod index=%{public}d [%{public}d]\n", index, userId_); - - if (imsCore[index] == nullptr) { - IMSA_HILOGI("PerUserSession::StartInputMethod imscore is null"); - return ErrorCode::ERROR_IME_BIND_FAILED; - } + /*! Start input method service + \param index it can be 0 or 1. 0 - default ime, 1 - security ime + \return ErrorCode::NO_ERROR no error + \return ErrorCode::ERROR_IME_BIND_FAILED failed to bind ime + \return ErrorCode::ERROR_IME_NOT_AVAILABLE no ime is available + \return ErrorCode::ERROR_SECURITY_IME_NOT_AVAILABLE no security ime is available + \return ErrorCode::ERROR_TOKEN_CREATE_FAILED failed to create window token + \return other errors returned by binder driver + */ + int PerUserSession::StartInputMethod(int index) + { + IMSA_HILOGI("PerUserSession::StartInputMethod index=%{public}d [%{public}d]\n", index, userId_); - sptr b = imsCore[index]->AsObject(); - inputMethodToken[index] = IPCSkeleton::GetInstance().GetContextObject(); - localControlChannel[index] = new InputControlChannelStub(userId_); - inputControlChannel[index] = localControlChannel[index]; - int ret_init = imsCore[index]->initializeInput(inputMethodToken[index], displayId, inputControlChannel[index]); - if (ret_init != ErrorCode::NO_ERROR) { - IMSA_HILOGE("PerUserSession::StartInputMethod initializeInput return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret_init), userId_); - localControlChannel[index] = nullptr; - inputControlChannel[index] = nullptr; - return ret_init; - } - return ErrorCode::NO_ERROR; + if (imsCore[index] == nullptr) { + IMSA_HILOGI("PerUserSession::StartInputMethod imscore is null"); + return ErrorCode::ERROR_IME_BIND_FAILED; } - /*! Stop input method service - \param index it can be 0 or 1. 0 - default ime, 1 - security ime - \return ErrorCode::NO_ERROR no error - \return ErrorCode::ERROR_IME_NOT_STARTED ime not started - \return ErrorCode::ERROR_IME_UNBIND_FAILED failed to unbind ime - \return ErrorCode::ERROR_TOKEN_DESTROY_FAILED failed to destroy window token - \return other errors returned by binder driver - */ - int PerUserSession::StopInputMethod(int index) - { - IMSA_HILOGI("Start... index = %{public}d [%{public}d]\n", index, userId_); - if (index >= MAX_IME || index < 0) { - IMSA_HILOGE("Aborted! %{public}s [%{public}d]\n", ErrorCode::ToString(ErrorCode::ERROR_BAD_PARAMETERS), userId_); - return ErrorCode::ERROR_BAD_PARAMETERS; - } - if (imsCore[index] == nullptr || currentIme[index] == nullptr) { - IMSA_HILOGE("Aborted! %{public}s [%{public}d]\n", ErrorCode::ToString(ErrorCode::ERROR_IME_NOT_STARTED), userId_); - return ErrorCode::ERROR_IME_NOT_STARTED; - } - if (currentIme[index] == currentIme[1-index] && imsCore[1-index] != nullptr) { - imsCore[index] = nullptr; - inputControlChannel[index] = nullptr; - localControlChannel[index] = nullptr; - IMSA_HILOGI("End...[%{public}d]\n", userId_); - return ErrorCode::NO_ERROR; - } - - IMSA_HILOGD("unbindInputMethodService...\n"); + sptr b = imsCore[index]->AsObject(); + inputMethodToken[index] = IPCSkeleton::GetInstance().GetContextObject(); + localControlChannel[index] = new InputControlChannelStub(userId_); + inputControlChannel[index] = localControlChannel[index]; + int ret_init = imsCore[index]->initializeInput(inputMethodToken[index], displayId, inputControlChannel[index]); + if (ret_init != ErrorCode::NO_ERROR) { + IMSA_HILOGE("PerUserSession::StartInputMethod initializeInput return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret_init), userId_); + localControlChannel[index] = nullptr; + inputControlChannel[index] = nullptr; + return ret_init; + } + return ErrorCode::NO_ERROR; + } - IMSA_HILOGD("destroyWindowToken...\n"); - int errorCode = ErrorCode::NO_ERROR; - int ret = Platform::Instance()->DestroyWindowToken(userId_, currentIme[index]->mPackageName); - inputMethodToken[index] = nullptr; - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("destroyWindowToken return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); - errorCode = ErrorCode::ERROR_TOKEN_DESTROY_FAILED; - } - sptr b = imsCore[index]->AsObject(); - ret = b->RemoveDeathRecipient(imsDeathRecipient); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("RemoveDeathRecipient return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); - } + /*! Stop input method service + \param index it can be 0 or 1. 0 - default ime, 1 - security ime + \return ErrorCode::NO_ERROR no error + \return ErrorCode::ERROR_IME_NOT_STARTED ime not started + \return ErrorCode::ERROR_IME_UNBIND_FAILED failed to unbind ime + \return ErrorCode::ERROR_TOKEN_DESTROY_FAILED failed to destroy window token + \return other errors returned by binder driver + */ + int PerUserSession::StopInputMethod(int index) + { + IMSA_HILOGI("Start... index = %{public}d [%{public}d]\n", index, userId_); + if (index >= MAX_IME || index < 0) { + IMSA_HILOGE("Aborted! %{public}s [%{public}d]\n", ErrorCode::ToString(ErrorCode::ERROR_BAD_PARAMETERS), userId_); + return ErrorCode::ERROR_BAD_PARAMETERS; + } + if (imsCore[index] == nullptr || currentIme[index] == nullptr) { + IMSA_HILOGE("Aborted! %{public}s [%{public}d]\n", ErrorCode::ToString(ErrorCode::ERROR_IME_NOT_STARTED), userId_); + return ErrorCode::ERROR_IME_NOT_STARTED; + } + if (currentIme[index] == currentIme[1-index] && imsCore[1-index] != nullptr) { imsCore[index] = nullptr; inputControlChannel[index] = nullptr; localControlChannel[index] = nullptr; IMSA_HILOGI("End...[%{public}d]\n", userId_); - return errorCode; - } - - /*! Show keyboard - \param inputClient the remote object handler of the input client. - \return ErrorCode::NO_ERROR no error - \return ErrorCode::ERROR_IME_NOT_STARTED ime not started - \return ErrorCode::ERROR_KBD_IS_OCCUPIED keyboard is showing by other client - \return ErrorCode::ERROR_CLIENT_NOT_FOUND the input client is not found - \return ErrorCode::ERROR_IME_START_FAILED failed to start input method service - \return ErrorCode::ERROR_KBD_SHOW_FAILED failed to show keyboard - \return other errors returned by binder driver - */ - int PerUserSession::ShowKeyboard( const sptr& inputClient ) - { - IMSA_HILOGI("PerUserSession::ShowKeyboard"); - ClientInfo* clientInfo = GetClientInfo(inputClient); - int index = GetImeIndex(inputClient); - if (index == -1 || clientInfo == nullptr) { - IMSA_HILOGE("PerUserSession::ShowKeyboard Aborted! index = -1 or clientInfo is nullptr"); - return ErrorCode::ERROR_CLIENT_NOT_FOUND; - } - - lastImeIndex = index; - bool supportPhysicalKbd = Platform::Instance()->CheckPhysicalKeyboard(); - localControlChannel[index]->ResetFlag(); - bool ret = imsCore[index]->startInput(clientInfo->channel, clientInfo->attribute, supportPhysicalKbd); - if (!ret || - localControlChannel[index]->GetAgentAndChannel(&imsAgent, &imsChannel)==false) { - IMSA_HILOGE("PerUserSession::ShowKeyboard Aborted! client is not ready"); - int result = clientInfo->client->onInputReady(1, nullptr, nullptr); - if (result != ErrorCode::NO_ERROR) { - IMSA_HILOGE("PerUserSession::ShowKeyboard onInputReady return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); - } - return ErrorCode::ERROR_IME_START_FAILED; - } + return ErrorCode::NO_ERROR; + } - ret = imsCore[index]->showKeyboard(1); - if (!ret) { - IMSA_HILOGE("PerUserSession::ShowKeyboard Aborted! showKeyboard has error : %{public}s", ErrorCode::ToString(ret)); + IMSA_HILOGD("unbindInputMethodService...\n"); - int ret_client = clientInfo->client->onInputReady(1, nullptr, nullptr); - if (ret_client != ErrorCode::NO_ERROR) { - IMSA_HILOGE("PerUserSession::ShowKeyboard onInputReady has error : %{public}s", ErrorCode::ToString(ret_client)); - } - return ErrorCode::ERROR_KBD_SHOW_FAILED; - } + IMSA_HILOGD("destroyWindowToken...\n"); + int errorCode = ErrorCode::NO_ERROR; + int ret = Platform::Instance()->DestroyWindowToken(userId_, currentIme[index]->mPackageName); + inputMethodToken[index] = nullptr; + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("destroyWindowToken return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); + errorCode = ErrorCode::ERROR_TOKEN_DESTROY_FAILED; + } + sptr b = imsCore[index]->AsObject(); + ret = b->RemoveDeathRecipient(imsDeathRecipient); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("RemoveDeathRecipient return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); + } + imsCore[index] = nullptr; + inputControlChannel[index] = nullptr; + localControlChannel[index] = nullptr; + IMSA_HILOGI("End...[%{public}d]\n", userId_); + return errorCode; + } - if(clientInfo->client == nullptr){ - IMSA_HILOGI("PerUserSession::ShowKeyboard clientInfo->client is nullptr"); - } + /*! Show keyboard + \param inputClient the remote object handler of the input client. + \return ErrorCode::NO_ERROR no error + \return ErrorCode::ERROR_IME_NOT_STARTED ime not started + \return ErrorCode::ERROR_KBD_IS_OCCUPIED keyboard is showing by other client + \return ErrorCode::ERROR_CLIENT_NOT_FOUND the input client is not found + \return ErrorCode::ERROR_IME_START_FAILED failed to start input method service + \return ErrorCode::ERROR_KBD_SHOW_FAILED failed to show keyboard + \return other errors returned by binder driver + */ + int PerUserSession::ShowKeyboard( const sptr& inputClient ) + { + IMSA_HILOGI("PerUserSession::ShowKeyboard"); + ClientInfo* clientInfo = GetClientInfo(inputClient); + int index = GetImeIndex(inputClient); + if (index == -1 || clientInfo == nullptr) { + IMSA_HILOGE("PerUserSession::ShowKeyboard Aborted! index = -1 or clientInfo is nullptr"); + return ErrorCode::ERROR_CLIENT_NOT_FOUND; + } - int result = clientInfo->client->onInputReady(0, imsAgent, imsChannel); + lastImeIndex = index; + bool supportPhysicalKbd = Platform::Instance()->CheckPhysicalKeyboard(); + localControlChannel[index]->ResetFlag(); + bool ret = imsCore[index]->startInput(clientInfo->channel, clientInfo->attribute, supportPhysicalKbd); + if (!ret || + localControlChannel[index]->GetAgentAndChannel(&imsAgent, &imsChannel)==false) { + IMSA_HILOGE("PerUserSession::ShowKeyboard Aborted! client is not ready"); + int result = clientInfo->client->onInputReady(1, nullptr, nullptr); if (result != ErrorCode::NO_ERROR) { - IMSA_HILOGE("PerUserSession::ShowKeyboard Aborted! onInputReady return : %{public}s", ErrorCode::ToString(ret)); - return result; + IMSA_HILOGE("PerUserSession::ShowKeyboard onInputReady return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); } - currentClient = inputClient; - return ErrorCode::NO_ERROR; + return ErrorCode::ERROR_IME_START_FAILED; } - /*! hide keyboard - \param inputClient the remote object handler of the input client. - \return ErrorCode::NO_ERROR no error - \return ErrorCode::ERROR_IME_NOT_STARTED ime not started - \return ErrorCode::ERROR_KBD_IS_NOT_SHOWING keyboard has not been showing - \return ErrorCode::ERROR_CLIENT_NOT_FOUND the input client is not found - \return ErrorCode::ERROR_KBD_HIDE_FAILED failed to hide keyboard - \return other errors returned by binder driver - */ - int PerUserSession::HideKeyboard(const sptr& inputClient) - { - IMSA_HILOGI("PerUserSession::HideKeyboard"); - int index = GetImeIndex(inputClient); - if (index == -1) { - IMSA_HILOGE("PerUserSession::HideKeyboard Aborted! %{public}s [%{public}d]\n", ErrorCode::ToString(ErrorCode::ERROR_CLIENT_NOT_FOUND), userId_); - return ErrorCode::ERROR_CLIENT_NOT_FOUND; - } - ClientInfo* clientInfo = GetClientInfo(inputClient); - if(clientInfo == nullptr){ - IMSA_HILOGE("PerUserSession::HideKeyboard GetClientInfo pointer nullptr"); - } - if (imsCore[index] == nullptr) { - IMSA_HILOGE("PerUserSession::HideKeyboard imsCore[index] is nullptr"); - clientInfo->client->onInputReady(1, nullptr, nullptr); - return ErrorCode::ERROR_IME_NOT_STARTED; - } + ret = imsCore[index]->showKeyboard(1); + if (!ret) { + IMSA_HILOGE("PerUserSession::ShowKeyboard Aborted! showKeyboard has error : %{public}s", ErrorCode::ToString(ret)); - if (currentClient == nullptr) { - clientInfo->client->onInputReady(1, nullptr, nullptr); - IMSA_HILOGE("PerUserSession::HideKeyboard Aborted! %{public}s [%{public}d]\n", ErrorCode::ToString(ErrorCode::ERROR_KBD_IS_NOT_SHOWING), userId_); - return ErrorCode::ERROR_KBD_IS_NOT_SHOWING; - } - bool ret = imsCore[index]->hideKeyboard(1); - if(!ret) { - IMSA_HILOGE("PerUserSession::HideKeyboard [imsCore->hideKeyboard] failed"); - ret=ErrorCode::ERROR_KBD_HIDE_FAILED; - } - int ret_stop = imsCore[index]->stopInput(); - if (ret_stop != ErrorCode::NO_ERROR) { - IMSA_HILOGE("PerUserSession::HideKeyboard Aborted! stopInput return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret_stop), userId_); - ret = ErrorCode::ERROR_KBD_HIDE_FAILED; + int ret_client = clientInfo->client->onInputReady(1, nullptr, nullptr); + if (ret_client != ErrorCode::NO_ERROR) { + IMSA_HILOGE("PerUserSession::ShowKeyboard onInputReady has error : %{public}s", ErrorCode::ToString(ret_client)); } + return ErrorCode::ERROR_KBD_SHOW_FAILED; + } - int ret_client_stop = clientInfo->client->onInputReady(1, nullptr, nullptr); - if (ret_client_stop != ErrorCode::NO_ERROR) { - IMSA_HILOGE("PerUserSession::HideKeyboard onInputReady return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret_client_stop), userId_); - } - currentClient = nullptr; - imsAgent = nullptr; - if (imsChannel != nullptr) { - delete imsChannel; - imsChannel = nullptr; - } - return ErrorCode::NO_ERROR; + if(clientInfo->client == nullptr){ + IMSA_HILOGI("PerUserSession::ShowKeyboard clientInfo->client is nullptr"); } - /*! Get the display mode of the current keyboard showing - \return return display mode. - \n 0 - part sceen mode, 1 - full sceen mode - */ - int PerUserSession::GetDisplayMode() - { - return currentDisplayMode; + int result = clientInfo->client->onInputReady(0, imsAgent, imsChannel); + if (result != ErrorCode::NO_ERROR) { + IMSA_HILOGE("PerUserSession::ShowKeyboard Aborted! onInputReady return : %{public}s", ErrorCode::ToString(ret)); + return result; } + currentClient = inputClient; + return ErrorCode::NO_ERROR; + } - /*! Get the keyboard window height - \param[out] retHeight the height of keyboard window showing or showed returned to caller - \return ErrorCode - */ - int PerUserSession::GetKeyboardWindowHeight(int *retHeight) - { - if (retHeight == nullptr) { - return ErrorCode::ERROR_BAD_PARAMETERS; - } - if (imsCore[lastImeIndex] != nullptr) { - int ret = imsCore[lastImeIndex]->getKeyboardWindowHeight(retHeight); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("getKeyboardWindowHeight return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); - } - return ret; - } - IMSA_HILOGW("No IME is started [%{public}d]\n", userId_); + /*! hide keyboard + \param inputClient the remote object handler of the input client. + \return ErrorCode::NO_ERROR no error + \return ErrorCode::ERROR_IME_NOT_STARTED ime not started + \return ErrorCode::ERROR_KBD_IS_NOT_SHOWING keyboard has not been showing + \return ErrorCode::ERROR_CLIENT_NOT_FOUND the input client is not found + \return ErrorCode::ERROR_KBD_HIDE_FAILED failed to hide keyboard + \return other errors returned by binder driver + */ + int PerUserSession::HideKeyboard(const sptr& inputClient) + { + IMSA_HILOGI("PerUserSession::HideKeyboard"); + int index = GetImeIndex(inputClient); + if (index == -1) { + IMSA_HILOGE("PerUserSession::HideKeyboard Aborted! %{public}s [%{public}d]\n", ErrorCode::ToString(ErrorCode::ERROR_CLIENT_NOT_FOUND), userId_); + return ErrorCode::ERROR_CLIENT_NOT_FOUND; + } + ClientInfo* clientInfo = GetClientInfo(inputClient); + if(clientInfo == nullptr){ + IMSA_HILOGE("PerUserSession::HideKeyboard GetClientInfo pointer nullptr"); + } + if (imsCore[index] == nullptr) { + IMSA_HILOGE("PerUserSession::HideKeyboard imsCore[index] is nullptr"); + clientInfo->client->onInputReady(1, nullptr, nullptr); return ErrorCode::ERROR_IME_NOT_STARTED; } - /*! Get the current keyboard type - \return return the pointer of the object of current keyboard type. - \n null if no keyboard type supported by the current ime. - \note The returned pointer should NOT be freed by the caller. - */ - KeyboardType* PerUserSession::GetCurrentKeyboardType() - { - if (inputMethodSetting == nullptr || currentIme[DEFAULT_IME] == nullptr) { - IMSA_HILOGI("Ime has not started ! [%{public}d]\n", userId_); - return nullptr; + if (currentClient == nullptr) { + clientInfo->client->onInputReady(1, nullptr, nullptr); + IMSA_HILOGE("PerUserSession::HideKeyboard Aborted! %{public}s [%{public}d]\n", ErrorCode::ToString(ErrorCode::ERROR_KBD_IS_NOT_SHOWING), userId_); + return ErrorCode::ERROR_KBD_IS_NOT_SHOWING; + } + bool ret = imsCore[index]->hideKeyboard(1); + if(!ret) { + IMSA_HILOGE("PerUserSession::HideKeyboard [imsCore->hideKeyboard] failed"); + ret=ErrorCode::ERROR_KBD_HIDE_FAILED; + } + + int ret_client_stop = clientInfo->client->onInputReady(1, nullptr, nullptr); + if (ret_client_stop != ErrorCode::NO_ERROR) { + IMSA_HILOGE("PerUserSession::HideKeyboard onInputReady return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret_client_stop), userId_); + } + currentClient = nullptr; + imsAgent = nullptr; + imsCore[index] = nullptr; + if (imsChannel != nullptr) { + delete imsChannel; + imsChannel = nullptr; + } + return ErrorCode::NO_ERROR; + } + + /*! Get the display mode of the current keyboard showing + \return return display mode. + \n 0 - part sceen mode, 1 - full sceen mode + */ + int PerUserSession::GetDisplayMode() + { + return currentDisplayMode; + } + + /*! Get the keyboard window height + \param[out] retHeight the height of keyboard window showing or showed returned to caller + \return ErrorCode + */ + int PerUserSession::GetKeyboardWindowHeight(int *retHeight) + { + if (retHeight == nullptr) { + return ErrorCode::ERROR_BAD_PARAMETERS; + } + if (imsCore[lastImeIndex] != nullptr) { + int ret = imsCore[lastImeIndex]->getKeyboardWindowHeight(retHeight); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("getKeyboardWindowHeight return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); } - if (currentIme[DEFAULT_IME] == currentIme[SECURITY_IME]) { + return ret; + } + IMSA_HILOGW("No IME is started [%{public}d]\n", userId_); + return ErrorCode::ERROR_IME_NOT_STARTED; + } + + /*! Get the current keyboard type + \return return the pointer of the object of current keyboard type. + \n null if no keyboard type supported by the current ime. + \note The returned pointer should NOT be freed by the caller. + */ + KeyboardType* PerUserSession::GetCurrentKeyboardType() + { + if (inputMethodSetting == nullptr || currentIme[DEFAULT_IME] == nullptr) { + IMSA_HILOGI("Ime has not started ! [%{public}d]\n", userId_); + return nullptr; + } + if (currentIme[DEFAULT_IME] == currentIme[SECURITY_IME]) { + return nullptr; + } + int hashCode = inputMethodSetting->GetCurrentKeyboardType(); // To be checked. + if (hashCode == -1) { + std::vector hashCodeList = inputMethodSetting->GetEnabledKeyboardTypes(currentIme[DEFAULT_IME]->mImeId); + if (hashCodeList.size() == 0) { + IMSA_HILOGE("Cannot find any keyboard types for the current ime [%{public}d]\n", userId_); return nullptr; } - int hashCode = inputMethodSetting->GetCurrentKeyboardType(); // To be checked. - if (hashCode == -1) { - std::vector hashCodeList = inputMethodSetting->GetEnabledKeyboardTypes(currentIme[DEFAULT_IME]->mImeId); - if (hashCodeList.size() == 0) { - IMSA_HILOGE("Cannot find any keyboard types for the current ime [%{public}d]\n", userId_); - return nullptr; - } - hashCode = hashCodeList[0]; - } + hashCode = hashCodeList[0]; + } - for(int i=0; i<(int)currentIme[DEFAULT_IME]->mTypes.size(); i++) { - if (currentIme[DEFAULT_IME]->mTypes[i]->getHashCode() == hashCode) { - return currentIme[DEFAULT_IME]->mTypes[i]; - } + for(int i=0; i<(int)currentIme[DEFAULT_IME]->mTypes.size(); i++) { + if (currentIme[DEFAULT_IME]->mTypes[i]->getHashCode() == hashCode) { + return currentIme[DEFAULT_IME]->mTypes[i]; } - return nullptr; } + return nullptr; + } - /*! Handle the situation a remote input client died\n - It's called when a remote input client died - \param who the remote object handler of the input client died. - */ - void PerUserSession::OnClientDied(const wptr& who) - { - IMSA_HILOGI("PerUserSession::OnClientDied Start...[%{public}d]\n", userId_); - bool flag = false; - std::map, ClientInfo*>::iterator it; + /*! Handle the situation a remote input client died\n + It's called when a remote input client died + \param who the remote object handler of the input client died. + */ + void PerUserSession::OnClientDied(const wptr& who) + { + IMSA_HILOGI("PerUserSession::OnClientDied Start...[%{public}d]\n", userId_); + bool flag = false; + std::map, ClientInfo*>::iterator it; - for (it=mapClients.begin(); it!=mapClients.end(); ++it) { - if (it->first == who) { - flag = true; - break; - } - } - if (flag == false) { - IMSA_HILOGW("Aborted! The client died is not found! [%{public}d]\n", userId_); - return; + for (it=mapClients.begin(); it!=mapClients.end(); ++it) { + if (it->first == who) { + flag = true; + break; } + } + if (flag == false) { + IMSA_HILOGW("Aborted! The client died is not found! [%{public}d]\n", userId_); + return; + } - sptr client = iface_cast(it->first); - int remainClientNum = 0; - if (currentClient == client) { - HideKeyboard(client); - } - RemoveClient(client, &remainClientNum); + sptr client = it->second->client; + int remainClientNum = 0; + if (currentClient != nullptr) { + HideKeyboard(client); } + RemoveClient(client, &remainClientNum); + } - /*! Handle the situation a input method service died\n - It's called when an input method service died - \param who the remote object handler of input method service who died. - */ - void PerUserSession::OnImsDied(const wptr& who) - { - (void) who; // temporary void it, as we will add support for security IME. - IMSA_HILOGI("Start...[%{public}d]\n", userId_); - int index = 0; - for(int i=0; i b = imsCore[i]->AsObject(); - if (b == who) { - index = i; - break; - } - } - if (currentClient && (GetImeIndex(currentClient)==index || - currentIme[index] == currentIme[1-index])) { - needReshowClient = currentClient; - HideKeyboard(currentClient); - } - StopInputMethod(index); - if (currentIme[index] == currentIme[1-index]) { - StopInputMethod(1-index); + /*! Handle the situation a input method service died\n + It's called when an input method service died + \param who the remote object handler of input method service who died. + */ + void PerUserSession::OnImsDied(const wptr& who) + { + (void) who; // temporary void it, as we will add support for security IME. + IMSA_HILOGI("Start...[%{public}d]\n", userId_); + int index = 0; + for(int i=0; i b = imsCore[i]->AsObject(); + if (b == who) { + index = i; + break; } + } + if (currentClient && (GetImeIndex(currentClient)==index || + currentIme[index] == currentIme[1-index])) { + needReshowClient = currentClient; + HideKeyboard(currentClient); + } + StopInputMethod(index); + if (currentIme[index] == currentIme[1-index]) { + StopInputMethod(1-index); + } - if (IncreaseOrResetImeError(false, index) == 3) { - // call to disable the current input method. - MessageParcel *parcel = new MessageParcel(); - parcel->WriteInt32(userId_); - parcel->WriteString16(currentIme[index]->mImeId); - Message* msg = new Message(MSG_ID_DISABLE_IMS, parcel); - MessageHandler::Instance()->SendMessage(msg); - } else { - // restart current input method. - IMSA_HILOGI("IME died. Restart input method ! [%{public}d]\n", userId_); - MessageParcel *parcel = new MessageParcel(); - parcel->WriteInt32(userId_); - parcel->WriteInt32(index); - parcel->WriteString16(currentIme[index]->mImeId); - Message* msg = new Message(MSG_ID_RESTART_IMS, parcel); - usleep(1600*1000); // wait that PACKAGE_REMOVED message is received if this ime has been removed - MessageHandler::Instance()->SendMessage(msg); - } - IMSA_HILOGI("End...[%{public}d]\n", userId_); + if (IncreaseOrResetImeError(false, index) == 3) { + // call to disable the current input method. + MessageParcel *parcel = new MessageParcel(); + parcel->WriteInt32(userId_); + parcel->WriteString16(currentIme[index]->mImeId); + Message* msg = new Message(MSG_ID_DISABLE_IMS, parcel); + MessageHandler::Instance()->SendMessage(msg); + } else { + // restart current input method. + IMSA_HILOGI("IME died. Restart input method ! [%{public}d]\n", userId_); + MessageParcel *parcel = new MessageParcel(); + parcel->WriteInt32(userId_); + parcel->WriteInt32(index); + parcel->WriteString16(currentIme[index]->mImeId); + Message* msg = new Message(MSG_ID_RESTART_IMS, parcel); + usleep(1600*1000); // wait that PACKAGE_REMOVED message is received if this ime has been removed + MessageHandler::Instance()->SendMessage(msg); } + IMSA_HILOGI("End...[%{public}d]\n", userId_); + } - /*! It's called when input method setting data in the system is changed - \param key the name of setting item changed. - \param value the value of setting item changed. - \return ErrorCode::NO_ERROR no error - \return ErrorCode::ERROR_SETTING_SAME_VALUE the current value is same as the one in the system. - */ - int PerUserSession::OnSettingChanged(const std::u16string& key, const std::u16string& value) - { - IMSA_HILOGI("Start...[%{public}d]\n", userId_); - std::unique_lock lock(mtx); - if (inputMethodSetting == nullptr) { - return ErrorCode::ERROR_NULL_POINTER; - } - std::u16string currentValue = inputMethodSetting->GetValue(key); + /*! It's called when input method setting data in the system is changed + \param key the name of setting item changed. + \param value the value of setting item changed. + \return ErrorCode::NO_ERROR no error + \return ErrorCode::ERROR_SETTING_SAME_VALUE the current value is same as the one in the system. + */ + int PerUserSession::OnSettingChanged(const std::u16string& key, const std::u16string& value) + { + IMSA_HILOGI("Start...[%{public}d]\n", userId_); + std::unique_lock lock(mtx); + if (inputMethodSetting == nullptr) { + return ErrorCode::ERROR_NULL_POINTER; + } + std::u16string currentValue = inputMethodSetting->GetValue(key); - IMSA_HILOGD("%{public}s=%{public}s, currentValue = %{public}s\n", Utils::to_utf8(key).c_str(), Utils::to_utf8(value).c_str(), Utils::to_utf8(currentValue).c_str()); + IMSA_HILOGD("%{public}s=%{public}s, currentValue = %{public}s\n", Utils::to_utf8(key).c_str(), Utils::to_utf8(value).c_str(), Utils::to_utf8(currentValue).c_str()); - if (currentValue == value) { - IMSA_HILOGI("End...[%{public}d]\n", userId_); - return ErrorCode::ERROR_SETTING_SAME_VALUE; - } + if (currentValue == value) { + IMSA_HILOGI("End...[%{public}d]\n", userId_); + return ErrorCode::ERROR_SETTING_SAME_VALUE; + } - if (key == InputMethodSetting::CURRENT_KEYBOARD_TYPE_TAG) { - return OnCurrentKeyboardTypeChanged(DEFAULT_IME, value); - } else if (key == InputMethodSetting::CURRENT_SYS_KEYBOARD_TYPE_TAG) { - return OnCurrentKeyboardTypeChanged(SECURITY_IME, value); - } else if (key == InputMethodSetting::CURRENT_INPUT_METHOD_TAG) { - if (currentIme[DEFAULT_IME] == nullptr || - value == currentIme[DEFAULT_IME]->mImeId) { - return ErrorCode::NO_ERROR; - } + if (key == InputMethodSetting::CURRENT_KEYBOARD_TYPE_TAG) { + return OnCurrentKeyboardTypeChanged(DEFAULT_IME, value); + } else if (key == InputMethodSetting::CURRENT_SYS_KEYBOARD_TYPE_TAG) { + return OnCurrentKeyboardTypeChanged(SECURITY_IME, value); + } else if (key == InputMethodSetting::CURRENT_INPUT_METHOD_TAG) { + if (currentIme[DEFAULT_IME] == nullptr || + value == currentIme[DEFAULT_IME]->mImeId) { + return ErrorCode::NO_ERROR; + } + if (currentClient != nullptr && GetImeIndex(currentClient)==DEFAULT_IME) { + needReshowClient = currentClient; + HideKeyboard(currentClient); + } + StopInputMethod(DEFAULT_IME); + currentIme[DEFAULT_IME] = nullptr; + currentKbdIndex[DEFAULT_IME] = 0; + inputMethodSetting->SetCurrentKeyboardType(-1); + } else if (key == InputMethodSetting::ENABLED_INPUT_METHODS_TAG) { + if (currentIme[DEFAULT_IME] && currentIme[DEFAULT_IME]!=currentIme[SECURITY_IME] && + value.find(currentIme[DEFAULT_IME]->mImeId) == std::string::npos) { if (currentClient != nullptr && GetImeIndex(currentClient)==DEFAULT_IME) { needReshowClient = currentClient; HideKeyboard(currentClient); @@ -756,623 +762,612 @@ namespace MiscServices { currentIme[DEFAULT_IME] = nullptr; currentKbdIndex[DEFAULT_IME] = 0; inputMethodSetting->SetCurrentKeyboardType(-1); - } else if (key == InputMethodSetting::ENABLED_INPUT_METHODS_TAG) { - if (currentIme[DEFAULT_IME] && currentIme[DEFAULT_IME]!=currentIme[SECURITY_IME] && - value.find(currentIme[DEFAULT_IME]->mImeId) == std::string::npos) { - if (currentClient != nullptr && GetImeIndex(currentClient)==DEFAULT_IME) { - needReshowClient = currentClient; - HideKeyboard(currentClient); - } - StopInputMethod(DEFAULT_IME); - currentIme[DEFAULT_IME] = nullptr; - currentKbdIndex[DEFAULT_IME] = 0; - inputMethodSetting->SetCurrentKeyboardType(-1); - } - } - IMSA_HILOGI("End...[%{public}d]\n", userId_); - return ErrorCode::NO_ERROR; - } - - /*! Change current keyboard type. - \param index it can be 0 or 1. 0 - default ime, 1 - security ime. - \param value the hash code of keyboard type - \return ErrorCode::NO_ERROR no error - \return ErrorCode::ERROR_SETTING_SAME_VALUE the current value is same as the one in the system. - */ - int PerUserSession::OnCurrentKeyboardTypeChanged(int index, const std::u16string& value) - { - std::string str = Utils::to_utf8(value); - int hashCode = std::atoi(str.c_str()); - if (hashCode == -1) { - return ErrorCode::ERROR_SETTING_SAME_VALUE;; - } - // switch within the current ime. - if (index == SECURITY_IME || currentIme[DEFAULT_IME] == currentIme[SECURITY_IME]) { - int num = currentKbdIndex[index]; - if (currentIme[index]->mTypes[num]->getHashCode() == hashCode) { - return ErrorCode::ERROR_SETTING_SAME_VALUE; - } - for(int i=0; i<(int)currentIme[index]->mTypes.size(); i++) { - if (currentIme[index]->mTypes[i]->getHashCode() == hashCode) { - currentKbdIndex[index] = i; - break; - } - } - } else { - std::u16string imeId = currentIme[index]->mImeId; - std::vector currentKbdTypes = inputMethodSetting->GetEnabledKeyboardTypes(imeId); - int num = currentKbdIndex[index]; - if (currentKbdTypes[num] == hashCode) { - return ErrorCode::ERROR_SETTING_SAME_VALUE; - } - for(int i=0; i<(int)currentKbdTypes.size(); i++) { - if (currentKbdTypes[i] == hashCode) { - currentKbdIndex[index] = i; - break; - } - } - } - KeyboardType* type = GetKeyboardType(index, currentKbdIndex[index]); - if (type != nullptr) { - if (currentClient != nullptr) { - int ret = imsCore[index]->setKeyboardType(*type); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("setKeyboardType return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); - } - } - if (imsCore[index] == imsCore[1-index]) { - inputMethodSetting->SetCurrentKeyboardType(type->getHashCode()); - inputMethodSetting->SetCurrentSysKeyboardType(type->getHashCode()); - currentKbdIndex[1-index] = currentKbdIndex[index]; - } else if (index == DEFAULT_IME) { - inputMethodSetting->SetCurrentKeyboardType(type->getHashCode()); - } else { - inputMethodSetting->SetCurrentSysKeyboardType(type->getHashCode()); - } } - return ErrorCode::NO_ERROR; } + IMSA_HILOGI("End...[%{public}d]\n", userId_); + return ErrorCode::NO_ERROR; + } - /*! Hide current keyboard - \param flag the flag to hide keyboard. - */ - void PerUserSession::OnHideKeyboardSelf(int flags) - { - IMSA_HILOGW("PerUserSession::OnHideKeyboardSelf"); - (void) flags; - HideKeyboard(currentClient); + /*! Change current keyboard type. + \param index it can be 0 or 1. 0 - default ime, 1 - security ime. + \param value the hash code of keyboard type + \return ErrorCode::NO_ERROR no error + \return ErrorCode::ERROR_SETTING_SAME_VALUE the current value is same as the one in the system. + */ + int PerUserSession::OnCurrentKeyboardTypeChanged(int index, const std::u16string& value) + { + std::string str = Utils::to_utf8(value); + int hashCode = std::atoi(str.c_str()); + if (hashCode == -1) { + return ErrorCode::ERROR_SETTING_SAME_VALUE;; } - - /*! Switch to next keyboard type - */ - void PerUserSession::OnAdvanceToNext( ) - { - int index = GetImeIndex(currentClient); - if (index == -1) { - IMSA_HILOGW("%{public}s [%{public}d]\n", ErrorCode::ToString(ErrorCode::ERROR_CLIENT_NOT_FOUND), userId_); - return ; + // switch within the current ime. + if (index == SECURITY_IME || currentIme[DEFAULT_IME] == currentIme[SECURITY_IME]) { + int num = currentKbdIndex[index]; + if (currentIme[index]->mTypes[num]->getHashCode() == hashCode) { + return ErrorCode::ERROR_SETTING_SAME_VALUE; } - int size = 0; - if (index==SECURITY_IME || currentIme[DEFAULT_IME] == currentIme[SECURITY_IME] ) { - size = currentIme[index]->mTypes.size(); - } else { - std::u16string imeId = currentIme[index]->mImeId; - std::vector currentKbdTypes = inputMethodSetting->GetEnabledKeyboardTypes(imeId); - size = currentKbdTypes.size(); + for(int i=0; i<(int)currentIme[index]->mTypes.size(); i++) { + if (currentIme[index]->mTypes[i]->getHashCode() == hashCode) { + currentKbdIndex[index] = i; + break; + } } - if (size < 2) { - IMSA_HILOGW("No next keyboard is available. [%{public}d]\n", userId_); - return ; + } else { + std::u16string imeId = currentIme[index]->mImeId; + std::vector currentKbdTypes = inputMethodSetting->GetEnabledKeyboardTypes(imeId); + int num = currentKbdIndex[index]; + if (currentKbdTypes[num] == hashCode) { + return ErrorCode::ERROR_SETTING_SAME_VALUE; } - - int num = currentKbdIndex[index]+1; - num %= size; - KeyboardType* type = GetKeyboardType(index, num); - if (type == nullptr) { - IMSA_HILOGW("No next keyboard is available. [%{public}d]\n", userId_); - return; + for(int i=0; i<(int)currentKbdTypes.size(); i++) { + if (currentKbdTypes[i] == hashCode) { + currentKbdIndex[index] = i; + break; + } } - InputMethodSetting tmpSetting; - if (imsCore[index] == imsCore[1-index]) { - tmpSetting.SetCurrentKeyboardType(type->getHashCode()); - tmpSetting.SetCurrentSysKeyboardType(type->getHashCode()); + } + KeyboardType* type = GetKeyboardType(index, currentKbdIndex[index]); + if (type != nullptr) { + if (currentClient != nullptr) { + int ret = imsCore[index]->setKeyboardType(*type); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("setKeyboardType return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); + } } - else if (index == DEFAULT_IME) { - tmpSetting.SetCurrentKeyboardType(type->getHashCode()); + if (imsCore[index] == imsCore[1-index]) { + inputMethodSetting->SetCurrentKeyboardType(type->getHashCode()); + inputMethodSetting->SetCurrentSysKeyboardType(type->getHashCode()); + currentKbdIndex[1-index] = currentKbdIndex[index]; + } else if (index == DEFAULT_IME) { + inputMethodSetting->SetCurrentKeyboardType(type->getHashCode()); } else { - tmpSetting.SetCurrentSysKeyboardType(type->getHashCode()); + inputMethodSetting->SetCurrentSysKeyboardType(type->getHashCode()); } - Platform::Instance()->SetInputMethodSetting(userId_, tmpSetting); } + return ErrorCode::NO_ERROR; + } - /*! Set display mode - \param mode the display mode of soft keyboard UI. - \n 0 - part sceen mode, 1 - full sceen mode - */ - void PerUserSession::OnSetDisplayMode(int mode) - { - currentDisplayMode = mode; - ClientInfo* clientInfo = GetClientInfo(currentClient); - if (clientInfo == nullptr) { - IMSA_HILOGE("%{public}s [%{public}d]\n", ErrorCode::ToString(ErrorCode::ERROR_CLIENT_NOT_FOUND), userId_); - return ; - } - int ret = clientInfo->client->setDisplayMode(mode); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("setDisplayMode return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); - } - } + /*! Hide current keyboard + \param flag the flag to hide keyboard. + */ + void PerUserSession::OnHideKeyboardSelf(int flags) + { + IMSA_HILOGW("PerUserSession::OnHideKeyboardSelf"); + (void) flags; + HideKeyboard(currentClient); + } - /*! Restart input method service - \param index it can be DEFAULT_IME or SECURITY_IME - \param imeId the id of the input method service going to restart - */ - void PerUserSession::OnRestartIms(int index, const std::u16string& imeId) - { - if (index<0 || index>=MAX_IME) { - return ; - } - IMSA_HILOGI("Start...[%{public}d]\n", userId_); - if (currentIme[index] && currentIme[index]->mImeId == imeId) { - int ret = StartInputMethod(index); - if (needReshowClient && GetImeIndex(needReshowClient)==index) { - if (ret == ErrorCode::NO_ERROR) { - ShowKeyboard(needReshowClient); - } - needReshowClient = nullptr; - } - } - IMSA_HILOGI("End...[%{public}d]\n", userId_); + /*! Switch to next keyboard type + */ + void PerUserSession::OnAdvanceToNext( ) + { + int index = GetImeIndex(currentClient); + if (index == -1) { + IMSA_HILOGW("%{public}s [%{public}d]\n", ErrorCode::ToString(ErrorCode::ERROR_CLIENT_NOT_FOUND), userId_); + return ; + } + int size = 0; + if (index==SECURITY_IME || currentIme[DEFAULT_IME] == currentIme[SECURITY_IME] ) { + size = currentIme[index]->mTypes.size(); + } else { + std::u16string imeId = currentIme[index]->mImeId; + std::vector currentKbdTypes = inputMethodSetting->GetEnabledKeyboardTypes(imeId); + size = currentKbdTypes.size(); + } + if (size < 2) { + IMSA_HILOGW("No next keyboard is available. [%{public}d]\n", userId_); + return ; } - /*! It's called when this user is locked - */ - void PerUserSession::OnUserLocked() - { - IMSA_HILOGI("PerUserSession::OnUserLocked"); - if (userState == UserState::USER_STATE_STARTED) { - IMSA_HILOGI("End...[%{public}d]\n", userId_); - return; - } - userState = UserState::USER_STATE_STARTED; - // hide current keyboard - if (currentClient != nullptr) { - HideKeyboard(currentClient); - } - for(int i=0; i<2; i++) { - StopInputMethod(i); - currentIme[i] = nullptr; - } - // disconnect all clients. - std::map, ClientInfo*>::iterator it; - for(it=mapClients.begin(); it!=mapClients.end();) { - sptr b = it->first; - b->RemoveDeathRecipient(clientDeathRecipient); - ClientInfo* clientInfo = it->second; - if (clientInfo != nullptr) { - int ret = clientInfo->client->onInputReleased(0); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("2-onInputReleased return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); - } - delete clientInfo; - } - IMSA_HILOGD("erase client..\n"); - it = mapClients.erase(it); - } - mapClients.clear(); + int num = currentKbdIndex[index]+1; + num %= size; + KeyboardType* type = GetKeyboardType(index, num); + if (type == nullptr) { + IMSA_HILOGW("No next keyboard is available. [%{public}d]\n", userId_); + return; + } + InputMethodSetting tmpSetting; + if (imsCore[index] == imsCore[1-index]) { + tmpSetting.SetCurrentKeyboardType(type->getHashCode()); + tmpSetting.SetCurrentSysKeyboardType(type->getHashCode()); + } + else if (index == DEFAULT_IME) { + tmpSetting.SetCurrentKeyboardType(type->getHashCode()); + } else { + tmpSetting.SetCurrentSysKeyboardType(type->getHashCode()); + } + Platform::Instance()->SetInputMethodSetting(userId_, tmpSetting); + } - // reset values - inputMethodSetting = nullptr; - currentClient = nullptr; - needReshowClient = nullptr; + /*! Set display mode + \param mode the display mode of soft keyboard UI. + \n 0 - part sceen mode, 1 - full sceen mode + */ + void PerUserSession::OnSetDisplayMode(int mode) + { + currentDisplayMode = mode; + ClientInfo* clientInfo = GetClientInfo(currentClient); + if (clientInfo == nullptr) { + IMSA_HILOGE("%{public}s [%{public}d]\n", ErrorCode::ToString(ErrorCode::ERROR_CLIENT_NOT_FOUND), userId_); + return ; } + int ret = clientInfo->client->setDisplayMode(mode); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("setDisplayMode return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); + } + } - /*! Print the session information of this user into the given stream - \n The information includes: - \li the information of all the input clients connected to the input method management system. - \li current input method engine information - \li security input method engine information - \li current session information - \param fd the raw file descriptor that the dump is being sent to - */ - void PerUserSession::Dump(int fd) - { - std::map, ClientInfo*>::const_iterator it; - dprintf(fd, "\n - User Session State :\n"); - dprintf(fd, " * Client count = %d\n", mapClients.size()); - int index = 0; - for(it=mapClients.cbegin(); it!=mapClients.cend(); ++it) { - if (currentClient != nullptr && - Platform::RemoteBrokerToObject(currentClient) == it->first) { - dprintf(fd, " *[%d] Client Information: (current client)\n", index++); - } else { - dprintf(fd, " [%d] Client Information:\n", index++); + /*! Restart input method service + \param index it can be DEFAULT_IME or SECURITY_IME + \param imeId the id of the input method service going to restart + */ + void PerUserSession::OnRestartIms(int index, const std::u16string& imeId) + { + if (index<0 || index>=MAX_IME) { + return ; + } + IMSA_HILOGI("Start...[%{public}d]\n", userId_); + if (currentIme[index] && currentIme[index]->mImeId == imeId) { + int ret = StartInputMethod(index); + if (needReshowClient && GetImeIndex(needReshowClient)==index) { + if (ret == ErrorCode::NO_ERROR) { + ShowKeyboard(needReshowClient); } - DumpClientInfo(fd, *(it->second)); + needReshowClient = nullptr; } - std::string header[2] = {"Current", "Security"}; - for(int i=0; i<2; i++) { - if (currentIme[i] != nullptr) { - dprintf(fd, "\n * %s IME mImeId = %s\n", header[i].c_str(), Utils::to_utf8(currentIme[i]->mImeId).c_str()); - KeyboardType* type = currentIme[i]->mTypes.at(currentKbdIndex[i]); - dprintf(fd, " %s KeyboardType mHashCode = %d, mLanguage = %s\n", header[i].c_str(), - type->getHashCode(), Utils::to_utf8(type->getLanguage()).c_str()); - - if (imsCore[i] != nullptr) { - sptr b = imsCore[i]->AsObject(); - dprintf(fd, " %s IME Service = %s#%p\n", header[i].c_str(), - Utils::to_utf8(b->GetObjectDescriptor()).c_str(), b.GetRefPtr()); - b=inputControlChannel[i]->AsObject(); - dprintf(fd, " %s InputControlChannel = %s#%p\n", - header[i].c_str(), Utils::to_utf8(b->GetObjectDescriptor()).c_str(), b.GetRefPtr()); - dprintf(fd, " %s inputMethodWindowToken = %p\n", header[i].c_str(), inputMethodToken[i].GetRefPtr()); - } else { - dprintf(fd, " %s IME Service = null (not started)\n", header[i].c_str()); - } - } else { - dprintf(fd, "\n * %s IME = null\n", header[i].c_str()); + } + IMSA_HILOGI("End...[%{public}d]\n", userId_); + } + + /*! It's called when this user is locked + */ + void PerUserSession::OnUserLocked() + { + IMSA_HILOGI("PerUserSession::OnUserLocked"); + if (userState == UserState::USER_STATE_STARTED) { + IMSA_HILOGI("End...[%{public}d]\n", userId_); + return; + } + userState = UserState::USER_STATE_STARTED; + // hide current keyboard + if (currentClient != nullptr) { + HideKeyboard(currentClient); + } + for(int i=0; i<2; i++) { + StopInputMethod(i); + currentIme[i] = nullptr; + } + // disconnect all clients. + std::map, ClientInfo*>::iterator it; + for(it=mapClients.begin(); it!=mapClients.end();) { + sptr b = it->first; + b->RemoveDeathRecipient(clientDeathRecipient); + ClientInfo* clientInfo = it->second; + if (clientInfo != nullptr) { + int ret = clientInfo->client->onInputReleased(0); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("2-onInputReleased return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); } + delete clientInfo; } - DumpCurrentSession(fd); + IMSA_HILOGD("erase client..\n"); + it = mapClients.erase(it); } + mapClients.clear(); - /*! dump current session - \param fd the file descriptor to output the information - */ - void PerUserSession::DumpCurrentSession(int fd) - { - if (currentClient == nullptr) { - dprintf(fd, "\n * Current Session = null (keyboard is not showing by any client)\n"); - return; + // reset values + inputMethodSetting = nullptr; + currentClient = nullptr; + needReshowClient = nullptr; + } + + /*! Print the session information of this user into the given stream + \n The information includes: + \li the information of all the input clients connected to the input method management system. + \li current input method engine information + \li security input method engine information + \li current session information + \param fd the raw file descriptor that the dump is being sent to + */ + void PerUserSession::Dump(int fd) + { + std::map, ClientInfo*>::const_iterator it; + dprintf(fd, "\n - User Session State :\n"); + dprintf(fd, " * Client count = %d\n", mapClients.size()); + int index = 0; + for(it=mapClients.cbegin(); it!=mapClients.cend(); ++it) { + if (currentClient != nullptr && + Platform::RemoteBrokerToObject(currentClient) == it->first) { + dprintf(fd, " *[%d] Client Information: (current client)\n", index++); + } else { + dprintf(fd, " [%d] Client Information:\n", index++); } - sptr b = Platform::RemoteBrokerToObject(currentClient); - std::map, ClientInfo*>::iterator it = mapClients.find(b); - int index = GetImeIndex(currentClient); - dprintf(fd, "\n * Current Session State :\n"); - dprintf(fd, " current client [= %s#%p] information :\n", - Utils::to_utf8(b->GetObjectDescriptor()).c_str(), b.GetRefPtr()); DumpClientInfo(fd, *(it->second)); - - dprintf(fd, " current IME mImeID = %s\n", Utils::to_utf8(currentIme[index]->mImeId).c_str()); - b = Platform::RemoteBrokerToObject(imsCore[index]); - dprintf(fd, " IME service = %s#%p\n", Utils::to_utf8(b->GetObjectDescriptor()).c_str(), b.GetRefPtr()); - b = Platform::RemoteBrokerToObject(imsAgent); - dprintf(fd, " inputAgent = %s#%p\n", Utils::to_utf8(b->GetObjectDescriptor()).c_str(), b.GetRefPtr()); - b = Platform::RemoteBrokerToObject(inputControlChannel[index]); - dprintf(fd, " inputControlChannel = %s#%p\n", Utils::to_utf8(b->GetObjectDescriptor()).c_str(), b.GetRefPtr()); - dprintf(fd, " inputMethodWindowToken = #%p\n", inputMethodToken[index].GetRefPtr()); - dprintf(fd, " displayId = %d\n", displayId); - if (currentDisplayMode == 0) { - dprintf(fd, " displayMode = %d [ part sceen ]\n", currentDisplayMode); + } + std::string header[2] = {"Current", "Security"}; + for(int i=0; i<2; i++) { + if (currentIme[i] != nullptr) { + dprintf(fd, "\n * %s IME mImeId = %s\n", header[i].c_str(), Utils::to_utf8(currentIme[i]->mImeId).c_str()); + KeyboardType* type = currentIme[i]->mTypes.at(currentKbdIndex[i]); + dprintf(fd, " %s KeyboardType mHashCode = %d, mLanguage = %s\n", header[i].c_str(), + type->getHashCode(), Utils::to_utf8(type->getLanguage()).c_str()); + + if (imsCore[i] != nullptr) { + sptr b = imsCore[i]->AsObject(); + dprintf(fd, " %s IME Service = %s#%p\n", header[i].c_str(), + Utils::to_utf8(b->GetObjectDescriptor()).c_str(), b.GetRefPtr()); + b=inputControlChannel[i]->AsObject(); + dprintf(fd, " %s InputControlChannel = %s#%p\n", + header[i].c_str(), Utils::to_utf8(b->GetObjectDescriptor()).c_str(), b.GetRefPtr()); + dprintf(fd, " %s inputMethodWindowToken = %p\n", header[i].c_str(), inputMethodToken[i].GetRefPtr()); + } else { + dprintf(fd, " %s IME Service = null (not started)\n", header[i].c_str()); + } } else { - dprintf(fd, " displayMode = %d [ full sceen ]\n", currentDisplayMode); + dprintf(fd, "\n * %s IME = null\n", header[i].c_str()); } - int height = 0; - GetKeyboardWindowHeight(&height); - dprintf(fd, " keyboard window height = %d\n", height); } + DumpCurrentSession(fd); + } - /*! dump a client information - \param fd the file descriptor to output the information - \param clientInfo client information of a remote input client - */ - void PerUserSession::DumpClientInfo(int fd, const ClientInfo& clientInfo) - { - dprintf(fd, " pid = %d\n", clientInfo.pid); - dprintf(fd, " uid = %d\n", clientInfo.uid); - dprintf(fd, " userId = %d\n", clientInfo.userId); - dprintf(fd, " displayId = %d\n", clientInfo.displayId); - - sptr b = Platform::RemoteBrokerToObject(clientInfo.client); - dprintf(fd, " inputClient = %s#%p\n", Utils::to_utf8(b->GetObjectDescriptor()).c_str(), b.GetRefPtr()); - b = Platform::RemoteBrokerToObject(clientInfo.channel); - dprintf(fd, " inputDataChannel = %s#%p\n", Utils::to_utf8(b->GetObjectDescriptor()).c_str(), b.GetRefPtr()); - } - - /*! Increase or reset ime error number - \param resetFlag the flag to increase or reset number. - \n resetFlag=true, reset error number to 0; - \n resetFlag=false, increase error number. - \param imeIndex index=0 default ime; index=1 security ime - \return return the error count value. It is less or equal 3. - */ - int PerUserSession::IncreaseOrResetImeError(bool resetFlag, int imeIndex) - { - static int errorNum[2] = {0, 0}; - static time_t past[2] = {time(0), time(0)}; - if (resetFlag == true) { - errorNum[imeIndex] = 0; - past[imeIndex] = 0; - return 0; - } + /*! dump current session + \param fd the file descriptor to output the information + */ + void PerUserSession::DumpCurrentSession(int fd) + { + if (currentClient == nullptr) { + dprintf(fd, "\n * Current Session = null (keyboard is not showing by any client)\n"); + return; + } + sptr b = Platform::RemoteBrokerToObject(currentClient); + std::map, ClientInfo*>::iterator it = mapClients.find(b); + int index = GetImeIndex(currentClient); + dprintf(fd, "\n * Current Session State :\n"); + dprintf(fd, " current client [= %s#%p] information :\n", + Utils::to_utf8(b->GetObjectDescriptor()).c_str(), b.GetRefPtr()); + DumpClientInfo(fd, *(it->second)); + + dprintf(fd, " current IME mImeID = %s\n", Utils::to_utf8(currentIme[index]->mImeId).c_str()); + b = Platform::RemoteBrokerToObject(imsCore[index]); + dprintf(fd, " IME service = %s#%p\n", Utils::to_utf8(b->GetObjectDescriptor()).c_str(), b.GetRefPtr()); + b = Platform::RemoteBrokerToObject(imsAgent); + dprintf(fd, " inputAgent = %s#%p\n", Utils::to_utf8(b->GetObjectDescriptor()).c_str(), b.GetRefPtr()); + b = Platform::RemoteBrokerToObject(inputControlChannel[index]); + dprintf(fd, " inputControlChannel = %s#%p\n", Utils::to_utf8(b->GetObjectDescriptor()).c_str(), b.GetRefPtr()); + dprintf(fd, " inputMethodWindowToken = #%p\n", inputMethodToken[index].GetRefPtr()); + dprintf(fd, " displayId = %d\n", displayId); + if (currentDisplayMode == 0) { + dprintf(fd, " displayMode = %d [ part sceen ]\n", currentDisplayMode); + } else { + dprintf(fd, " displayMode = %d [ full sceen ]\n", currentDisplayMode); + } + int height = 0; + GetKeyboardWindowHeight(&height); + dprintf(fd, " keyboard window height = %d\n", height); + } - errorNum[imeIndex]++; - time_t now = time(0); - double diffSeconds = difftime(now, past[imeIndex]); + /*! dump a client information + \param fd the file descriptor to output the information + \param clientInfo client information of a remote input client + */ + void PerUserSession::DumpClientInfo(int fd, const ClientInfo& clientInfo) + { + dprintf(fd, " pid = %d\n", clientInfo.pid); + dprintf(fd, " uid = %d\n", clientInfo.uid); + dprintf(fd, " userId = %d\n", clientInfo.userId); + dprintf(fd, " displayId = %d\n", clientInfo.displayId); + + sptr b = Platform::RemoteBrokerToObject(clientInfo.client); + dprintf(fd, " inputClient = %s#%p\n", Utils::to_utf8(b->GetObjectDescriptor()).c_str(), b.GetRefPtr()); + b = Platform::RemoteBrokerToObject(clientInfo.channel); + dprintf(fd, " inputDataChannel = %s#%p\n", Utils::to_utf8(b->GetObjectDescriptor()).c_str(), b.GetRefPtr()); + } - //time difference is more than 5 minutes, reset time and error num; - if (diffSeconds > 300) { - past[imeIndex] = now; - errorNum[imeIndex] = 1; - } - return errorNum[imeIndex]; + /*! Increase or reset ime error number + \param resetFlag the flag to increase or reset number. + \n resetFlag=true, reset error number to 0; + \n resetFlag=false, increase error number. + \param imeIndex index=0 default ime; index=1 security ime + \return return the error count value. It is less or equal 3. + */ + int PerUserSession::IncreaseOrResetImeError(bool resetFlag, int imeIndex) + { + static int errorNum[2] = {0, 0}; + static time_t past[2] = {time(0), time(0)}; + if (resetFlag == true) { + errorNum[imeIndex] = 0; + past[imeIndex] = 0; + return 0; } - /*! Get keyboard type - \param imeIndex it can be 0 or 1. 0 - default ime, 1 - security ime - \param typeIndex the index of keyboard type. - \return a KeyboardType pointer when it's found. - \return null when it's not found. - \note The returned pointer should not be freed by caller. - */ - KeyboardType* PerUserSession::GetKeyboardType(int imeIndex, int typeIndex) - { - if(typeIndex < 0) { + errorNum[imeIndex]++; + time_t now = time(0); + double diffSeconds = difftime(now, past[imeIndex]); + + //time difference is more than 5 minutes, reset time and error num; + if (diffSeconds > 300) { + past[imeIndex] = now; + errorNum[imeIndex] = 1; + } + return errorNum[imeIndex]; + } + + /*! Get keyboard type + \param imeIndex it can be 0 or 1. 0 - default ime, 1 - security ime + \param typeIndex the index of keyboard type. + \return a KeyboardType pointer when it's found. + \return null when it's not found. + \note The returned pointer should not be freed by caller. + */ + KeyboardType* PerUserSession::GetKeyboardType(int imeIndex, int typeIndex) + { + if(typeIndex < 0) { + return nullptr; + } + if (imeIndex == SECURITY_IME || currentIme[DEFAULT_IME] == currentIme[SECURITY_IME]) { + if (typeIndex >= (int)currentIme[imeIndex]->mTypes.size()) { return nullptr; } - if (imeIndex == SECURITY_IME || currentIme[DEFAULT_IME] == currentIme[SECURITY_IME]) { - if (typeIndex >= (int)currentIme[imeIndex]->mTypes.size()) { - return nullptr; - } - return currentIme[imeIndex]->mTypes[typeIndex]; - } else { - std::u16string imeId = currentIme[imeIndex]->mImeId; - std::vector currentKbdTypes = inputMethodSetting->GetEnabledKeyboardTypes(imeId); - int size = currentKbdTypes.size(); - if (typeIndex >= size) { - return nullptr; - } - int hashCode = currentKbdTypes[typeIndex]; - for(int i=0; i<(int)currentIme[imeIndex]->mTypes.size(); i++) { - if (currentIme[imeIndex]->mTypes[i]->getHashCode() == hashCode) { - return currentIme[imeIndex]->mTypes[i]; - } + return currentIme[imeIndex]->mTypes[typeIndex]; + } else { + std::u16string imeId = currentIme[imeIndex]->mImeId; + std::vector currentKbdTypes = inputMethodSetting->GetEnabledKeyboardTypes(imeId); + int size = currentKbdTypes.size(); + if (typeIndex >= size) { + return nullptr; + } + int hashCode = currentKbdTypes[typeIndex]; + for(int i=0; i<(int)currentIme[imeIndex]->mTypes.size(); i++) { + if (currentIme[imeIndex]->mTypes[i]->getHashCode() == hashCode) { + return currentIme[imeIndex]->mTypes[i]; } } - return nullptr; } + return nullptr; + } - /*! Reset current keyboard type - \param imeIndex it can be 0 or 1. 0 - default ime, 1 - security ime - */ - void PerUserSession::ResetCurrentKeyboardType(int imeIndex) - { - currentKbdIndex[imeIndex] = 0; - int hashCode = 0; - if (imeIndex == DEFAULT_IME) { - hashCode = inputMethodSetting->GetCurrentKeyboardType(); - } else { - hashCode = inputMethodSetting->GetCurrentSysKeyboardType(); - } - KeyboardType* type = nullptr; - if (hashCode == -1) { - type = GetKeyboardType(imeIndex, currentKbdIndex[imeIndex]); - } else { - bool flag = false; - if (imeIndex == SECURITY_IME || currentIme[DEFAULT_IME] == currentIme[SECURITY_IME]) { - for(int i=0; i<(int)currentIme[imeIndex]->mTypes.size(); i++) { - if (currentIme[imeIndex]->mTypes[i]->getHashCode()==hashCode) { - currentKbdIndex[imeIndex] = i; - flag = true; - break; - } - } - } else { - std::vector hashCodeList = inputMethodSetting->GetEnabledKeyboardTypes(currentIme[imeIndex]->mImeId); - for(int i=0; i<(int)hashCodeList.size(); i++) { - if (hashCode == hashCodeList[i]) { - currentKbdIndex[imeIndex] = i; - flag = true; - break; - } + /*! Reset current keyboard type + \param imeIndex it can be 0 or 1. 0 - default ime, 1 - security ime + */ + void PerUserSession::ResetCurrentKeyboardType(int imeIndex) + { + currentKbdIndex[imeIndex] = 0; + int hashCode = 0; + if (imeIndex == DEFAULT_IME) { + hashCode = inputMethodSetting->GetCurrentKeyboardType(); + } else { + hashCode = inputMethodSetting->GetCurrentSysKeyboardType(); + } + KeyboardType* type = nullptr; + if (hashCode == -1) { + type = GetKeyboardType(imeIndex, currentKbdIndex[imeIndex]); + } else { + bool flag = false; + if (imeIndex == SECURITY_IME || currentIme[DEFAULT_IME] == currentIme[SECURITY_IME]) { + for(int i=0; i<(int)currentIme[imeIndex]->mTypes.size(); i++) { + if (currentIme[imeIndex]->mTypes[i]->getHashCode()==hashCode) { + currentKbdIndex[imeIndex] = i; + flag = true; + break; } } - if (flag == false) { - IMSA_HILOGW("The current keyboard type [hashCode=%{public}d] is not found in the current IME. Reset it! [%{public}d]\n", - hashCode, userId_); - type = GetKeyboardType(imeIndex, currentKbdIndex[imeIndex]); - } else if (imsCore[imeIndex] == imsCore[1-imeIndex]) { - currentKbdIndex[1-imeIndex] = currentKbdIndex[imeIndex]; + } else { + std::vector hashCodeList = inputMethodSetting->GetEnabledKeyboardTypes(currentIme[imeIndex]->mImeId); + for(int i=0; i<(int)hashCodeList.size(); i++) { + if (hashCode == hashCodeList[i]) { + currentKbdIndex[imeIndex] = i; + flag = true; + break; + } } } - if (type != nullptr) { - InputMethodSetting tmpSetting; - if (imsCore[imeIndex] == imsCore[1-imeIndex]) { - inputMethodSetting->SetCurrentKeyboardType(type->getHashCode()); - inputMethodSetting->SetCurrentSysKeyboardType(type->getHashCode()); - currentKbdIndex[1-imeIndex] = currentKbdIndex[imeIndex]; - tmpSetting.SetCurrentKeyboardType(type->getHashCode()); - tmpSetting.SetCurrentSysKeyboardType(type->getHashCode()); - } else if (imeIndex == DEFAULT_IME) { - tmpSetting.SetCurrentKeyboardType(type->getHashCode()); - inputMethodSetting->SetCurrentKeyboardType(type->getHashCode()); - } else { - tmpSetting.SetCurrentSysKeyboardType(type->getHashCode()); - inputMethodSetting->SetCurrentSysKeyboardType(type->getHashCode()); - } - Platform::Instance()->SetInputMethodSetting(userId_, tmpSetting); + if (flag == false) { + IMSA_HILOGW("The current keyboard type [hashCode=%{public}d] is not found in the current IME. Reset it! [%{public}d]\n", + hashCode, userId_); + type = GetKeyboardType(imeIndex, currentKbdIndex[imeIndex]); + } else if (imsCore[imeIndex] == imsCore[1-imeIndex]) { + currentKbdIndex[1-imeIndex] = currentKbdIndex[imeIndex]; } } - - /*! Get ime index for the input client - \param inputClient the remote object handler of an input client. - \return 0 - default ime - \return 1 - security ime - \return -1 - input client is not found - */ - int PerUserSession::GetImeIndex(const sptr& inputClient) - { - if (inputClient == nullptr) { - IMSA_HILOGW("PerUserSession::GetImeIndex inputClient is nullptr"); - return -1; + if (type != nullptr) { + InputMethodSetting tmpSetting; + if (imsCore[imeIndex] == imsCore[1-imeIndex]) { + inputMethodSetting->SetCurrentKeyboardType(type->getHashCode()); + inputMethodSetting->SetCurrentSysKeyboardType(type->getHashCode()); + currentKbdIndex[1-imeIndex] = currentKbdIndex[imeIndex]; + tmpSetting.SetCurrentKeyboardType(type->getHashCode()); + tmpSetting.SetCurrentSysKeyboardType(type->getHashCode()); + } else if (imeIndex == DEFAULT_IME) { + tmpSetting.SetCurrentKeyboardType(type->getHashCode()); + inputMethodSetting->SetCurrentKeyboardType(type->getHashCode()); + } else { + tmpSetting.SetCurrentSysKeyboardType(type->getHashCode()); + inputMethodSetting->SetCurrentSysKeyboardType(type->getHashCode()); } + Platform::Instance()->SetInputMethodSetting(userId_, tmpSetting); + } + } - ClientInfo *clientInfo = GetClientInfo(inputClient); - if (clientInfo == nullptr) { - IMSA_HILOGW("PerUserSession::GetImeIndex clientInfo is nullptr"); - return -1; - } + /*! Get ime index for the input client + \param inputClient the remote object handler of an input client. + \return 0 - default ime + \return 1 - security ime + \return -1 - input client is not found + */ + int PerUserSession::GetImeIndex(const sptr& inputClient) + { + if (inputClient == nullptr) { + IMSA_HILOGW("PerUserSession::GetImeIndex inputClient is nullptr"); + return -1; + } - if (clientInfo->attribute.GetSecurityFlag() == true) { - return SECURITY_IME; - } - return DEFAULT_IME; + ClientInfo *clientInfo = GetClientInfo(inputClient); + if (clientInfo == nullptr) { + IMSA_HILOGW("PerUserSession::GetImeIndex clientInfo is nullptr"); + return -1; } - /*! Copy session data from one IME to another IME - \param imeIndex it can be 0 or 1. - \n 0 - default ime, 1 - security ime - */ - void PerUserSession::CopyInputMethodService(int imeIndex) - { - imsCore[imeIndex] = imsCore[1-imeIndex]; - localControlChannel[imeIndex] = localControlChannel[1-imeIndex]; - inputControlChannel[imeIndex] = inputControlChannel[1-imeIndex]; - inputMethodToken[imeIndex] = inputMethodToken[1-imeIndex]; - currentKbdIndex[imeIndex] = currentKbdIndex[1-imeIndex]; - int hashCode[2]; - hashCode[0] = inputMethodSetting->GetCurrentKeyboardType(); - hashCode[1] = inputMethodSetting->GetCurrentSysKeyboardType(); - if (hashCode[imeIndex] != hashCode[1-imeIndex]) { - hashCode[imeIndex] = hashCode[1-imeIndex]; - inputMethodSetting->SetCurrentKeyboardType(hashCode[0]); - inputMethodSetting->SetCurrentSysKeyboardType(hashCode[1]); - - InputMethodSetting tmpSetting; - tmpSetting.ClearData(); - tmpSetting.SetCurrentKeyboardType(hashCode[0]); - tmpSetting.SetCurrentSysKeyboardType(hashCode[1]); - Platform::Instance()->SetInputMethodSetting(userId_, tmpSetting); - } + if (clientInfo->attribute.GetSecurityFlag() == true) { + return SECURITY_IME; } + return DEFAULT_IME; + } - /*! Get ClientInfo - \param inputClient the IInputClient remote handler of given input client - \return a pointer of ClientInfo if client is found - \n null if client is not found - \note the clientInfo pointer should not be freed by caller - */ - ClientInfo* PerUserSession::GetClientInfo(const sptr& inputClient) - { - if (inputClient == nullptr) { - IMSA_HILOGE("PerUserSession::GetClientInfo inputClient is nullptr"); - return nullptr; - } - sptr b = Platform::RemoteBrokerToObject(inputClient); - std::map, ClientInfo*>::iterator it = mapClients.find(b); - if (it == mapClients.end()) { - return nullptr; - } + /*! Copy session data from one IME to another IME + \param imeIndex it can be 0 or 1. + \n 0 - default ime, 1 - security ime + */ + void PerUserSession::CopyInputMethodService(int imeIndex) + { + imsCore[imeIndex] = imsCore[1-imeIndex]; + localControlChannel[imeIndex] = localControlChannel[1-imeIndex]; + inputControlChannel[imeIndex] = inputControlChannel[1-imeIndex]; + inputMethodToken[imeIndex] = inputMethodToken[1-imeIndex]; + currentKbdIndex[imeIndex] = currentKbdIndex[1-imeIndex]; + int hashCode[2]; + hashCode[0] = inputMethodSetting->GetCurrentKeyboardType(); + hashCode[1] = inputMethodSetting->GetCurrentSysKeyboardType(); + if (hashCode[imeIndex] != hashCode[1-imeIndex]) { + hashCode[imeIndex] = hashCode[1-imeIndex]; + inputMethodSetting->SetCurrentKeyboardType(hashCode[0]); + inputMethodSetting->SetCurrentSysKeyboardType(hashCode[1]); + + InputMethodSetting tmpSetting; + tmpSetting.ClearData(); + tmpSetting.SetCurrentKeyboardType(hashCode[0]); + tmpSetting.SetCurrentSysKeyboardType(hashCode[1]); + Platform::Instance()->SetInputMethodSetting(userId_, tmpSetting); + } + } - return (ClientInfo*) it->second; + /*! Get ClientInfo + \param inputClient the IInputClient remote handler of given input client + \return a pointer of ClientInfo if client is found + \n null if client is not found + \note the clientInfo pointer should not be freed by caller + */ + ClientInfo* PerUserSession::GetClientInfo(const sptr& inputClient) + { + if (inputClient == nullptr) { + IMSA_HILOGE("PerUserSession::GetClientInfo inputClient is nullptr"); + return nullptr; + } + sptr b = Platform::RemoteBrokerToObject(inputClient); + std::map, ClientInfo*>::iterator it = mapClients.find(b); + if (it == mapClients.end()) { + return nullptr; } - void PerUserSession::BindInputAbility(){ - IMSA_HILOGE("PerUserSession::BindInputAbility"); - AAFwk::Want want; - want.SetAction("action.system.inputmethod"); - want.SetElementName("com.example.kikakeyboard","com.example.kikakeyboard.MainAbility"); - sptr stub(new (std::nothrow) InputMethodAbilityConnectionStub(0)); - sptr connCallback = new (std::nothrow) AAFwk::AbilityConnectionProxy(stub); - GetAbilityManagerService()->StartAbility(want); + return (ClientInfo*) it->second; + } + + void PerUserSession::BindInputAbility(){ + IMSA_HILOGE("PerUserSession::BindInputAbility"); + AAFwk::Want want; + want.SetAction("action.system.inputmethod"); + want.SetElementName("com.example.kikakeyboard","com.example.kikakeyboard.MainAbility"); + sptr stub(new (std::nothrow) InputMethodAbilityConnectionStub(0)); + sptr connCallback = new (std::nothrow) AAFwk::AbilityConnectionProxy(stub); + GetAbilityManagerService()->StartAbility(want); + } + + sptr PerUserSession::GetAbilityManagerService() + { + IMSA_HILOGE("GetAbilityManagerService start"); + sptr abilityMsObj = + OHOS::DelayedSingleton::GetInstance()->GetSystemAbility(ABILITY_MGR_SERVICE_ID); + if (abilityMsObj == nullptr) { + IMSA_HILOGE("failed to get ability manager service"); + return nullptr; } + return iface_cast(abilityMsObj); + } - sptr PerUserSession::GetAbilityManagerService() - { - IMSA_HILOGE("GetAbilityManagerService start"); - sptr abilityMsObj = - OHOS::DelayedSingleton::GetInstance()->GetSystemAbility(ABILITY_MGR_SERVICE_ID); - if (abilityMsObj == nullptr) { - IMSA_HILOGE("failed to get ability manager service"); - return nullptr; - } - return iface_cast(abilityMsObj); + /*! Prepare input. Called by an input client. + \n Run in work thread of this user + \param msg the parameters from remote client are saved in msg->msgContent_ + \return ErrorCode + */ + void PerUserSession::OnPrepareInput(Message* msg) + { + IMSA_HILOGI("PerUserSession::OnPrepareInput Start...[%{public}d]\n", userId_); + MessageParcel* data = msg->msgContent_; + int pid = data->ReadInt32(); + int uid = data->ReadInt32(); + int displayId = data->ReadInt32(); + + sptr clientObject = data->ReadRemoteObject(); + if (clientObject == nullptr) { + IMSA_HILOGI("PerUserSession::OnPrepareInput clientObject is null"); + } + sptr client = new InputClientProxy(clientObject); + sptr channelObject = data->ReadRemoteObject(); + if (channelObject == nullptr) { + IMSA_HILOGI("PerUserSession::OnPrepareInput channelObject is null"); + } + sptr channel = new InputDataChannelProxy(channelObject); + InputAttribute* attribute = data->ReadParcelable(); + if (attribute ==nullptr) { + IMSA_HILOGI("PerUserSession::OnPrepareInput attribute is nullptr"); } - /*! Prepare input. Called by an input client. - \n Run in work thread of this user - \param msg the parameters from remote client are saved in msg->msgContent_ - \return ErrorCode - */ - void PerUserSession::OnPrepareInput(Message* msg) - { - IMSA_HILOGI("PerUserSession::OnPrepareInput Start...[%{public}d]\n", userId_); - MessageParcel* data = msg->msgContent_; - int pid = data->ReadInt32(); - int uid = data->ReadInt32(); - int displayId = data->ReadInt32(); - - sptr clientObject = data->ReadRemoteObject(); - if (clientObject == nullptr) { - IMSA_HILOGI("PerUserSession::OnPrepareInput clientObject is null"); - } - sptr client = new InputClientProxy(clientObject); - sptr channelObject = data->ReadRemoteObject(); - if (channelObject == nullptr) { - IMSA_HILOGI("PerUserSession::OnPrepareInput channelObject is null"); - } - sptr channel = new InputDataChannelProxy(channelObject); - InputAttribute* attribute = data->ReadParcelable(); - if (attribute ==nullptr) { - IMSA_HILOGI("PerUserSession::OnPrepareInput attribute is nullptr"); - } + int ret = AddClient(pid, uid, displayId, client, channel, *attribute); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("PerUserSession::OnPrepareInput Aborted! %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); + return; + } + SetDisplayId(displayId); + int index = GetImeIndex(client); + IMSA_HILOGI("PerUserSession::OnPrepareInput index = %{public}d",index); + currentIndex = index; + IMSA_HILOGI("PerUserSession::OnPrepareInput BindInputAbility start"); + BindInputAbility(); + IMSA_HILOGI("PerUserSession::OnPrepareInput BindInputAbility end"); + } - int ret = AddClient(pid, uid, displayId, client, channel, *attribute); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("PerUserSession::OnPrepareInput Aborted! %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); - return; - } - SetDisplayId(displayId); - int index = GetImeIndex(client); - IMSA_HILOGI("PerUserSession::OnPrepareInput index = %{public}d",index); - currentIndex = index; - IMSA_HILOGI("PerUserSession::OnPrepareInput BindInputAbility start"); - BindInputAbility(); - IMSA_HILOGI("PerUserSession::OnPrepareInput BindInputAbility end"); - } - - /*! Release input. Called by an input client. - \n Run in work thread of this user - \param msg the parameters from remote client are saved in msg->msgContent_ - \return ErrorCode - */ - void PerUserSession::OnReleaseInput(Message* msg) - { - IMSA_HILOGI("PerUserSession::OnReleaseInput Start...[%{public}d]\n", userId_); - MessageParcel* data = msg->msgContent_; - - sptr clientObject = data->ReadRemoteObject(); - sptr client = new InputClientProxy(clientObject); - sptr interface = client; - int remainClientNum = 0; - if (currentClient == interface) { - HideKeyboard(client); - } - int ret = RemoveClient(client, &remainClientNum); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("PerUserSession::OnReleaseInput Aborted! Failed to RemoveClient [%{public}d]\n", userId_); - } - IMSA_HILOGI("PerUserSession::OnReleaseInput End...[%{public}d]\n", userId_); + /*! Release input. Called by an input client. + \n Run in work thread of this user + \param msg the parameters from remote client are saved in msg->msgContent_ + \return ErrorCode + */ + void PerUserSession::OnReleaseInput(Message* msg) + { + IMSA_HILOGI("PerUserSession::OnReleaseInput Start...[%{public}d]\n", userId_); + MessageParcel* data = msg->msgContent_; + + sptr clientObject = data->ReadRemoteObject(); + sptr client = new InputClientProxy(clientObject); + sptr interface = client; + int remainClientNum = 0; + if (currentClient == interface) { + HideKeyboard(client); + } + int ret = RemoveClient(client, &remainClientNum); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("PerUserSession::OnReleaseInput Aborted! Failed to RemoveClient [%{public}d]\n", userId_); } + IMSA_HILOGI("PerUserSession::OnReleaseInput End...[%{public}d]\n", userId_); + } - /*! Start input. Called by an input client. - \n Run in work thread of this user - \param msg the parameters from remote client are saved in msg->msgContent_ - \return ErrorCode - */ - void PerUserSession::OnStartInput(Message* msg) - { - IMSA_HILOGI("PerUserSession::OnStartInput"); - MessageParcel* data = msg->msgContent_; - sptr clientObject = data->ReadRemoteObject(); - sptr client = new InputClientProxy(clientObject); - int ret = ShowKeyboard(client); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("PerUserSession::OnStartInput Aborted! %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); - } else { - IMSA_HILOGI("PerUserSession::OnStartInput End...[%{public}d]\n", userId_); - } + /*! Start input. Called by an input client. + \n Run in work thread of this user + \param msg the parameters from remote client are saved in msg->msgContent_ + \return ErrorCode + */ + void PerUserSession::OnStartInput(Message* msg) + { + IMSA_HILOGI("PerUserSession::OnStartInput"); + MessageParcel* data = msg->msgContent_; + sptr clientObject = data->ReadRemoteObject(); + sptr client = new InputClientProxy(clientObject); + int ret = ShowKeyboard(client); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("PerUserSession::OnStartInput Aborted! %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); + } else { + IMSA_HILOGI("PerUserSession::OnStartInput End...[%{public}d]\n", userId_); } + } void PerUserSession::onSetInputMethodCore(Message* msg) { @@ -1384,40 +1379,40 @@ namespace MiscServices { int index = currentIndex; IMSA_HILOGI("PerUserSession::onSetInputMethodCore index = [%{public}d]\n", index); if (index >= MAX_IME || index < 0) { - IMSA_HILOGE("PerUserSession::onSetInputMethodCore Aborted! %{public}s [%{public}d]\n", ErrorCode::ToString(ErrorCode::ERROR_BAD_PARAMETERS), userId_); - return; + IMSA_HILOGE("PerUserSession::onSetInputMethodCore Aborted! %{public}s [%{public}d]\n", ErrorCode::ToString(ErrorCode::ERROR_BAD_PARAMETERS), userId_); + return; } if (imsCore[index] != nullptr) { - IMSA_HILOGI("PerUserSession::onSetInputMethodCore End... Input Method Service has already been started ! [%{public}d]\n", userId_); - return; + IMSA_HILOGI("PerUserSession::onSetInputMethodCore End... Input Method Service has already been started ! [%{public}d]\n", userId_); + return; } imsCore[index]=core; int ret = StartInputMethod(index); if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("PerUserSession::onSetInputMethodCore Aborted! %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); + IMSA_HILOGE("PerUserSession::onSetInputMethodCore Aborted! %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); } else { - IMSA_HILOGI("PerUserSession::onSetInputMethodCore End...[%{public}d]\n", userId_); + IMSA_HILOGI("PerUserSession::onSetInputMethodCore End...[%{public}d]\n", userId_); } } - /*! Stop input. Called by an input client. - \n Run in work thread of this user - \param msg the parameters from remote client are saved in msg->msgContent_ - \return ErrorCode - */ - void PerUserSession::OnStopInput(Message* msg) - { - IMSA_HILOGI("PerUserSession::OnStopInput"); - MessageParcel* data = msg->msgContent_; + /*! Stop input. Called by an input client. + \n Run in work thread of this user + \param msg the parameters from remote client are saved in msg->msgContent_ + \return ErrorCode + */ + void PerUserSession::OnStopInput(Message* msg) + { + IMSA_HILOGI("PerUserSession::OnStopInput"); + MessageParcel* data = msg->msgContent_; - sptr clientObject = data->ReadRemoteObject(); - sptr client = new InputClientProxy(clientObject); - int ret = HideKeyboard(client); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("PerUserSession::OnStopInput Aborted! %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); - } else { - IMSA_HILOGI("PerUserSession::OnStopInput End...[%{public}d]\n", userId_); - } + sptr clientObject = data->ReadRemoteObject(); + sptr client = new InputClientProxy(clientObject); + int ret = HideKeyboard(client); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("PerUserSession::OnStopInput Aborted! %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_); + } else { + IMSA_HILOGI("PerUserSession::OnStopInput End...[%{public}d]\n", userId_); } } } +} diff --git a/unitest/src/test_imc.cpp b/unitest/src/test_imc.cpp index aa4a6331b70cc4d3c7bf664793c0a876b431303a..336de404d2b76865110cf985e1fa10a016ebec48 100644 --- a/unitest/src/test_imc.cpp +++ b/unitest/src/test_imc.cpp @@ -40,7 +40,7 @@ public: TextListener() {} ~TextListener() {} void InsertText(const std::u16string& text) { - IMSA_HILOGI("IMC TEST TextListener InsertText: %{public}s", Utils::to_utf8(text).c_str()); + IMSA_HILOGI("IMC TEST TextListener InsertText: %{public}s", MiscServices::Utils::to_utf8(text).c_str()); } void DeleteBackward(int32_t length){