diff --git a/common/include/global.h b/common/include/global.h index 3748e1939ebbd035879152555e0820043c36fc31..47d61bd7ebd0163210696fa7743c13e14211c497 100644 --- a/common/include/global.h +++ b/common/include/global.h @@ -142,6 +142,7 @@ enum { ERROR_SA_POST_TASK_FAILED, ERROR_IME_HAS_STARTED, ERROR_OPERATION_NOT_ALLOWED, + ERROR_REQUEST_RATE_EXCEEDED, ERROR_IMSA_END, }; }; // namespace ErrorCode diff --git a/frameworks/native/inputmethod_ability/IInputMethodCore.idl b/frameworks/native/inputmethod_ability/IInputMethodCore.idl index aa7aef25795e5398ac454885bbe5faaad9aa7954..557ff1207e93c09c9e93e75d9fc311c8897f3929 100644 --- a/frameworks/native/inputmethod_ability/IInputMethodCore.idl +++ b/frameworks/native/inputmethod_ability/IInputMethodCore.idl @@ -35,4 +35,5 @@ interface OHOS.MiscServices.IInputMethodCore { [oneway] void OnSetInputType([in] int inputType); void OnCallingDisplayIdChanged([in] unsigned long dispalyId); void OnSendPrivateData([in] Value value); + void NotifyPreemption(); } \ No newline at end of file diff --git a/frameworks/native/inputmethod_ability/include/input_method_ability.h b/frameworks/native/inputmethod_ability/include/input_method_ability.h index 08eff1228a7a89842d9fee098d3d9a6f0e09b0e6..e69116c88e4f18480f6297d78522cee86d204666 100644 --- a/frameworks/native/inputmethod_ability/include/input_method_ability.h +++ b/frameworks/native/inputmethod_ability/include/input_method_ability.h @@ -122,6 +122,7 @@ public: int32_t ShowKeyboard(int32_t requestKeyboardReason); int32_t HideKeyboard(); int32_t OnDiscardTypingText(); + int32_t OnNotifyPreemption(); void OnInitInputControlChannel(sptr channelObj); void OnSetSubtype(SubProperty subProperty); diff --git a/frameworks/native/inputmethod_ability/include/input_method_core_service_impl.h b/frameworks/native/inputmethod_ability/include/input_method_core_service_impl.h index dda07ef7a592d3582bd75ba32ffd801c35e55891..049cec6ced358d27c6656a0738cb306355d88d35 100644 --- a/frameworks/native/inputmethod_ability/include/input_method_core_service_impl.h +++ b/frameworks/native/inputmethod_ability/include/input_method_core_service_impl.h @@ -47,6 +47,7 @@ public: ErrCode OnSetInputType(int32_t inputType) override; ErrCode OnCallingDisplayIdChanged(uint64_t dispalyId) override; ErrCode OnSendPrivateData(const Value &Value) override; + ErrCode NotifyPreemption() override; }; } // namespace MiscServices } // namespace OHOS diff --git a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp index bda8812072017d01356468b9c2d7375811eb03b1..3b364924eb02d82ef6d3081027fbb20cce8bc42e 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp @@ -139,6 +139,7 @@ int32_t InputMethodAbility::InitConnect() int32_t InputMethodAbility::UnRegisteredProxyIme(UnRegisteredType type) { + IMSA_HILOGD("type %{public}d", type); isBound_.store(false); auto proxy = GetImsaProxy(); if (proxy == nullptr) { @@ -655,6 +656,7 @@ int32_t InputMethodAbility::InvokeStartInputCallback(const TextTotalConfig &text InvokeAttachOptionsCallback(options, isNotifyInputStart || !isNotify_); if (isNotifyInputStart || !isNotify_) { isNotify_ = true; + IMSA_HILOGD("OnInputStart begin"); imeListener_->OnInputStart(); } if (TextConfig::IsPrivateCommandValid(textConfig.privateCommand) && IsDefaultIme()) { @@ -1950,5 +1952,19 @@ int32_t InputMethodAbility::IsCapacitySupport(int32_t capacity, bool &isSupport) return proxy->IsCapacitySupport(capacity, isSupport); } + +int32_t InputMethodAbility::OnNotifyPreemption() +{ + IMSA_HILOGD("start."); + StopInput(dataChannelObject_, 0); + isBound_.store(false); + auto imeListener = GetImeListener(); + if (imeListener == nullptr) { + return ErrorCode::ERROR_IME_NOT_STARTED; + } + IMSA_HILOGD("notifyPreemption begin."); + imeListener->NotifyPreemption(); + return ErrorCode::NO_ERROR; +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/inputmethod_ability/src/input_method_ability_interface.cpp b/frameworks/native/inputmethod_ability/src/input_method_ability_interface.cpp index 84588700e3fc4cd40e9259d28d58b723b3c806ae..39b8dd50d3d3b68d2df1b2188fb86892f0bdb993 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_ability_interface.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_ability_interface.cpp @@ -97,5 +97,10 @@ void InputMethodAbilityInterface::SetKdListener(std::shared_ptr imeListener); void SetKdListener(std::shared_ptr kdListener); + int32_t SelectByRange(int32_t start, int32_t end); private: InputMethodAbilityInterface() = default; diff --git a/interfaces/inner_api/inputmethod_ability/include/input_method_engine_listener.h b/interfaces/inner_api/inputmethod_ability/include/input_method_engine_listener.h index ffdb16f61bb5b1ac657a3a461b91684d53ec32a7..0b9b15b365874e27accc98ad48802fedaa73916d 100644 --- a/interfaces/inner_api/inputmethod_ability/include/input_method_engine_listener.h +++ b/interfaces/inner_api/inputmethod_ability/include/input_method_engine_listener.h @@ -53,6 +53,8 @@ public: return false; } virtual void OnCallingDisplayIdChanged(uint64_t callingDisplayId) {}; + + virtual void NotifyPreemption() {}; }; } // namespace MiscServices } // namespace OHOS diff --git a/interfaces/inner_api/inputmethod_ability/include/input_method_types.h b/interfaces/inner_api/inputmethod_ability/include/input_method_types.h index a0860972ecf59e1b5795261351318ca3b7d63e7a..b06e646292c550005e0c4acadbc5967d4f98e594 100644 --- a/interfaces/inner_api/inputmethod_ability/include/input_method_types.h +++ b/interfaces/inner_api/inputmethod_ability/include/input_method_types.h @@ -20,7 +20,7 @@ #include "key_event.h" namespace OHOS { namespace MiscServices { -enum class UnRegisteredType : int32_t { REMOVE_PROXY_IME, SWITCH_PROXY_IME_TO_IME, NONE }; +enum class UnRegisteredType : int32_t { REMOVE_PROXY_IME, NONE }; } // namespace MiscServices } // namespace OHOS #endif // INPUTMETHOD_IMF_PROXY_IME_UNREGISTERED_TYPE_H diff --git a/services/include/client_group.h b/services/include/client_group.h index ad39189358e9eb38822fa363dff1273c81d27494..804e9c9a028109f6651e2ebf6853289198f4cec6 100644 --- a/services/include/client_group.h +++ b/services/include/client_group.h @@ -43,7 +43,7 @@ public: void RemoveClientInfo(const sptr &client, bool isClientDied = false); void UpdateClientInfo(const sptr &client, const std::unordered_map> &updateInfos); + std::variant> &updateInfos); std::shared_ptr GetClientInfo(sptr inputClient); std::shared_ptr GetClientInfo(pid_t pid); diff --git a/services/include/peruser_session.h b/services/include/peruser_session.h index fae2727235589117f5cac5089c346393d8848742..0ec8638643d95d111beb4355a493c9b42a2cffea 100644 --- a/services/include/peruser_session.h +++ b/services/include/peruser_session.h @@ -121,8 +121,8 @@ public: int64_t GetInactiveClientPid(uint64_t displayId); int32_t OnPanelStatusChange(const InputWindowStatus &status, const ImeWindowInfo &info, uint64_t displayId); int32_t OnUpdateListenEventFlag(const InputClientInfo &clientInfo); - int32_t OnRegisterProxyIme(const sptr &core, const sptr &agent); - int32_t OnUnRegisteredProxyIme(UnRegisteredType type, const sptr &core); + int32_t OnRegisterProxyIme(const sptr &core, const sptr &agent, int32_t pid); + int32_t OnUnRegisteredProxyIme(UnRegisteredType type, const sptr &core, pid_t pid); int32_t OnBindImeMirror(const sptr &core, const sptr &agent); int32_t OnUnBindImeMirror(); int32_t UpdateLargeMemorySceneState(const int32_t memoryState); @@ -147,6 +147,7 @@ public: int32_t RemoveAllCurrentClient(); std::shared_ptr GetReadyImeData(ImeType type); std::shared_ptr GetImeData(ImeType type); + std::shared_ptr GetImeData(pid_t pid); BlockQueue& GetSwitchQueue(); bool IsWmsReady(); bool CheckPwdInputPatternConv(InputClientInfo &clientInfo, uint64_t displayId); @@ -185,6 +186,10 @@ private: uint32_t num{ 0 }; time_t last{}; }; + enum TimeLimitType : uint32_t { + IME_LIMIT, + PROXY_IME_LIMIT, + }; using CoreMethod = std::function &)>; int32_t userId_; // the id of the user to whom the object is linking @@ -195,7 +200,7 @@ private: #endif static const int MAX_NOTIFY_TIME = 20; std::mutex resetLock; - ResetManager manager; + std::map managers_; using IpcExec = std::function; PerUserSession(const PerUserSession &); @@ -207,7 +212,7 @@ private: BlockQueue switchQueue_{ MAX_WAIT_TIME }; void OnClientDied(sptr remote); - void OnImeDied(const sptr &remote, ImeType type); + void OnImeDied(const sptr &remote, ImeType type, pid_t pid); int AddClientInfo(sptr inputClient, const InputClientInfo &clientInfo, ClientAddEvent event); int32_t RemoveClient(const sptr &client, const std::shared_ptr &clientGroup, @@ -223,8 +228,9 @@ private: const std::shared_ptr &imeNativeCfg = nullptr); int32_t UpdateImeData(sptr core, sptr agent, pid_t pid); int32_t AddImeData(ImeType type, sptr core, sptr agent, pid_t pid); - void RemoveImeData(ImeType type, bool isImeDied); - int32_t RemoveIme(const sptr &core, ImeType type); + void RemoveImeData(ImeType type); + void RemoveImeData(pid_t pid); + int32_t RemoveIme(ImeType type, pid_t pid); int32_t BindClientWithIme(const std::shared_ptr &clientInfo, ImeType type, bool isBindFromClient = false, uint64_t displayId = DEFAULT_DISPLAY_ID); @@ -265,7 +271,7 @@ private: int32_t HandleFirstStart(const std::shared_ptr &ime, bool isStopCurrentIme); int32_t HandleStartImeTimeout(const std::shared_ptr &ime); bool GetInputTypeToStart(std::shared_ptr &imeToStart); - void HandleImeBindTypeChanged(InputClientInfo &newClientInfo, const std::shared_ptr &clientGroup); + void HandleBindImeChanged(InputClientInfo &newClientInfo, const std::shared_ptr &clientGroup); int32_t NotifyCallingDisplayChanged(uint64_t displayId); bool GetCallingWindowInfo(const InputClientInfo &clientInfo, Rosen::CallingWindowInfo &callingWindowInfo); int32_t SendPrivateData(const std::unordered_map &privateCommand); @@ -285,12 +291,15 @@ private: void SetImeConnection(const sptr &connection); sptr GetImeConnection(); void ClearImeConnection(const sptr &connection); + int32_t IsRequestOverLimit(TimeLimitType timeLimit, int32_t resetTimeOut, int32_t restartNum); + int32_t PrepareImeInfos(ImeType type, std::vector> &agents, + std::vector &imeInfos); std::mutex imeStartLock_; BlockData isImeStarted_{ MAX_IME_START_TIME, false }; std::mutex imeDataLock_; - std::unordered_map> imeData_; + std::unordered_map>> imeData_; std::mutex focusedClientLock_; std::atomic isSwitching_ = false; diff --git a/services/src/client_group.cpp b/services/src/client_group.cpp index 3c8852eeee7225a1383373e2b48fbf715c0954c3..c3bdaa28f7bd59689150f9833c96c1707ab20a05 100644 --- a/services/src/client_group.cpp +++ b/services/src/client_group.cpp @@ -99,7 +99,7 @@ void ClientGroup::RemoveClientInfo(const sptr &client, bool isCli } void ClientGroup::UpdateClientInfo(const sptr &client, const std::unordered_map> &updateInfos) + std::variant> &updateInfos) { if (client == nullptr) { IMSA_HILOGE("client is nullptr!"); @@ -141,6 +141,10 @@ void ClientGroup::UpdateClientInfo(const sptr &client, const std: VariantUtil::GetValue(updateInfo.second, it->second->type); break; } + case UpdateFlag::BIND_IME_PID: { + VariantUtil::GetValue(updateInfo.second, it->second->bindImePid); + break; + } default: break; } diff --git a/services/src/input_method_system_ability.cpp b/services/src/input_method_system_ability.cpp index f6009b97dee40927b0036e141b8dab6084476a5c..5b6e6a3f5225cb3dcece483885f347f8a66f088f 100644 --- a/services/src/input_method_system_ability.cpp +++ b/services/src/input_method_system_ability.cpp @@ -837,6 +837,7 @@ ErrCode InputMethodSystemAbility::RequestHideInput(bool isFocusTriggered) ErrCode InputMethodSystemAbility::SetCoreAndAgent(const sptr &core, const sptr &agent) { IMSA_HILOGD("InputMethodSystemAbility start."); + auto pid = IPCSkeleton::GetCallingPid(); auto userId = GetCallingUserId(); auto session = UserSessionManager::GetInstance().GetUserSession(userId); if (session == nullptr) { @@ -844,7 +845,7 @@ ErrCode InputMethodSystemAbility::SetCoreAndAgent(const sptr & return ErrorCode::ERROR_NULL_POINTER; } if (identityChecker_->IsNativeSa(IPCSkeleton::GetCallingTokenID())) { - return session->OnRegisterProxyIme(core, agent); + return session->OnRegisterProxyIme(core, agent, pid); } if (!IsCurrentIme(userId)) { IMSA_HILOGE("not current ime, userId:%{public}d", userId); @@ -2177,6 +2178,7 @@ int32_t InputMethodSystemAbility::GetSecurityMode(int32_t &security) ErrCode InputMethodSystemAbility::UnRegisteredProxyIme(int32_t type, const sptr &core) { + pid_t pid = IPCSkeleton::GetCallingPid(); if (!identityChecker_->IsNativeSa(IPCSkeleton::GetCallingTokenID())) { IMSA_HILOGE("not native sa!"); return ErrorCode::ERROR_STATUS_PERMISSION_DENIED; @@ -2187,14 +2189,7 @@ ErrCode InputMethodSystemAbility::UnRegisteredProxyIme(int32_t type, const sptr< IMSA_HILOGE("%{public}d session is nullptr!", userId); return ErrorCode::ERROR_NULL_POINTER; } - if (static_cast(type) == UnRegisteredType::SWITCH_PROXY_IME_TO_IME) { - int32_t ret = ErrorCode::NO_ERROR; - ret = session->StartCurrentIme(); - if (ret != ErrorCode::NO_ERROR) { - return ret; - } - } - return session->OnUnRegisteredProxyIme(static_cast(type), core); + return session->OnUnRegisteredProxyIme(static_cast(type), core, pid); } int32_t InputMethodSystemAbility::CheckEnableAndSwitchPermission() diff --git a/services/src/peruser_session.cpp b/services/src/peruser_session.cpp index 5d999c8ee0993d25728add51bb9418a0b8a055c4..fa470129829b70ab10e5774495665727d76ddc52 100644 --- a/services/src/peruser_session.cpp +++ b/services/src/peruser_session.cpp @@ -68,6 +68,8 @@ constexpr const char *UNDEFINED = "undefined"; constexpr int32_t WAIT_ATTACH_FINISH_DELAY = 50; constexpr int32_t WAIT_ATTACH_FINISH_MAX_TIMES = 20; constexpr uint32_t MAX_SCB_START_COUNT = 2; +constexpr uint32_t PROXY_REGISTERATION_TIME_INTERVAL = 1; // 1s +constexpr uint32_t MAX_REGISTRATIONS_NUM = 3; PerUserSession::PerUserSession(int userId) : userId_(userId) { } PerUserSession::PerUserSession(int32_t userId, const std::shared_ptr &eventHandler) @@ -206,28 +208,28 @@ void PerUserSession::OnClientDied(sptr remote) * It's called when an ime died * @param the remote object handler of the ime who died. */ -void PerUserSession::OnImeDied(const sptr &remote, ImeType type) +void PerUserSession::OnImeDied(const sptr &remote, ImeType type, pid_t pid) { if (remote == nullptr) { return; } IMSA_HILOGI("type: %{public}d.", type); - auto imeData = GetImeData(type); + auto imeData = GetImeData(pid); if (imeData != nullptr && imeData->imeStatus == ImeStatus::EXITING) { - RemoveImeData(type, true); + RemoveImeData(pid); InputTypeManager::GetInstance().Set(false); NotifyImeStopFinished(); IMSA_HILOGI("%{public}d not current imeData.", type); return; } - RemoveImeData(type, true); + RemoveImeData(pid); if (!OsAccountAdapter::IsOsAccountForeground(userId_)) { IMSA_HILOGW("userId:%{public}d in background, no need to restart ime.", userId_); return; } auto clientGroup = GetClientGroup(type); auto clientInfo = clientGroup != nullptr ? clientGroup->GetCurrentClientInfo() : nullptr; - if (clientInfo != nullptr && clientInfo->bindImeType == type) { + if (clientInfo != nullptr && clientInfo->bindImeType == type && clientInfo->bindImePid == pid) { clientGroup->NotifyInputStopToClients(); StopClientInput(clientInfo); if (type == ImeType::IME) { @@ -254,22 +256,14 @@ void PerUserSession::OnImeDied(const sptr &remote, ImeType typ } } -int32_t PerUserSession::RemoveIme(const sptr &core, ImeType type) +int32_t PerUserSession::RemoveIme(ImeType type, pid_t pid) { - if (core == nullptr) { - return ErrorCode::ERROR_NULL_POINTER; - } - auto data = GetReadyImeData(type); - if (data == nullptr || data->core->AsObject() != core->AsObject()) { - return ErrorCode::ERROR_IME_NOT_STARTED; - } - auto clientGroup = GetClientGroup(type); auto clientInfo = clientGroup != nullptr ? clientGroup->GetCurrentClientInfo() : nullptr; - if (clientInfo != nullptr && clientInfo->bindImeType == type) { + if (clientInfo != nullptr && clientInfo->bindImeType == type && clientInfo->bindImePid == pid) { UnBindClientWithIme(clientInfo, { .sessionId = 0 }); } - RemoveImeData(type, true); + RemoveImeData(pid); return ErrorCode::NO_ERROR; } @@ -532,8 +526,8 @@ bool PerUserSession::IsProxyImeEnable() return ret; } -int32_t PerUserSession::OnStartInput(const InputClientInfo &inputClientInfo, std::vector> &agents, - std::vector &imeInfos) +int32_t PerUserSession::OnStartInput(const InputClientInfo &inputClientInfo, + std::vector> &agents, std::vector &imeInfos) { const sptr &client = inputClientInfo.client; if (client == nullptr) { @@ -554,9 +548,16 @@ int32_t PerUserSession::OnStartInput(const InputClientInfo &inputClientInfo, std infoTemp.isNotifyInputStart = inputClientInfo.isNotifyInputStart; ImeType imeType = GetImeType(inputClientInfo.displayId); if (GetDisplayGroupId(inputClientInfo.displayId) == DEFAULT_DISPLAY_ID) { - HandleImeBindTypeChanged(infoTemp, clientGroup); imeType = IsProxyImeEnable() ? ImeType::PROXY_IME : ImeType::IME; } + auto data = GetReadyImeData(imeType); + if (data == nullptr || data->agent == nullptr) { + IMSA_HILOGE("data or agent is nullptr!"); + return ErrorCode::ERROR_IME_NOT_STARTED; + } + infoTemp.bindImePid = data->pid; + infoTemp.bindImeType = imeType; + HandleBindImeChanged(infoTemp, clientGroup); infoTemp.isShowKeyboard = inputClientInfo.isShowKeyboard; infoTemp.needHide = inputClientInfo.needHide; infoTemp.requestKeyboardReason = inputClientInfo.requestKeyboardReason; @@ -567,22 +568,7 @@ int32_t PerUserSession::OnStartInput(const InputClientInfo &inputClientInfo, std IMSA_HILOGE("bind failed, ret: %{public}d!", ret); return ret; } - auto allData = GetAllReadyImeData(imeType); - if (allData.empty()) { - IMSA_HILOGE("allData is empty!"); - return ErrorCode::ERROR_IME_NOT_STARTED; - } - - for (auto &data : allData) { - if (data->agent == nullptr) { - IMSA_HILOGE("agent is nullptr!"); - return ErrorCode::ERROR_IME_NOT_STARTED; - } - agents.emplace_back(data->agent); - BindImeInfo imeInfo = { data->pid, data->ime.first }; - imeInfos.emplace_back(imeInfo); - } - return ErrorCode::NO_ERROR; + return PrepareImeInfos(imeType, agents, imeInfos); } int32_t PerUserSession::SendAllReadyImeToClient( @@ -666,7 +652,8 @@ int32_t PerUserSession::BindClientWithIme( } } clientGroup->UpdateClientInfo(clientInfo->client->AsObject(), { { UpdateFlag::BINDIMETYPE, type }, - { UpdateFlag::ISSHOWKEYBOARD, clientInfo->isShowKeyboard }, { UpdateFlag::STATE, ClientState::ACTIVE } }); + { UpdateFlag::ISSHOWKEYBOARD, clientInfo->isShowKeyboard }, { UpdateFlag::STATE, ClientState::ACTIVE }, + { UpdateFlag::BIND_IME_PID, data->pid} }); ReplaceCurrentClient(clientInfo->client, clientGroup); if (clientInfo->isShowKeyboard) { clientGroup->NotifyInputStartToClients( @@ -776,11 +763,22 @@ int32_t PerUserSession::OnSetCoreAndAgent(const sptr &core, co return ErrorCode::NO_ERROR; } -int32_t PerUserSession::OnRegisterProxyIme(const sptr &core, const sptr &agent) +int32_t PerUserSession::OnRegisterProxyIme(const sptr &core, const sptr &agent, + int32_t pid) { IMSA_HILOGD("start."); + auto result = IsRequestOverLimit(TimeLimitType::PROXY_IME_LIMIT, PROXY_REGISTERATION_TIME_INTERVAL, + MAX_REGISTRATIONS_NUM); + if (result != ErrorCode::NO_ERROR) { + IMSA_HILOGI("frequent calls, service is busy."); + return result; + } auto imeType = ImeType::PROXY_IME; - auto ret = AddImeData(imeType, core, agent, IPCSkeleton::GetCallingPid()); + auto lastImeData = GetImeData(imeType); + if (lastImeData != nullptr && lastImeData->core != nullptr && lastImeData->core->AsObject() != core->AsObject()) { + lastImeData->core->NotifyPreemption(); + } + auto ret = AddImeData(imeType, core, agent, pid); if (ret != ErrorCode::NO_ERROR) { return ret; } @@ -847,7 +845,7 @@ int32_t PerUserSession::OnUnregisterProxyIme(uint64_t displayId) if (displayId != agentDisplayId_.load()) { return false; } - RemoveImeData(ImeType::PROXY_AGENT_IME, false); + RemoveImeData(ImeType::PROXY_AGENT_IME); { std::lock_guard lock(virtualDisplayLock_); virtualScreenDisplayId_.erase(displayId); @@ -861,29 +859,14 @@ int32_t PerUserSession::OnUnregisterProxyIme(uint64_t displayId) return ErrorCode::NO_ERROR; } -int32_t PerUserSession::OnUnRegisteredProxyIme(UnRegisteredType type, const sptr &core) +int32_t PerUserSession::OnUnRegisteredProxyIme(UnRegisteredType type, const sptr &core, pid_t pid) { IMSA_HILOGD("proxy unregister type: %{public}d.", type); // 0: stop proxy 1: switch to ima if (type == UnRegisteredType::REMOVE_PROXY_IME) { - RemoveIme(core, ImeType::PROXY_IME); + RemoveIme(ImeType::PROXY_IME, pid); return ErrorCode::NO_ERROR; } - if (type == UnRegisteredType::SWITCH_PROXY_IME_TO_IME) { - auto clientInfo = GetCurrentClientInfo(); - if (clientInfo == nullptr) { - IMSA_HILOGE("not found current client!"); - return ErrorCode::ERROR_CLIENT_NOT_BOUND; - } - if (clientInfo->bindImeType == ImeType::PROXY_IME) { - UnBindClientWithIme(clientInfo, { .sessionId = 0 }); - } - InputClientInfo infoTemp; - infoTemp.isShowKeyboard = true; - infoTemp.client = clientInfo->client; - infoTemp.channel = clientInfo->channel; - return BindClientWithIme(std::make_shared(infoTemp), ImeType::IME); - } return ErrorCode::ERROR_BAD_PARAMETERS; } @@ -907,7 +890,7 @@ int32_t PerUserSession::OnUnBindImeMirror() IMSA_HILOGD("[ImeMirrorTag]start"); auto clientInfo = GetCurrentClientInfo(); if (clientInfo == nullptr) { - RemoveImeData(ImeType::IME_MIRROR, false); + RemoveImeData(ImeType::IME_MIRROR); IMSA_HILOGD("[ImeMirrorTag]no current client"); return ErrorCode::NO_ERROR; } @@ -920,7 +903,7 @@ int32_t PerUserSession::OnUnBindImeMirror() clientInfo->client->OnImeMirrorStop(data->agent); StopImeInput(ImeType::IME_MIRROR, clientInfo->channel, 0); - RemoveImeData(ImeType::IME_MIRROR, false); + RemoveImeData(ImeType::IME_MIRROR); return ErrorCode::NO_ERROR; } @@ -956,13 +939,8 @@ void PerUserSession::StartImeInImeDied() { IMSA_HILOGD("StartImeInImeDied."); { - std::lock_guard lock(resetLock); - auto now = time(nullptr); - if (difftime(now, manager.last) > IME_RESET_TIME_OUT) { - manager = { 0, now }; - } - ++manager.num; - if (manager.num > MAX_RESTART_NUM) { + auto result = IsRequestOverLimit(TimeLimitType::IME_LIMIT, IME_RESET_TIME_OUT, MAX_RESTART_NUM); + if (result != ErrorCode::NO_ERROR) { return; } } @@ -1038,18 +1016,31 @@ int32_t PerUserSession::AddImeData(ImeType type, sptr core, sp IMSA_HILOGE("core or agent is nullptr!"); return ErrorCode::ERROR_NULL_POINTER; } + std::lock_guard lock(imeDataLock_); + auto &imeDataList = imeData_[type]; + auto iter = std::find_if( + imeDataList.begin(), imeDataList.end(), [&core, this](const std::shared_ptr &existingImeData) { + return existingImeData != nullptr && core->AsObject() == existingImeData->core->AsObject(); + }); + if (iter != imeDataList.end()) { + auto imeData = *iter; + imeDataList.erase(iter); + IMSA_HILOGI("%{public}s preempt again!", imeData->ime.first.c_str()); + imeDataList.push_back(imeData); + return ErrorCode::NO_ERROR; + } sptr deathRecipient = new (std::nothrow) InputDeathRecipient(); if (deathRecipient == nullptr) { IMSA_HILOGE("failed to new deathRecipient!"); return ErrorCode::ERROR_NULL_POINTER; } - deathRecipient->SetDeathRecipient([this, core, type](const wptr &) { this->OnImeDied(core, type); }); + deathRecipient->SetDeathRecipient( + [this, core, type, pid](const wptr &) { this->OnImeDied(core, type, pid); }); auto coreObject = core->AsObject(); if (coreObject == nullptr || (coreObject->IsProxyObject() && !coreObject->AddDeathRecipient(deathRecipient))) { IMSA_HILOGE("failed to add death recipient!"); return ErrorCode::ERROR_ADD_DEATH_RECIPIENT_FAILED; } - std::lock_guard lock(imeDataLock_); auto imeData = std::make_shared(core, agent, deathRecipient, pid); imeData->imeStatus = ImeStatus::READY; imeData->ime.first = "proxyIme"; @@ -1063,22 +1054,18 @@ int32_t PerUserSession::AddImeData(ImeType type, sptr core, sp } else if (type == ImeType::IME_MIRROR) { imeData->ime.first.append(GET_NAME(_IME_MIRROR)); } - imeData_.insert_or_assign(type, imeData); + imeDataList.push_back(imeData); IMSA_HILOGI("add imeData with type: %{public}d name: %{public}s end", type, imeData->ime.first.c_str()); return ErrorCode::NO_ERROR; } std::shared_ptr PerUserSession::GetReadyImeData(ImeType type) { - std::lock_guard lock(imeDataLock_); - auto it = imeData_.find(type); - if (it == imeData_.end()) { - return nullptr; - } - if (it->second->imeStatus != ImeStatus::READY) { + auto data = GetImeData(type); + if (data == nullptr || data->imeStatus != ImeStatus::READY) { return nullptr; } - return it->second; + return data; } std::vector> PerUserSession::GetAllReadyImeData(ImeType type) @@ -1100,7 +1087,30 @@ std::vector> PerUserSession::GetAllReadyImeData(ImeType return { typeData, imeMirrorData }; } -void PerUserSession::RemoveImeData(ImeType type, bool isImeDied) +void PerUserSession::RemoveImeData(pid_t pid) +{ + std::lock_guard lock(imeDataLock_); + for (auto itType = imeData_.begin(); itType != imeData_.end(); ++itType) { + auto &imeDataList = itType->second; + auto iter = + std::find_if(imeDataList.begin(), imeDataList.end(), [pid](const std::shared_ptr &imeDataTmp) { + return imeDataTmp != nullptr && imeDataTmp->pid == pid; + }); + if (iter != imeDataList.end()) { + auto imeData = *iter; + if (imeData != nullptr && imeData->core != nullptr && imeData->core->AsObject() != nullptr) { + imeData->core->AsObject()->RemoveDeathRecipient(imeData->deathRecipient); + } + imeDataList.erase(iter); + if (imeDataList.empty()) { + imeData_.erase(itType); + } + break; + } + } +} + +void PerUserSession::RemoveImeData(ImeType type) { std::lock_guard lock(imeDataLock_); auto it = imeData_.find(type); @@ -1108,9 +1118,10 @@ void PerUserSession::RemoveImeData(ImeType type, bool isImeDied) IMSA_HILOGD("imeData not found."); return; } - auto data = it->second; - if (isImeDied && data->core != nullptr && data->core->AsObject() != nullptr) { - data->core->AsObject()->RemoveDeathRecipient(data->deathRecipient); + for (auto imeData : it->second) { + if (imeData != nullptr && imeData->core != nullptr && imeData->core->AsObject() != nullptr) { + imeData->core->AsObject()->RemoveDeathRecipient(imeData->deathRecipient); + } } imeData_.erase(type); } @@ -1930,7 +1941,7 @@ int32_t PerUserSession::InitImeData( if (imeNativeCfg != nullptr && !imeNativeCfg->imeExtendInfo.privateCommand.empty()) { imeData->imeExtendInfo.privateCommand = imeNativeCfg->imeExtendInfo.privateCommand; } - imeData_.insert({ ImeType::IME, imeData }); + imeData_.insert_or_assign(ImeType::IME, std::vector>{imeData}); return ErrorCode::NO_ERROR; } @@ -1945,10 +1956,14 @@ int32_t PerUserSession::UpdateImeData(sptr core, sptrsecond->core = core; - it->second->agent = agent; - it->second->pid = pid; - it->second->imeStateManager = ImeStateManagerFactory::GetInstance().CreateImeStateManager(pid, [this] { + auto &dataList = it->second; + if (dataList.empty() || dataList.back() == nullptr) { + return ErrorCode::ERROR_NULL_POINTER; + } + dataList.back()->core = core; + dataList.back()->agent = agent; + dataList.back()->pid = pid; + dataList.back()->imeStateManager = ImeStateManagerFactory::GetInstance().CreateImeStateManager(pid, [this] { StopCurrentIme(); }); sptr deathRecipient = new (std::nothrow) InputDeathRecipient(); @@ -1957,13 +1972,14 @@ int32_t PerUserSession::UpdateImeData(sptr core, sptrSetDeathRecipient([this, core, type](const wptr &) { this->OnImeDied(core, type); }); + deathRecipient->SetDeathRecipient( + [this, core, type, pid](const wptr &) { this->OnImeDied(core, type, pid); }); auto coreObject = core->AsObject(); if (coreObject == nullptr || (coreObject->IsProxyObject() && !coreObject->AddDeathRecipient(deathRecipient))) { IMSA_HILOGE("failed to add death recipient!"); return ErrorCode::ERROR_ADD_DEATH_RECIPIENT_FAILED; } - it->second->deathRecipient = deathRecipient; + dataList.back()->deathRecipient = deathRecipient; return ErrorCode::NO_ERROR; } @@ -1974,7 +1990,11 @@ int32_t PerUserSession::InitConnect(pid_t pid) if (it == imeData_.end()) { return ErrorCode::ERROR_NULL_POINTER; } - it->second->pid = pid; + auto &dataList = it->second; + if (dataList.empty() || dataList.back() == nullptr) { + return ErrorCode::ERROR_NULL_POINTER; + } + dataList.back()->pid = pid; return ErrorCode::NO_ERROR; } @@ -1985,7 +2005,26 @@ std::shared_ptr PerUserSession::GetImeData(ImeType type) if (it == imeData_.end()) { return nullptr; } - return it->second; + auto &dataList = it->second; + if (dataList.empty() || dataList.back() == nullptr) { + return nullptr; + } + return dataList.back(); +} + +std::shared_ptr PerUserSession::GetImeData(pid_t pid) +{ + std::lock_guard lock(imeDataLock_); + for (const auto &[imeType, imeDataList] : imeData_) { + auto iter = + std::find_if(imeDataList.begin(), imeDataList.end(), [pid](const std::shared_ptr &imeDataTmp) { + return imeDataTmp != nullptr && imeDataTmp->pid == pid; + }); + if (iter != imeDataList.end()) { + return *iter; + } + } + return nullptr; } int32_t PerUserSession::StartIme(const std::shared_ptr &ime, bool isStopCurrentIme) @@ -2019,12 +2058,16 @@ ImeAction PerUserSession::GetImeAction(ImeEvent action) if (it == imeData_.end()) { return ImeAction::DO_ACTION_IN_NULL_IME_DATA; } - auto iter = imeEventConverter_.find({ it->second->imeStatus, action }); + auto &dataList = it->second; + if (dataList.empty() || dataList.back() == nullptr) { + return ImeAction::DO_ACTION_IN_NULL_IME_DATA; + } + auto iter = imeEventConverter_.find({ dataList.back()->imeStatus, action }); if (iter == imeEventConverter_.end()) { IMSA_HILOGE("abnormal!"); return ImeAction::DO_ACTION_IN_IME_EVENT_CONVERT_FAILED; } - it->second->imeStatus = iter->second.first; + dataList.back()->imeStatus = iter->second.first; return iter->second.second; } @@ -2145,7 +2188,7 @@ int32_t PerUserSession::ForceStopCurrentIme(bool isNeedWait) } if (!ImeInfoInquirer::GetInstance().IsRunningIme(userId_, imeData->ime.first)) { IMSA_HILOGW("[%{public}s, %{public}s] already stop.", imeData->ime.first.c_str(), imeData->ime.second.c_str()); - RemoveImeData(ImeType::IME, true); + RemoveImeData(ImeType::IME); return ErrorCode::NO_ERROR; } auto clientInfo = GetCurrentClientInfo(); @@ -2170,7 +2213,7 @@ int32_t PerUserSession::ForceStopCurrentIme(bool isNeedWait) IMSA_HILOGW("stop [%{public}s, %{public}s] timeout.", imeData->ime.first.c_str(), imeData->ime.second.c_str()); return ErrorCode::ERROR_IMSA_FORCE_STOP_IME_TIMEOUT; } - RemoveImeData(ImeType::IME, true); + RemoveImeData(ImeType::IME); return ErrorCode::NO_ERROR; } @@ -2273,7 +2316,7 @@ bool PerUserSession::GetInputTypeToStart(std::shared_ptr &imeToSta return true; } -void PerUserSession::HandleImeBindTypeChanged( +void PerUserSession::HandleBindImeChanged( InputClientInfo &newClientInfo, const std::shared_ptr &clientGroup) { /* isClientInactive: true: represent the oldClientInfo is inactiveClient's @@ -2297,6 +2340,10 @@ void PerUserSession::HandleImeBindTypeChanged( if (oldClientInfo == nullptr) { return; } + if (IsSameClient(newClientInfo.client, oldClientInfo->client) && + newClientInfo.bindImePid != oldClientInfo->bindImePid) { + newClientInfo.isNotifyInputStart = true; + } if (!IsImeBindTypeChanged(oldClientInfo->bindImeType)) { return; } @@ -2309,9 +2356,6 @@ void PerUserSession::HandleImeBindTypeChanged( } } IMSA_HILOGD("isClientInactive: %{public}d!", isClientInactive); - if (IsSameClient(newClientInfo.client, oldClientInfo->client)) { - newClientInfo.isNotifyInputStart = true; - } if (isClientInactive) { StopImeInput(oldClientInfo->bindImeType, oldClientInfo->channel, 0); return; @@ -2764,5 +2808,41 @@ void PerUserSession::ClearImeConnection(const sptr &c IMSA_HILOGI("clear imeConnection."); connection_ = nullptr; } + +int32_t PerUserSession::IsRequestOverLimit(TimeLimitType timeLimitType, int32_t resetTimeOut, int32_t restartNum) +{ + std::lock_guard lock(resetLock); + auto now = time(nullptr); + auto& manager = managers_[timeLimitType]; + if (difftime(now, manager.last) > resetTimeOut) { + manager = {0, now}; + } + ++manager.num; + if (manager.num > restartNum) { + return ErrorCode::ERROR_REQUEST_RATE_EXCEEDED; + } + return ErrorCode::NO_ERROR; +} + +int32_t PerUserSession::PrepareImeInfos(ImeType type, std::vector> &agents, + std::vector &imeInfos) +{ + auto allData = GetAllReadyImeData(type); + if (allData.empty()) { + IMSA_HILOGE("allData is empty!"); + return ErrorCode::ERROR_IME_NOT_STARTED; + } + + for (auto &data : allData) { + if (data->agent == nullptr) { + IMSA_HILOGE("agent is nullptr!"); + return ErrorCode::ERROR_IME_NOT_STARTED; + } + agents.emplace_back(data->agent); + BindImeInfo imeInfo = { data->pid, data->ime.first }; + imeInfos.emplace_back(imeInfo); + } + return ErrorCode::NO_ERROR; +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/test/fuzztest/perusersession_fuzzer/perusersession_fuzzer.cpp b/test/fuzztest/perusersession_fuzzer/perusersession_fuzzer.cpp index 9f981fdac7859574b24bda819ef7909899e3ede9..22983e8a8ad0ab46b49505af78ddf68183b50c61 100644 --- a/test/fuzztest/perusersession_fuzzer/perusersession_fuzzer.cpp +++ b/test/fuzztest/perusersession_fuzzer/perusersession_fuzzer.cpp @@ -93,10 +93,10 @@ bool FuzzPerUserSession(const uint8_t *rawData, size_t size) auto agent = iface_cast(agentStub); static std::shared_ptr userSessions = std::make_shared(MAIN_USER_ID); - userSessions->OnRegisterProxyIme(core, agent->AsObject()); + userSessions->OnRegisterProxyIme(core, agent->AsObject(), -1); FuzzedDataProvider provider(rawData, size); int32_t type = provider.ConsumeIntegral(); - userSessions->OnUnRegisteredProxyIme(static_cast(type), core); + userSessions->OnUnRegisteredProxyIme(static_cast(type), core, -1); userSessions->IsProxyImeEnable(); userSessions->OnPrepareInput(clientInfo); diff --git a/test/unittest/cpp_test/BUILD.gn b/test/unittest/cpp_test/BUILD.gn index f2ff1d9c2ba31191e0d486ad7467d012a337a2a7..f4881ad1013865eed968c142de3e8f47b3f40f8e 100644 --- a/test/unittest/cpp_test/BUILD.gn +++ b/test/unittest/cpp_test/BUILD.gn @@ -932,7 +932,9 @@ ohos_unittest("ImeProxyTest") { "${inputmethod_path}/interfaces/inner_api/inputmethod_controller:input_client_stub", "${inputmethod_path}/interfaces/inner_api/inputmethod_controller:input_method_agent_proxy", "${inputmethod_path}/interfaces/inner_api/inputmethod_controller:inputmethod_client_static", - "${inputmethod_path}/services:inputmethod_service", + "${inputmethod_path}/services/adapter/settings_data_provider:settings_data_static", + "${inputmethod_path}/services:inputmethod_service_static", + "${inputmethod_path}/services/json:imf_json_static", "${inputmethod_path}/test/common:inputmethod_test_common", "${inputmethod_path}/test/unittest/cpp_test/common:inputmethod_tdd_util", "${inputmethod_path}/test/unittest/resource/bundle_dependencies/editorBox:editorBox", @@ -948,6 +950,9 @@ ohos_unittest("ImeProxyTest") { "access_token:libaccesstoken_sdk", "bundle_framework:appexecfwk_core", "c_utils:utils", + "cJSON:cjson", + "data_share:datashare_common", + "data_share:datashare_consumer", "googletest:gtest_main", "graphic_2d:librender_service_client", "graphic_2d:window_animation", diff --git a/test/unittest/cpp_test/src/ime_proxy_test.cpp b/test/unittest/cpp_test/src/ime_proxy_test.cpp index 72cfb645bcdd6e9f1acb2afcb811da06bc5b8f04..62a3494e1ef9617ec08d2e5cd6b9ebbcca5f12cf 100644 --- a/test/unittest/cpp_test/src/ime_proxy_test.cpp +++ b/test/unittest/cpp_test/src/ime_proxy_test.cpp @@ -14,8 +14,10 @@ */ #define private public +#define protected public #include "input_method_ability.h" #include "task_manager.h" +#include "ime_info_inquirer.h" #undef private #include @@ -380,8 +382,6 @@ HWTEST_F(ImeProxyTest, UnRegisteredProxyNotInBind_switch_009, TestSize.Level1) InputMethodEngineListenerImpl::isEnable_ = true; auto ret = InputMethodAbilityInterface::GetInstance().RegisteredProxy(); EXPECT_EQ(ret, ErrorCode::NO_ERROR); - ret = InputMethodAbilityInterface::GetInstance().UnRegisteredProxy(UnRegisteredType::SWITCH_PROXY_IME_TO_IME); - EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_BOUND); } /** @@ -405,10 +405,6 @@ HWTEST_F(ImeProxyTest, UnRegisteredProxyInProxyBind_switch_010, TestSize.Level1) ImeSettingListenerTestImpl::ResetParam(); InputMethodEngineListenerImpl::ResetParam(); - ret = InputMethodAbilityInterface::GetInstance().UnRegisteredProxy(UnRegisteredType::SWITCH_PROXY_IME_TO_IME); - EXPECT_EQ(ret, ErrorCode::NO_ERROR); - EXPECT_TRUE(InputMethodEngineListenerImpl::WaitInputFinish()); - EXPECT_TRUE(ImeSettingListenerTestImpl::WaitPanelShow()); Close(false); TddUtil::GetUnfocused(); } @@ -674,14 +670,30 @@ HWTEST_F(ImeProxyTest, DiscardTypingTextTest, TestSize.Level0) * @tc.desc: Test RegisterProxyIme * @tc.type: FUNC */ -HWTEST_F(ImeProxyTest, RegisterProxyImeTest, TestSize.Level0) +HWTEST_F(ImeProxyTest, RegisterProxyImeTest001, TestSize.Level0) { - IMSA_HILOGI("ImeProxyTest::TestRegisterProxyImeTest"); + IMSA_HILOGI("ImeProxyTest::TestRegisterProxyImeTest001 start"); uint64_t displayId = -1; auto ret = InputMethodAbilityInterface::GetInstance().RegisterProxyIme(displayId); EXPECT_NE(ret, ErrorCode::NO_ERROR); ret = InputMethodAbilityInterface::GetInstance().UnregisterProxyIme(displayId); EXPECT_NE(ret, ErrorCode::NO_ERROR); } + +/** + * @tc.name: TestRegisterProxyIme + * @tc.desc: Test RegisterProxyIme failed + * @tc.type: FUNC + */ +HWTEST_F(ImeProxyTest, RegisterProxyImeTest002, TestSize.Level0) +{ + IMSA_HILOGI("ImeProxyTest::RegisterProxyImeTest002 start"); + uint64_t displayId = 0; + auto ret = InputMethodAbilityInterface::GetInstance().RegisterProxyIme(displayId); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + std::shared_ptr property = imc_->GetCurrentInputMethod(); + ASSERT_TRUE(property != nullptr); + EXPECT_EQ(property->name, "com.example.testIme"); +} } // namespace MiscServices } // namespace OHOS diff --git a/test/unittest/cpp_test/src/input_method_controller_test.cpp b/test/unittest/cpp_test/src/input_method_controller_test.cpp index cdc38ed0e72d1904427b5363ea684ab5d55a62f0..d54d1b50e834bdb954646236267d1c1949ae5784 100644 --- a/test/unittest/cpp_test/src/input_method_controller_test.cpp +++ b/test/unittest/cpp_test/src/input_method_controller_test.cpp @@ -2161,7 +2161,7 @@ HWTEST_F(InputMethodControllerTest, TestClientNullptr, TestSize.Level0) auto ret = sessionTemp->OnUpdateListenEventFlag(clientInfo); EXPECT_EQ(ret, ErrorCode::ERROR_NULL_POINTER); - sessionTemp->HandleImeBindTypeChanged(clientInfo, nullptr); + sessionTemp->HandleBindImeChanged(clientInfo, nullptr); std::shared_ptr ptr = nullptr; sessionTemp->ClearRequestKeyboardReason(ptr); auto info = std::make_shared(); diff --git a/test/unittest/cpp_test/src/input_method_private_member_test.cpp b/test/unittest/cpp_test/src/input_method_private_member_test.cpp index 3a6a329d87b7542afc6ee1f0422428780433bc45..3f6251f081c1eefbf67a06097b8f4196951ae43f 100644 --- a/test/unittest/cpp_test/src/input_method_private_member_test.cpp +++ b/test/unittest/cpp_test/src/input_method_private_member_test.cpp @@ -343,11 +343,11 @@ HWTEST_F(InputMethodPrivateMemberTest, PerUserSessionParameterNullptr001, TestSi { IMSA_HILOGI("InputMethodPrivateMemberTest PerUserSessionParameterNullptr001 TEST START"); auto userSession = std::make_shared(MAIN_USER_ID); + std::vector> agents; InputClientInfo clientInfo; clientInfo.client = nullptr; - std::vector> agents; - std::vector imeInfos; - int32_t ret = userSession->OnStartInput(clientInfo, agents, imeInfos); + std::vector imeInfo; + int32_t ret = userSession->OnStartInput(clientInfo, agents, imeInfo); EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NULL_POINTER); ret = userSession->OnReleaseInput(nullptr, 0); EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NULL_POINTER); @@ -356,26 +356,6 @@ HWTEST_F(InputMethodPrivateMemberTest, PerUserSessionParameterNullptr001, TestSi EXPECT_EQ(client, nullptr); } -/** - * @tc.name: PerUserSessionParameterNullptr003 - * @tc.desc: Test PerUserSession with parameter nullptr. - * @tc.type: FUNC - * @tc.require: issuesI794QF - * @tc.author: Zhaolinglan - */ -HWTEST_F(InputMethodPrivateMemberTest, PerUserSessionParameterNullptr003, TestSize.Level0) -{ - IMSA_HILOGI("InputMethodPrivateMemberTest PerUserSessionParameterNullptr003 TEST START"); - auto userSession = std::make_shared(MAIN_USER_ID); - auto clientGroup = std::make_shared(DEFAULT_DISPLAY_ID, nullptr); - userSession->OnClientDied(nullptr); - userSession->OnImeDied(nullptr, ImeType::IME); - bool isShowKeyboard = false; - clientGroup->UpdateClientInfo(nullptr, { { UpdateFlag::ISSHOWKEYBOARD, isShowKeyboard } }); - int32_t ret = userSession->RemoveIme(nullptr, ImeType::IME); - EXPECT_EQ(ret, ErrorCode::ERROR_NULL_POINTER); -} - /** * @tc.name: SA_ImeCfgManagerTest_002 * @tc.desc: getImeCfg failed @@ -903,7 +883,7 @@ HWTEST_F(InputMethodPrivateMemberTest, IMC_testDeactivateClient, TestSize.Level0 */ HWTEST_F(InputMethodPrivateMemberTest, testIsPanelShown, TestSize.Level0) { - IMSA_HILOGI("InputMethodPrivateMemberTest PerUserSessionParameterNullptr003 TEST START"); + IMSA_HILOGI("InputMethodPrivateMemberTest testIsPanelShown TEST START"); auto userSession = std::make_shared(MAIN_USER_ID); PanelInfo panelInfo; panelInfo.panelType = SOFT_KEYBOARD; @@ -1174,11 +1154,8 @@ HWTEST_F(InputMethodPrivateMemberTest, TestOnUnRegisteredProxyIme, TestSize.Leve auto userSession = std::make_shared(MAIN_USER_ID); UnRegisteredType type = UnRegisteredType::REMOVE_PROXY_IME; const sptr core; - auto ret = userSession->OnUnRegisteredProxyIme(type, core); + auto ret = userSession->OnUnRegisteredProxyIme(type, core, IPCSkeleton::GetCallingPid()); EXPECT_EQ(ret, ErrorCode::NO_ERROR); - type = UnRegisteredType::SWITCH_PROXY_IME_TO_IME; - ret = userSession->OnUnRegisteredProxyIme(type, core); - EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_BOUND); userSession->clientGroupMap_.clear(); ret = userSession->RemoveAllCurrentClient(); EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NULL_POINTER); @@ -1749,7 +1726,9 @@ HWTEST_F(InputMethodPrivateMemberTest, SA_StartPreconfiguredDefaultIme, TestSize auto imeData1 = std::make_shared(nullptr, nullptr, nullptr, 100); imeData1->imeStatus = ImeStatus::READY; imeData1->ime = std::make_pair(bundleName, extName); - session.imeData_.insert_or_assign(ImeType::IME, imeData1); + std::vector> imeDataList; + imeDataList.push_back(imeData1); + session.imeData_.insert_or_assign(ImeType::IME, imeDataList); ImeInfoInquirer::GetInstance().systemConfig_.defaultInputMethod = bundleName + "/" + extName; auto [ret2, status2] = session.StartPreconfiguredDefaultIme(DEFAULT_DISPLAY_ID); EXPECT_EQ(status2, StartPreDefaultImeStatus::HAS_STARTED); @@ -1894,7 +1873,9 @@ HWTEST_F(InputMethodPrivateMemberTest, SA_SpecialSendPrivateData, TestSize.Level auto imeData1 = std::make_shared(nullptr, nullptr, nullptr, 100); imeData1->imeStatus = ImeStatus::READY; imeData1->ime = std::make_pair(bundleName, extName); - session.imeData_.insert_or_assign(ImeType::IME, imeData1); + std::vector> imeDataList; + imeDataList.push_back(imeData1); + session.imeData_.insert_or_assign(ImeType::IME, imeDataList); std::unordered_map privateCommand; // running ime same with pre default ime, send directly ImeInfoInquirer::GetInstance().systemConfig_.defaultInputMethod = bundleName + "/" + extName; @@ -1922,7 +1903,9 @@ HWTEST_F(InputMethodPrivateMemberTest, SA_CheckInputTypeOption, TestSize.Level0) auto imeData1 = std::make_shared(nullptr, nullptr, nullptr, 100); imeData1->imeStatus = ImeStatus::READY; imeData1->ime = std::make_pair(bundleName, extName); - session->imeData_.insert_or_assign(ImeType::IME, imeData1); + std::vector> imeDataList; + imeDataList.push_back(imeData1); + session->imeData_.insert_or_assign(ImeType::IME, imeDataList); UserSessionManager::GetInstance().userSessions_.insert_or_assign(MAIN_USER_ID, session); InputClientInfo info; // same textField, input type started @@ -2483,7 +2466,9 @@ HWTEST_F(InputMethodPrivateMemberTest, SA_RestoreCurrentImeSubType, TestSize.Lev auto imeData = std::make_shared(nullptr, nullptr, nullptr, 10); imeData->imeStatus = ImeStatus::READY; imeData->ime = std::make_pair(bundleName, extName); - session->imeData_.insert_or_assign(ImeType::IME, imeData); + std::vector> imeDataList; + imeDataList.push_back(imeData); + session->imeData_.insert_or_assign(ImeType::IME, imeDataList); ret = session->RestoreCurrentImeSubType(0); EXPECT_EQ(ret, ErrorCode::NO_ERROR); EXPECT_FALSE(InputTypeManager::GetInstance().isStarted_); @@ -2499,7 +2484,8 @@ HWTEST_F(InputMethodPrivateMemberTest, SA_RestoreCurrentImeSubType, TestSize.Lev InputTypeManager::GetInstance().isStarted_ = true; InputTypeManager::GetInstance().currentTypeIme_.bundleName = bundleName1; imeData->ime = std::make_pair(bundleName1, extName1); - session->imeData_.insert_or_assign(ImeType::IME, imeData); + imeDataList.push_back(imeData); + session->imeData_.insert_or_assign(ImeType::IME, imeDataList); ret = session->RestoreCurrentImeSubType(0); EXPECT_EQ(ret, ErrorCode::ERROR_IME_NOT_STARTED); EXPECT_FALSE(InputTypeManager::GetInstance().isStarted_); @@ -2599,7 +2585,9 @@ HWTEST_F(InputMethodPrivateMemberTest, SA_TryStartIme_001, TestSize.Level0) userSession->isBlockStartedByLowMem_ = true; auto imeData = std::make_shared(nullptr, nullptr, nullptr, 10); - userSession->imeData_.insert_or_assign(ImeType::IME, imeData); + std::vector> imeDataList; + imeDataList.push_back(imeData); + userSession->imeData_.insert_or_assign(ImeType::IME, imeDataList); ret = userSession->TryStartIme(); EXPECT_EQ(ret, ErrorCode::ERROR_IME_HAS_STARTED); @@ -2644,7 +2632,9 @@ HWTEST_F(InputMethodPrivateMemberTest, SA_TryDisconnectIme_001, TestSize.Level0) auto ret = userSession->TryDisconnectIme(); EXPECT_EQ(ret, ErrorCode::ERROR_IME_NOT_STARTED); auto imeData = std::make_shared(nullptr, nullptr, nullptr, 10); - userSession->imeData_.insert_or_assign(ImeType::IME, imeData); + std::vector> imeDataList; + imeDataList.push_back(imeData); + userSession->imeData_.insert_or_assign(ImeType::IME, imeDataList); userSession->attachingCount_ = 1; ret = userSession->TryDisconnectIme(); @@ -2703,5 +2693,186 @@ HWTEST_F(InputMethodPrivateMemberTest, SA_TestClearImeConnection_001, TestSize.L userSession->ClearImeConnection(connection1); EXPECT_EQ(userSession->GetImeConnection(), connection); } + +/** + * @tc.name: PerUserSession_AddImeData_001 + * @tc.desc: PerUserSession_AddImeData_001 + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(InputMethodPrivateMemberTest, PerUserSession_AddImeData_001, TestSize.Level0) +{ + IMSA_HILOGI("InputMethodPrivateMemberTest::PerUserSession_AddImeData_001 start."); + auto userSession = std::make_shared(MAIN_USER_ID); + userSession->imeData_.clear(); + pid_t pid1 = 100; + sptr coreStub1 = new (std::nothrow) InputMethodCoreServiceImpl(); + sptr agentStub1 = new (std::nothrow) InputMethodAgentServiceImpl(); + auto ret = userSession->AddImeData(ImeType::PROXY_IME, coreStub1, agentStub1->AsObject(), pid1); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + auto it = userSession->imeData_.find(ImeType::PROXY_IME); + ASSERT_NE(it, userSession->imeData_.end()); + EXPECT_EQ(it->second.size(), 1); + + pid_t pid2 = 101; + sptr coreStub2 = new (std::nothrow) InputMethodCoreServiceImpl(); + sptr agentStub2 = new (std::nothrow) InputMethodAgentServiceImpl(); + ret = userSession->AddImeData(ImeType::PROXY_IME, coreStub2, agentStub2->AsObject(), pid2); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + it = userSession->imeData_.find(ImeType::PROXY_IME); + ASSERT_NE(it, userSession->imeData_.end()); + EXPECT_EQ(it->second.size(), 2); + + ret = userSession->AddImeData(ImeType::PROXY_IME, coreStub1, agentStub1->AsObject(), pid1); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + it = userSession->imeData_.find(ImeType::PROXY_IME); + ASSERT_NE(it, userSession->imeData_.end()); + ASSERT_EQ(it->second.size(), 2); + EXPECT_EQ(it->second[1]->pid, pid1); +} + +/** + * @tc.name: PerUserSession_GetImeData_001 + * @tc.desc: imeData_ info abnormal + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(InputMethodPrivateMemberTest, PerUserSession_GetImeData_001, TestSize.Level0) +{ + IMSA_HILOGI("InputMethodPrivateMemberTest::PerUserSession_GetImeData_001 start."); + auto userSession = std::make_shared(MAIN_USER_ID); + userSession->imeData_.clear(); + auto imeData = userSession->GetImeData(ImeType::PROXY_IME); + EXPECT_EQ(imeData, nullptr); + pid_t pid1 = 101; + imeData = userSession->GetImeData(pid1); + EXPECT_EQ(imeData, nullptr); + + userSession->imeData_.insert_or_assign(ImeType::IME, std::vector>{}); + imeData = userSession->GetImeData(ImeType::PROXY_IME); + EXPECT_EQ(imeData, nullptr); + imeData = userSession->GetImeData(pid1); + EXPECT_EQ(imeData, nullptr); + + userSession->imeData_.insert_or_assign(ImeType::PROXY_IME, std::vector>{}); + imeData = userSession->GetImeData(ImeType::PROXY_IME); + EXPECT_EQ(imeData, nullptr); + imeData = userSession->GetImeData(pid1); + EXPECT_EQ(imeData, nullptr); +} + +/** + * @tc.name: PerUserSession_GetImeData_002 + * @tc.desc: imeData_ normal + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(InputMethodPrivateMemberTest, PerUserSession_GetImeData_002, TestSize.Level0) +{ + IMSA_HILOGI("InputMethodPrivateMemberTest::PerUserSession_GetImeData_002 start."); + auto userSession = std::make_shared(MAIN_USER_ID); + userSession->imeData_.clear(); + pid_t pid1 = 101; + sptr coreStub1 = new (std::nothrow) InputMethodCoreServiceImpl(); + sptr agentStub1 = new (std::nothrow) InputMethodAgentServiceImpl(); + userSession->AddImeData(ImeType::PROXY_IME, coreStub1, agentStub1->AsObject(), pid1); + + pid_t pid2 = 102; + sptr coreStub2 = new (std::nothrow) InputMethodCoreServiceImpl(); + sptr agentStub2 = new (std::nothrow) InputMethodAgentServiceImpl(); + userSession->AddImeData(ImeType::PROXY_IME, coreStub2, agentStub2->AsObject(), pid2); + auto it = userSession->imeData_.find(ImeType::PROXY_IME); + ASSERT_NE(it, userSession->imeData_.end()); + EXPECT_EQ(it->second.size(), 2); + + auto imeData = userSession->GetImeData(ImeType::IME_MIRROR); + EXPECT_EQ(imeData, nullptr); + imeData = userSession->GetImeData(ImeType::PROXY_IME); + ASSERT_NE(imeData, nullptr); + EXPECT_EQ(imeData->pid, pid2); + + pid_t pid3 = 103; + imeData = userSession->GetImeData(pid3); + EXPECT_EQ(imeData, nullptr); + imeData = userSession->GetImeData(pid1); + ASSERT_NE(imeData, nullptr); + EXPECT_EQ(imeData->pid, pid1); +} + +/** + * @tc.name: PerUserSession_RemoveImeData_001 + * @tc.desc: Remove imeData by pid + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(InputMethodPrivateMemberTest, PerUserSession_RemoveImeData_001, TestSize.Level0) +{ + IMSA_HILOGI("InputMethodPrivateMemberTest::PerUserSession_RemoveImeData_001 start."); + auto userSession = std::make_shared(MAIN_USER_ID); + userSession->imeData_.clear(); + pid_t pid1 = 101; + sptr coreStub1 = new (std::nothrow) InputMethodCoreServiceImpl(); + sptr agentStub1 = new (std::nothrow) InputMethodAgentServiceImpl(); + userSession->AddImeData(ImeType::PROXY_IME, coreStub1, agentStub1->AsObject(), pid1); + + pid_t pid2 = 102; + sptr coreStub2 = new (std::nothrow) InputMethodCoreServiceImpl(); + sptr agentStub2 = new (std::nothrow) InputMethodAgentServiceImpl(); + userSession->AddImeData(ImeType::PROXY_IME, coreStub2, agentStub2->AsObject(), pid2); + auto it = userSession->imeData_.find(ImeType::PROXY_IME); + ASSERT_NE(it, userSession->imeData_.end()); + EXPECT_EQ(it->second.size(), 2); + + pid_t pid3 = 103; + userSession->RemoveImeData(pid3); + it = userSession->imeData_.find(ImeType::PROXY_IME); + ASSERT_NE(it, userSession->imeData_.end()); + EXPECT_EQ(it->second.size(), 2); + + userSession->RemoveImeData(pid2); + it = userSession->imeData_.find(ImeType::PROXY_IME); + ASSERT_NE(it, userSession->imeData_.end()); + ASSERT_EQ(it->second.size(), 1); + EXPECT_EQ(it->second[0]->pid, pid1); + + userSession->RemoveImeData(pid1); + it = userSession->imeData_.find(ImeType::PROXY_IME); + EXPECT_EQ(it, userSession->imeData_.end()); +} + +/** + * @tc.name: PerUserSession_RemoveImeData_002 + * @tc.desc: Remove imeData by imeType + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(InputMethodPrivateMemberTest, PerUserSession_RemoveImeData_002, TestSize.Level0) +{ + IMSA_HILOGI("InputMethodPrivateMemberTest::PerUserSession_RemoveImeData_002 start."); + auto userSession = std::make_shared(MAIN_USER_ID); + userSession->imeData_.clear(); + pid_t pid1 = 101; + sptr coreStub1 = new (std::nothrow) InputMethodCoreServiceImpl(); + sptr agentStub1 = new (std::nothrow) InputMethodAgentServiceImpl(); + userSession->AddImeData(ImeType::PROXY_IME, coreStub1, agentStub1->AsObject(), pid1); + + pid_t pid2 = 102; + sptr coreStub2 = new (std::nothrow) InputMethodCoreServiceImpl(); + sptr agentStub2 = new (std::nothrow) InputMethodAgentServiceImpl(); + userSession->AddImeData(ImeType::PROXY_IME, coreStub2, agentStub2->AsObject(), pid2); + auto it = userSession->imeData_.find(ImeType::PROXY_IME); + ASSERT_NE(it, userSession->imeData_.end()); + EXPECT_EQ(it->second.size(), 2); + + userSession->RemoveImeData(ImeType::IME_MIRROR); + it = userSession->imeData_.find(ImeType::PROXY_IME); + ASSERT_NE(it, userSession->imeData_.end()); + EXPECT_EQ(it->second.size(), 2); + + userSession->RemoveImeData(ImeType::PROXY_IME); + it = userSession->imeData_.find(ImeType::PROXY_IME); + EXPECT_EQ(it, userSession->imeData_.end()); +} + } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/test/unittest/cpp_test/src/json_operate_test.cpp b/test/unittest/cpp_test/src/json_operate_test.cpp index bafd6b4a4c581007240e97d460316ad52e0fb0cc..0d02043fd51e237ede89025b4c2101a953268316 100644 --- a/test/unittest/cpp_test/src/json_operate_test.cpp +++ b/test/unittest/cpp_test/src/json_operate_test.cpp @@ -411,5 +411,28 @@ HWTEST_F(JsonOperateTest, testIsDynamicStartIme, TestSize.Level1) instance.systemConfig_.dynamicStartImeValue = ""; instance.systemConfig_.dynamicStartImeSysParam = ""; } + +/** + * @tc.name: testImedataUidListParse + * @tc.desc: ImedataUidList Parse + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenyu + */ +HWTEST_F(JsonOperateTest, testImedataUidListParse, TestSize.Level1) +{ + IMSA_HILOGI("JsonOperateTest ImedataUidListParse START"); + ImeInfoInquirer::GetInstance().systemConfig_.proxyImeUidList.clear(); + ASSERT_EQ(ImeInfoInquirer::GetInstance().systemConfig_.proxyImeUidList.size(), 0); + auto ret = ImeInfoInquirer::GetInstance().IsVirtualProxyIme(0); + if (ImeInfoInquirer::GetInstance().systemConfig_.proxyImeUidList.size() != 0) { + ret = ImeInfoInquirer::GetInstance().IsVirtualProxyIme(0); + ASSERT_FALSE(ret); + ret = ImeInfoInquirer::GetInstance().IsVirtualProxyIme(5521); + ASSERT_TRUE(ret); + ret = ImeInfoInquirer::GetInstance().IsVirtualProxyIme(7101); + ASSERT_TRUE(ret); + } +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file