diff --git a/README.md b/README.md index 8a3e68aa..1f57d143 100644 --- a/README.md +++ b/README.md @@ -13,24 +13,33 @@ Input Method Framework, is used to connect the application and input method. the The input method framework currently has four modules, as follows: 1. Application client + 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 diff --git a/README_zh.md b/README_zh.md index 8dc68e09..0406b4d9 100644 --- a/README_zh.md +++ b/README_zh.md @@ -10,19 +10,27 @@ 输入法框架目前有四大模块,具体如下: 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接口,主要是留给输入法进行调用使用的 #### 框架主要支持功能 diff --git a/frameworks/inputmethod_controller/include/input_method_controller.h b/frameworks/inputmethod_controller/include/input_method_controller.h index 474c7de4..c21b54ff 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 153bcd6e..29a476f5 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 e8e3f0be..64e9daa2 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 { +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 - 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 - }; + 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; + }; - /*! \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() + { + this->client = nullptr; + this->channel = nullptr; + }; + }; - 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; - }; + /*! \class PerUserSession + \brief The class provides session management in input method management service - ~ClientInfo() - { - this->client = nullptr; - this->channel = nullptr; - }; - }; + 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 + }; - /*! \class PerUserSession - \brief The class provides session management in input method management service + public: + explicit PerUserSession(int userId); + ~PerUserSession(); - 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 - }; + void SetCurrentIme(InputMethodProperty* ime); + void SetSecurityIme(InputMethodProperty* ime); + void SetInputMethodSetting(InputMethodSetting* setting); + void ResetIme(InputMethodProperty* defaultIme, InputMethodProperty* securityIme); + void OnPackageRemoved(const std::u16string& packageName); - public: - explicit PerUserSession(int userId); - ~PerUserSession(); + int GetDisplayMode(); + int GetKeyboardWindowHeight(int *retHeight); + KeyboardType* GetCurrentKeyboardType(); - 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 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 - int GetDisplayMode(); - int GetKeyboardWindowHeight(int *retHeight); - KeyboardType* GetCurrentKeyboardType(); + InputMethodProperty* currentIme[MAX_IME]; //!< 0 - the default ime. 1 - security ime - 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 */ + 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 - InputMethodProperty* currentIme[MAX_IME]; //!< 0 - the default ime. 1 - security ime - /*!< \n The pointers are referred to the objects in the PerUserSetting */ + 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 - 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 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_; - 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); - - }; - } + 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 db7f4524..8f200a60 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; - } - } - delete msg; - } + /*! Work thread for this user + */ + void PerUserSession::WorkThread() + { + if (msgHandler == nullptr) { + return ; } - - /*! 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 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 input method setting data - \param setting InputMethodSetting pointer referred to the instance in PerUserSetting. - */ - void PerUserSession::SetInputMethodSetting(InputMethodSetting* setting) - { - inputMethodSetting = setting; - } - - /*! 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"); + while(1){ + Message* msg = msgHandler->GetMessage(); 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; + switch(msg->msgId_) { + case MSG_ID_USER_LOCK: + case MSG_ID_EXIT_SERVICE: { + OnUserLocked(); + delete msg; + return; } - if (imsCore[i]) { - StopInputMethod(i); + case MSG_ID_PREPARE_INPUT: { + OnPrepareInput(msg); + break; } - IncreaseOrResetImeError(true, i); - currentIme[i] = ime[i]; - if (currentIme[i]==nullptr) { - if (needReshowClient && GetImeIndex(needReshowClient)==i) { - needReshowClient = nullptr; - } - continue; + case MSG_ID_RELEASE_INPUT: { + OnReleaseInput(msg); + break; } - - 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; - } + case MSG_ID_START_INPUT: { + OnStartInput(msg); + break; } - if (flag) { - int ret = StartInputMethod(i); - if (needReshowClient && GetImeIndex(needReshowClient)==i) { - if (ret==ErrorCode::NO_ERROR) { - ShowKeyboard(needReshowClient); - } - needReshowClient = nullptr; - } + 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; } + } - /*! 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; + /*! 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 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 input method setting data + \param setting InputMethodSetting pointer referred to the instance in PerUserSetting. + */ + void PerUserSession::SetInputMethodSetting(InputMethodSetting* setting) + { + inputMethodSetting = setting; + } + + /*! 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; + } + + 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); - } - - } - - /*! 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; - } - - 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)++; + int ret = StartInputMethod(i); + if (needReshowClient && GetImeIndex(needReshowClient)==i) { + if (ret==ErrorCode::NO_ERROR) { + ShowKeyboard(needReshowClient); } + needReshowClient = nullptr; } } - return ErrorCode::NO_ERROR; + } + } + + /*! 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); + } + } + + /*! 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; } - /*! 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 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; + } - if (imsCore[index] == nullptr) { - IMSA_HILOGI("PerUserSession::StartInputMethod imscore is null"); - return ErrorCode::ERROR_IME_BIND_FAILED; - } + /*! 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); - 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; + 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; } - /*! 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; - } + 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("unbindInputMethodService...\n"); - - 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; + return ErrorCode::NO_ERROR; } - /*! 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; - } + IMSA_HILOGD("unbindInputMethodService...\n"); - 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; - } + 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; + } - ret = imsCore[index]->showKeyboard(1); - if (!ret) { - IMSA_HILOGE("PerUserSession::ShowKeyboard Aborted! showKeyboard has error : %{public}s", ErrorCode::ToString(ret)); + /*! 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 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; - } - - if(clientInfo->client == nullptr){ - IMSA_HILOGI("PerUserSession::ShowKeyboard clientInfo->client is nullptr"); - } - - 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; + 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)); } - 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_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; + return ErrorCode::ERROR_KBD_SHOW_FAILED; } - /*! 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; + if(clientInfo->client == nullptr){ + IMSA_HILOGI("PerUserSession::ShowKeyboard clientInfo->client is nullptr"); } - /*! 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_); + 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; + } + + /*! 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 (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; - } - hashCode = hashCodeList[0]; - } + 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; + } - 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]; - } + 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_); } + 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; } - - /*! 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 (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; } - 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); + hashCode = hashCodeList[0]; } - /*! 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; - } + 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]; } - if (currentClient && (GetImeIndex(currentClient)==index || - currentIme[index] == currentIme[1-index])) { + } + 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; + + 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 = 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); + } + + 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); + + 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 (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(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_); - } - - /*! 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()); - - 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; - } + 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; } + 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;; + /*! 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; } - // 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; } - 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 { - 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; - } - } + inputMethodSetting->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_); - } - } - 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; + } + 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); + } + + /*! 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 ; } - /*! Hide current keyboard - \param flag the flag to hide keyboard. - */ - void PerUserSession::OnHideKeyboardSelf(int flags) - { - IMSA_HILOGW("PerUserSession::OnHideKeyboardSelf"); - (void) flags; + 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); + } + + /*! 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_); + } + } + + /*! 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_); + } + + /*! 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); } - - /*! 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 ; + 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; } - int size = 0; - if (index==SECURITY_IME || currentIme[DEFAULT_IME] == currentIme[SECURITY_IME] ) { - size = currentIme[index]->mTypes.size(); + IMSA_HILOGD("erase client..\n"); + it = mapClients.erase(it); + } + mapClients.clear(); + + // 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 { - 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 ; + dprintf(fd, " [%d] Client Information:\n", index++); } + DumpClientInfo(fd, *(it->second)); + } + 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()); - 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; + 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()); } + } + DumpCurrentSession(fd); + } + + /*! 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); + } + + /*! 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; + } + + 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; + } + 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; + } + + /*! 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; + } + } + } + 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]; + } + } + if (type != nullptr) { InputMethodSetting tmpSetting; - if (imsCore[index] == imsCore[1-index]) { + 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 (index == DEFAULT_IME) { + } 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); } + } - /*! 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_); - } + /*! 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; } - /*! 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_); + ClientInfo *clientInfo = GetClientInfo(inputClient); + if (clientInfo == nullptr) { + IMSA_HILOGW("PerUserSession::GetImeIndex clientInfo is nullptr"); + return -1; } - /*! 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(); - - // reset values - inputMethodSetting = nullptr; - currentClient = nullptr; - needReshowClient = nullptr; + if (clientInfo->attribute.GetSecurityFlag() == true) { + return SECURITY_IME; } + return DEFAULT_IME; + } - /*! 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++); - } - DumpClientInfo(fd, *(it->second)); - } - 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()); + /*! 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]); - 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()); - } - } - DumpCurrentSession(fd); + InputMethodSetting tmpSetting; + tmpSetting.ClearData(); + tmpSetting.SetCurrentKeyboardType(hashCode[0]); + tmpSetting.SetCurrentSysKeyboardType(hashCode[1]); + Platform::Instance()->SetInputMethodSetting(userId_, tmpSetting); } + } - /*! 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); + /*! 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; } - - /*! 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; - } - - 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; - } - 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]; - } - } - } + sptr b = Platform::RemoteBrokerToObject(inputClient); + std::map, ClientInfo*>::iterator it = mapClients.find(b); + if (it == mapClients.end()) { 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; - } - } - } - 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]; - } - } - 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); - } + 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); + } + + /*! 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"); } - /*! 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; - } - - ClientInfo *clientInfo = GetClientInfo(inputClient); - if (clientInfo == nullptr) { - IMSA_HILOGW("PerUserSession::GetImeIndex clientInfo is nullptr"); - return -1; - } - - if (clientInfo->attribute.GetSecurityFlag() == true) { - return SECURITY_IME; - } - return DEFAULT_IME; + 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"); + } - /*! 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]); + /*! 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_; - InputMethodSetting tmpSetting; - tmpSetting.ClearData(); - tmpSetting.SetCurrentKeyboardType(hashCode[0]); - tmpSetting.SetCurrentSysKeyboardType(hashCode[1]); - Platform::Instance()->SetInputMethodSetting(userId_, tmpSetting); - } + sptr clientObject = data->ReadRemoteObject(); + sptr client = new InputClientProxy(clientObject); + sptr interface = client; + int remainClientNum = 0; + if (currentClient == interface) { + HideKeyboard(client); } - - /*! 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; - } - - return (ClientInfo*) it->second; + 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_); + } - 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); - } - - /*! 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"); - } - - /*! 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 aa4a6331..336de404 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){