From d8b4a3f4b8730b265261dc2cd3c863370cfcd51e Mon Sep 17 00:00:00 2001 From: hemenghao Date: Wed, 6 Aug 2025 11:20:08 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B4=BE=E7=BB=B4=E6=96=AF=E9=9C=80=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: hemenghao --- .../inputmethod_ability/IInputMethodCore.idl | 1 + .../include/input_method_ability.h | 1 + .../include/input_method_core_service_impl.h | 1 + .../inputmethod_ability/include/tasks/task.h | 3 +- .../include/tasks/task_imsa.h | 12 ++ .../src/input_method_ability.cpp | 17 +- .../src/input_method_ability_interface.cpp | 5 + .../src/input_method_core_service_impl.cpp | 6 +- .../include/input_client_info.h | 2 + .../include/input_method_ability_interface.h | 2 + .../include/input_method_engine_listener.h | 2 + services/include/client_group.h | 2 +- services/include/ime_info_inquirer.h | 4 + services/include/peruser_session.h | 14 +- services/include/sys_cfg_parser.h | 9 + services/src/client_group.cpp | 6 +- services/src/ime_info_inquirer.cpp | 23 ++ services/src/input_method_system_ability.cpp | 7 +- services/src/peruser_session.cpp | 203 +++++++++++++----- services/src/sys_cfg_parser.cpp | 13 ++ .../perusersession_fuzzer.cpp | 2 +- test/unittest/cpp_test/BUILD.gn | 7 +- test/unittest/cpp_test/src/ime_proxy_test.cpp | 43 +++- .../src/input_method_controller_test.cpp | 2 +- .../src/input_method_private_member_test.cpp | 35 ++- .../cpp_test/src/json_operate_test.cpp | 21 ++ 26 files changed, 363 insertions(+), 80 deletions(-) diff --git a/frameworks/native/inputmethod_ability/IInputMethodCore.idl b/frameworks/native/inputmethod_ability/IInputMethodCore.idl index aa7aef257..557ff1207 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 a94f600ae..643d74f85 100644 --- a/frameworks/native/inputmethod_ability/include/input_method_ability.h +++ b/frameworks/native/inputmethod_ability/include/input_method_ability.h @@ -119,6 +119,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 dda07ef7a..049cec6ce 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/include/tasks/task.h b/frameworks/native/inputmethod_ability/include/tasks/task.h index 77f1afcf9..dd4a0a2cc 100644 --- a/frameworks/native/inputmethod_ability/include/tasks/task.h +++ b/frameworks/native/inputmethod_ability/include/tasks/task.h @@ -62,7 +62,8 @@ enum TaskType : uint32_t { TASK_TYPE_IMSA_SET_CORE_AND_AGENT, TASK_TYPE_IMSA_ADJUST_KEYBOARD, TASK_TYPE_IMSA_DISCARD_TYPING_TEXT, - TASK_TYPE_IMSA_END = TASK_TYPE_IMSA_DISCARD_TYPING_TEXT, + TASK_TYPE_IMSA_NOTIFY_PREEMPTION, + TASK_TYPE_IMSA_END = TASK_TYPE_IMSA_NOTIFY_PREEMPTION, // Task from inner TASK_TYPE_RESUME, diff --git a/frameworks/native/inputmethod_ability/include/tasks/task_imsa.h b/frameworks/native/inputmethod_ability/include/tasks/task_imsa.h index 819b623cd..eef3666b3 100644 --- a/frameworks/native/inputmethod_ability/include/tasks/task_imsa.h +++ b/frameworks/native/inputmethod_ability/include/tasks/task_imsa.h @@ -196,6 +196,18 @@ public: } ~TaskImsaSetCoreAndAgent() = default; }; + +class TaskImsaNotifyPreemption : public Task { +public: + explicit TaskImsaNotifyPreemption() : Task(TASK_TYPE_IMSA_NOTIFY_PREEMPTION) + { + auto func = []() { + InputMethodAbility::GetInstance().OnNotifyPreemption(); + }; + actions_.emplace_back(std::make_unique(func)); + } + ~TaskImsaNotifyPreemption() = default; +}; } // 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 04a611eaf..a37add40c 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) { @@ -456,15 +457,15 @@ void InputMethodAbility::OnAttributeChange(InputAttribute attribute) int32_t InputMethodAbility::OnStopInputService(bool isTerminateIme) { IMSA_HILOGI("isTerminateIme: %{public}d.", isTerminateIme); - isBound_.store(false); auto imeListener = GetImeListener(); if (imeListener == nullptr) { return ErrorCode::ERROR_IME_NOT_STARTED; } - if (isTerminateIme) { + if (isTerminateIme && isBound_) { isImeTerminating.store(true); return imeListener->OnInputStop(); } + isBound_.store(false); return ErrorCode::NO_ERROR; } @@ -1884,5 +1885,17 @@ int32_t InputMethodAbility::IsCapacitySupport(int32_t capacity, bool &isSupport) return proxy->IsCapacitySupport(capacity, isSupport); } + +int32_t InputMethodAbility::OnNotifyPreemption() +{ + StopInput(dataChannelObject_, 0); + isBound_.store(false); + auto imeListener = GetImeListener(); + if (imeListener == nullptr) { + return ErrorCode::ERROR_IME_NOT_STARTED; + } + // 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 9da345e6e..c08e0c00a 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_ability_interface.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_ability_interface.cpp @@ -87,5 +87,10 @@ void InputMethodAbilityInterface::SetKdListener(std::shared_ptr()); + return ERR_OK; +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/inputmethod_controller/include/input_client_info.h b/frameworks/native/inputmethod_controller/include/input_client_info.h index b35768952..6c8d49837 100644 --- a/frameworks/native/inputmethod_controller/include/input_client_info.h +++ b/frameworks/native/inputmethod_controller/include/input_client_info.h @@ -31,6 +31,7 @@ enum class UpdateFlag : uint32_t { TEXT_CONFIG, UIEXTENSION_TOKENID, CLIENT_TYPE, + IME_DATA_PID, }; enum class ImeType : int32_t { IME = 0, @@ -75,6 +76,7 @@ struct InputClientInfo { RequestKeyboardReason requestKeyboardReason { RequestKeyboardReason::NONE }; // show keyboard reason ClientType type{ INNER_KIT }; // for hiSysEvent std::string name; // for hiSysEvent, client name:SA/processName app/bundleName + pid_t bindImePid { -1 }; }; struct InputClientInfoInner : public Parcelable { diff --git a/interfaces/inner_api/inputmethod_ability/include/input_method_ability_interface.h b/interfaces/inner_api/inputmethod_ability/include/input_method_ability_interface.h index 59f240445..3d74371da 100644 --- a/interfaces/inner_api/inputmethod_ability/include/input_method_ability_interface.h +++ b/interfaces/inner_api/inputmethod_ability/include/input_method_ability_interface.h @@ -26,6 +26,7 @@ namespace OHOS { namespace MiscServices { +using AsyncIpcCallBack = std::function; class InputMethodAbilityInterface { public: static InputMethodAbilityInterface &GetInstance(); @@ -59,6 +60,7 @@ public: int32_t SendFunctionKey(int32_t funcKey); void SetImeListener(std::shared_ptr imeListener); void SetKdListener(std::shared_ptr kdListener); + int32_t SelectByRange(int32_t start, int32_t end, const AsyncIpcCallBack &callback); 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 ffdb16f61..0b9b15b36 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/services/include/client_group.h b/services/include/client_group.h index ad3918935..804e9c9a0 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/ime_info_inquirer.h b/services/include/ime_info_inquirer.h index e7b0ada42..7415bbee6 100644 --- a/services/include/ime_info_inquirer.h +++ b/services/include/ime_info_inquirer.h @@ -91,8 +91,11 @@ public: bool IsEnableNumKey(); bool IsVirtualProxyIme(int32_t callingUid); bool IsSpecialSaUid(int32_t callingUid); + bool IsContainUid(int32_t callingUid); void InitSystemConfig(); + void InitImeUidList(); SystemConfig GetSystemConfig(); + std::vector GetImeUidList(); ImeNativeCfg GetDefaultIme(); std::string GetSystemSpecialIme(); int32_t QueryFullImeInfo(std::vector>> &imeInfos); @@ -148,6 +151,7 @@ private: FullImeInfo &imeInfo, bool needBrief = false); SystemConfig systemConfig_; + std::vector imeDataUidList_; bool IsTempInputMethod(const OHOS::AppExecFwk::ExtensionAbilityInfo &extInfo); }; } // namespace MiscServices diff --git a/services/include/peruser_session.h b/services/include/peruser_session.h index cb36cbadc..b6e5e37ff 100644 --- a/services/include/peruser_session.h +++ b/services/include/peruser_session.h @@ -115,7 +115,7 @@ public: 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 OnUnRegisteredProxyIme(UnRegisteredType type, const sptr &core, pid_t pid); int32_t UpdateLargeMemorySceneState(const int32_t memoryState); int32_t OnRegisterProxyIme( uint64_t displayId, const sptr &core, const sptr &agent); @@ -138,6 +138,7 @@ public: int32_t RemoveAllCurrentClient(); std::shared_ptr GetReadyImeData(ImeType type); std::shared_ptr GetImeData(ImeType type); + std::shared_ptr GetImeDataByPid(ImeType type, pid_t pid); BlockQueue& GetSwitchQueue(); bool IsWmsReady(); bool CheckPwdInputPatternConv(InputClientInfo &clientInfo, uint64_t displayId); @@ -170,6 +171,7 @@ public: void IncreaseScbStartCount(); int32_t TryStartIme(); int32_t TryDisconnectIme(); + bool CompareImeData(const std::shared_ptr& lhs, const std::shared_ptr& rhs); private: struct ResetManager { @@ -196,7 +198,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, @@ -213,7 +215,8 @@ private: 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 RemoveImeDataByPid(ImeType type, pid_t pid, bool isImeDied); + int32_t RemoveIme(const sptr &core, ImeType type, pid_t pid); std::shared_ptr GetValidIme(ImeType type); int32_t BindClientWithIme(const std::shared_ptr &clientInfo, ImeType type, @@ -253,7 +256,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); @@ -276,7 +279,7 @@ private: 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; @@ -323,6 +326,7 @@ private: std::mutex connectionLock_{}; sptr connection_ = nullptr; std::atomic isBlockStartedByLowMem_ = false; + int32_t count_ { 0 }; }; } // namespace MiscServices } // namespace OHOS diff --git a/services/include/sys_cfg_parser.h b/services/include/sys_cfg_parser.h index 664f7c1d3..e1df22e70 100644 --- a/services/include/sys_cfg_parser.h +++ b/services/include/sys_cfg_parser.h @@ -154,6 +154,14 @@ struct IgnoreSysPanelAdjustCfg : public Serializable { } }; +struct ImeDataUidCfg : public Serializable { + std::vector imeDataUidList; + bool Unmarshal(cJSON *node) override + { + return GetValue(node, GET_NAME(imeDataUidList), imeDataUidList); + } +}; + class SysCfgParser { public: static bool ParseSystemConfig(SystemConfig &systemConfig); @@ -161,6 +169,7 @@ public: static bool ParsePanelAdjust(std::vector &sysPanelAdjust); static bool ParseDefaultFullIme(std::vector &defaultFullImeList); static bool ParseIgnoreSysPanelAdjust(IgnoreSysPanelAdjust &ignoreSysPanelAdjust); + static bool ParseImeUidList(std::vector &imeDataUidList); private: static std::string GetSysCfgContent(const std::string &key); diff --git a/services/src/client_group.cpp b/services/src/client_group.cpp index 3c8852eee..0be5ca07f 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::IME_DATA_PID: { + VariantUtil::GetValue(updateInfo.second, it->second->bindImePid); + break; + } default: break; } diff --git a/services/src/ime_info_inquirer.cpp b/services/src/ime_info_inquirer.cpp index f1bcf5a1c..432d472f7 100644 --- a/services/src/ime_info_inquirer.cpp +++ b/services/src/ime_info_inquirer.cpp @@ -88,6 +88,29 @@ SystemConfig ImeInfoInquirer::GetSystemConfig() return systemConfig_; } +void ImeInfoInquirer::InitImeUidList() +{ + auto ret = SysCfgParser::ParseImeUidList(imeDataUidList_); + if (!ret) { + IMSA_HILOGE("parse systemConfig failed!"); + return; + } +} + +std::vector ImeInfoInquirer::GetImeUidList() +{ + return imeDataUidList_; +} + +bool ImeInfoInquirer::IsContainUid(int32_t uid) +{ + bool isContained = std::any_of(imeDataUidList_.begin(), imeDataUidList_.end(), [uid](int32_t value) { + return value == uid; + }); + IMSA_HILOGD(" isContained: %{public}d, uid: %{public}d", isContained, uid); + return isContained; +} + bool ImeInfoInquirer::QueryImeExtInfos(const int32_t userId, std::vector &infos) { IMSA_HILOGD("userId: %{public}d.", userId); diff --git a/services/src/input_method_system_ability.cpp b/services/src/input_method_system_ability.cpp index caac6c8c6..11f863352 100644 --- a/services/src/input_method_system_ability.cpp +++ b/services/src/input_method_system_ability.cpp @@ -362,6 +362,7 @@ int32_t InputMethodSystemAbility::Init() #ifdef IMF_ON_DEMAND_START_STOP_SA_ENABLE ImeCfgManager::GetInstance().Init(); ImeInfoInquirer::GetInstance().InitSystemConfig(); + ImeInfoInquirer::GetInstance().InitImeUidList(); bool isSuccess = Publish(this); if (!isSuccess) { IMSA_HILOGE("publish failed"); @@ -378,6 +379,7 @@ int32_t InputMethodSystemAbility::Init() IMSA_HILOGI("publish success"); state_ = ServiceRunningState::STATE_RUNNING; ImeInfoInquirer::GetInstance().InitSystemConfig(); + ImeInfoInquirer::GetInstance().InitImeUidList(); ImeStateManagerFactory::GetInstance().SetDynamicStartIme(ImeInfoInquirer::GetInstance().IsDynamicStartIme()); #endif InitMonitors(); @@ -835,7 +837,7 @@ ErrCode InputMethodSystemAbility::SetCoreAndAgent(const sptr & IMSA_HILOGE("%{public}d session is nullptr!", userId); return ErrorCode::ERROR_NULL_POINTER; } - if (identityChecker_->IsNativeSa(IPCSkeleton::GetCallingTokenID())) { + if (ImeInfoInquirer::GetInstance().IsContainUid(IPCSkeleton::GetCallingUid())) { return session->OnRegisterProxyIme(core, agent); } if (!IsCurrentIme(userId)) { @@ -2124,6 +2126,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; @@ -2141,7 +2144,7 @@ ErrCode InputMethodSystemAbility::UnRegisteredProxyIme(int32_t type, const sptr< 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 51cc5f8c7..7c3fb6538 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 ONE_SECOND = 1000; +constexpr uint32_t MAX_REGISTER_TIMES_ONE_SECOND = 1000; PerUserSession::PerUserSession(int userId) : userId_(userId) { } PerUserSession::PerUserSession(int32_t userId, const std::shared_ptr &eventHandler) @@ -119,7 +121,7 @@ int32_t PerUserSession::HideKeyboard( IMSA_HILOGE("client info is nullptr!"); return ErrorCode::ERROR_CLIENT_NOT_FOUND; } - auto data = GetReadyImeData(clientInfo->bindImeType); + auto data = GetImeData(clientInfo->bindImeType); if (data == nullptr) { IMSA_HILOGE("ime: %{public}d is not exist!", clientInfo->bindImeType); return ErrorCode::ERROR_IME_NOT_STARTED; @@ -147,7 +149,7 @@ int32_t PerUserSession::ShowKeyboard(const sptr ¤tClient, IMSA_HILOGE("client info is nullptr!"); return ErrorCode::ERROR_CLIENT_NOT_FOUND; } - auto data = GetReadyImeData(clientInfo->bindImeType); + auto data = GetImeData(clientInfo->bindImeType); if (data == nullptr) { IMSA_HILOGE("ime: %{public}d is not exist!", clientInfo->bindImeType); return ErrorCode::ERROR_IME_NOT_STARTED; @@ -204,28 +206,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 = GetImeDataByPid(type, pid); if (imeData != nullptr && imeData->imeStatus == ImeStatus::EXITING) { - RemoveImeData(type, true); + RemoveImeDataByPid(type, pid, true); InputTypeManager::GetInstance().Set(false); NotifyImeStopFinished(); IMSA_HILOGI("%{public}d not current imeData.", type); return; } - RemoveImeData(type, true); + RemoveImeDataByPid(type, pid, true); 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) { @@ -252,22 +254,22 @@ void PerUserSession::OnImeDied(const sptr &remote, ImeType typ } } -int32_t PerUserSession::RemoveIme(const sptr &core, ImeType type) +int32_t PerUserSession::RemoveIme(const sptr &core, 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()) { + auto data = GetImeDataByPid(type, pid); + if (data == nullptr) { 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); + RemoveImeDataByPid(type, pid, true); return ErrorCode::NO_ERROR; } @@ -519,7 +521,7 @@ void PerUserSession::DeactivateClient(const sptr &client) bool PerUserSession::IsProxyImeEnable() { - auto data = GetReadyImeData(ImeType::PROXY_IME); + auto data = GetImeData(ImeType::PROXY_IME); bool ret = false; if (data == nullptr || data->core == nullptr) { return false; @@ -548,26 +550,27 @@ int32_t PerUserSession::OnStartInput( IMSA_HILOGD("start input with keyboard[%{public}d].", inputClientInfo.isShowKeyboard); InputClientInfo infoTemp = *clientInfo; infoTemp.isNotifyInputStart = inputClientInfo.isNotifyInputStart; - ImeType imeType = GetImeType(inputClientInfo.displayId); + infoTemp.bindImeType = GetImeType(inputClientInfo.displayId); if (GetDisplayGroupId(inputClientInfo.displayId) == DEFAULT_DISPLAY_ID) { - HandleImeBindTypeChanged(infoTemp, clientGroup); - imeType = IsProxyImeEnable() ? ImeType::PROXY_IME : ImeType::IME; + infoTemp.bindImeType = IsProxyImeEnable() ? ImeType::PROXY_IME : ImeType::IME; + } + auto data = GetReadyImeData(infoTemp.bindImeType); + if (data == nullptr || data->agent == nullptr) { + IMSA_HILOGE("data or agent is nullptr!"); + return ErrorCode::ERROR_IME_NOT_STARTED; } + infoTemp.bindImePid = data->pid; + HandleBindImeChanged(infoTemp, clientGroup); infoTemp.isShowKeyboard = inputClientInfo.isShowKeyboard; infoTemp.needHide = inputClientInfo.needHide; infoTemp.requestKeyboardReason = inputClientInfo.requestKeyboardReason; infoTemp.config.requestKeyboardReason = inputClientInfo.requestKeyboardReason; - int32_t ret = - BindClientWithIme(std::make_shared(infoTemp), imeType, true, inputClientInfo.displayId); + int32_t ret = BindClientWithIme(std::make_shared(infoTemp), infoTemp.bindImeType, true, + inputClientInfo.displayId); if (ret != ErrorCode::NO_ERROR) { IMSA_HILOGE("bind failed, ret: %{public}d!", ret); return ret; } - auto data = GetReadyImeData(imeType); - if (data == nullptr || data->agent == nullptr) { - IMSA_HILOGE("data or agent is nullptr!"); - return ErrorCode::ERROR_IME_NOT_STARTED; - } agent = data->agent; imeInfo = { data->pid, data->ime.first }; return ErrorCode::NO_ERROR; @@ -621,7 +624,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::IME_DATA_PID, data->pid} }); ReplaceCurrentClient(clientInfo->client, clientGroup); if (clientInfo->isShowKeyboard) { clientGroup->NotifyInputStartToClients( @@ -671,7 +675,7 @@ void PerUserSession::StopClientInput( void PerUserSession::StopImeInput(ImeType currentType, const sptr ¤tChannel, uint32_t sessionId) { - auto data = GetReadyImeData(currentType); + auto data = GetImeData(currentType); if (data == nullptr) { return; } @@ -731,8 +735,26 @@ int32_t PerUserSession::OnSetCoreAndAgent(const sptr &core, co int32_t PerUserSession::OnRegisterProxyIme(const sptr &core, const sptr &agent) { - IMSA_HILOGD("start."); + IMSA_HILOGD("start"); + int64_t startPoint; + if (count_ == 0) { + startPoint = duration_cast(system_clock::now().time_since_epoch()).count(); + } auto imeType = ImeType::PROXY_IME; + auto lastImeData = GetImeData(imeType); + if (lastImeData != nullptr) { + count_++; + if (count_ == MAX_REGISTER_TIMES_ONE_SECOND) { + int64_t costTime = duration_cast(system_clock::now().time_since_epoch()).count() - startPoint; + if (costTime <= ONE_SECOND) { + IMSA_HILOGI("service is busy."); + return ErrorCode::ERROR_DEVICE_UNSUPPORTED; + } + count_ = 0; + } + + lastImeData->core->NotifyPreemption(); + } auto ret = AddImeData(imeType, core, agent, IPCSkeleton::GetCallingPid()); if (ret != ErrorCode::NO_ERROR) { return ret; @@ -814,12 +836,12 @@ 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(core, ImeType::PROXY_IME, pid); return ErrorCode::NO_ERROR; } if (type == UnRegisteredType::SWITCH_PROXY_IME_TO_IME) { @@ -958,7 +980,8 @@ int32_t PerUserSession::AddImeData(ImeType type, sptr core, sp 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!"); @@ -976,11 +999,25 @@ int32_t PerUserSession::AddImeData(ImeType type, sptr core, sp } else if (type == ImeType::PROXY_AGENT_IME) { imeData->ime.first.append(GET_NAME(_PROXY_AGENT_IME)); } - imeData_.insert_or_assign(type, imeData); + + auto &imeDataList = imeData_[type]; + auto it = std::find_if(imeDataList.begin(), imeDataList.end(), [&imeData, this]( + const std::shared_ptr& existingImeData) { + return CompareImeData(imeData, existingImeData); + }); + if (it != imeDataList.end()) { + imeDataList.erase(it); + } + 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; } +bool PerUserSession::CompareImeData(const std::shared_ptr& lhs, const std::shared_ptr& rhs) +{ + return (*lhs).core->AsObject() == (*rhs).core->AsObject(); +} + std::shared_ptr PerUserSession::GetReadyImeData(ImeType type) { std::lock_guard lock(imeDataLock_); @@ -988,21 +1025,46 @@ std::shared_ptr PerUserSession::GetReadyImeData(ImeType type) if (it == imeData_.end()) { return nullptr; } - if (it->second->imeStatus != ImeStatus::READY) { + auto& dataList = it->second; + if (dataList.empty()) { return nullptr; } - return it->second; + if (dataList.back()->imeStatus != ImeStatus::READY) { + return nullptr; + } + return dataList.back(); } std::shared_ptr PerUserSession::GetValidIme(ImeType type) { - auto data = GetReadyImeData(type); + auto data = GetImeData(type); if (data != nullptr || type != ImeType::IME) { return data; } - IMSA_HILOGI("current ime is empty, try to restart it."); StartCurrentIme(); - return GetReadyImeData(type); + return GetImeData(type); +} + +void PerUserSession::RemoveImeDataByPid(ImeType type, pid_t pid, bool isImeDied) +{ + std::lock_guard lock(imeDataLock_); + auto it = imeData_.find(type); + if (it == imeData_.end()) { + IMSA_HILOGD("imeData not found."); + return; + } + auto& dataList = it->second; + dataList.erase( + std::remove_if(dataList.begin(), dataList.end(), [pid, isImeDied](const std::shared_ptr& data) { + if (data->pid == pid) { + if (isImeDied && data->core != nullptr && data->core->AsObject() != nullptr) { + data->core->AsObject()->RemoveDeathRecipient(data->deathRecipient); + } + return true; + } + return false; + }), dataList.end()); + return; } void PerUserSession::RemoveImeData(ImeType type, bool isImeDied) @@ -1013,7 +1075,11 @@ void PerUserSession::RemoveImeData(ImeType type, bool isImeDied) IMSA_HILOGD("imeData not found."); return; } - auto data = it->second; + auto& dataList = it->second; + if (dataList.empty()) { + return; + } + auto data = dataList.back(); if (isImeDied && data->core != nullptr && data->core->AsObject() != nullptr) { data->core->AsObject()->RemoveDeathRecipient(data->deathRecipient); } @@ -1795,7 +1861,9 @@ int32_t PerUserSession::InitImeData( if (imeNativeCfg != nullptr && !imeNativeCfg->imeExtendInfo.privateCommand.empty()) { imeData->imeExtendInfo.privateCommand = imeNativeCfg->imeExtendInfo.privateCommand; } - imeData_.insert({ ImeType::IME, imeData }); + std::vector> imeDataList; + imeDataList.push_back(imeData); + imeData_.insert({ ImeType::IME, imeDataList }); return ErrorCode::NO_ERROR; } @@ -1810,10 +1878,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()) { + 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(); @@ -1822,13 +1894,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; } @@ -1839,7 +1912,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()) { + return ErrorCode::ERROR_NULL_POINTER; + } + dataList.back()->pid = pid; return ErrorCode::NO_ERROR; } @@ -1850,7 +1927,27 @@ std::shared_ptr PerUserSession::GetImeData(ImeType type) if (it == imeData_.end()) { return nullptr; } - return it->second; + auto& dataList = it->second; + if (dataList.empty()) { + return nullptr; + } + return dataList.back(); +} + +std::shared_ptr PerUserSession::GetImeDataByPid(ImeType type, pid_t pid) +{ + std::lock_guard lock(imeDataLock_); + auto it = imeData_.find(type); + if (it == imeData_.end()) { + return nullptr; + } + auto& dataList = it->second; + for (const auto& imeData : dataList) { + if (imeData && imeData->pid == pid) { + return imeData; + } + } + return nullptr; } int32_t PerUserSession::StartIme(const std::shared_ptr &ime, bool isStopCurrentIme) @@ -1884,12 +1981,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()) { + 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; } @@ -2138,7 +2239,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 @@ -2162,6 +2263,9 @@ void PerUserSession::HandleImeBindTypeChanged( if (oldClientInfo == nullptr) { return; } + if (IsSameClient(newClientInfo.client, oldClientInfo->client) && newClientInfo.pid != oldClientInfo->pid) { + newClientInfo.isNotifyInputStart = true; + } if (!IsImeBindTypeChanged(oldClientInfo->bindImeType)) { return; } @@ -2174,9 +2278,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; diff --git a/services/src/sys_cfg_parser.cpp b/services/src/sys_cfg_parser.cpp index bead0887a..654c8f189 100644 --- a/services/src/sys_cfg_parser.cpp +++ b/services/src/sys_cfg_parser.cpp @@ -94,6 +94,19 @@ std::string SysCfgParser::GetSysCfgContent(const std::string &key) } return content; } + +bool SysCfgParser::ParseImeUidList(std::vector &imeDataUidList) +{ + auto content = GetSysCfgContent(GET_NAME(imeDataUidList)); + if (content.empty()) { + IMSA_HILOGD("content is empty"); + return false; + } + ImeDataUidCfg imeDataUidCfg; + auto ret = imeDataUidCfg.Unmarshall(content); + imeDataUidList = imeDataUidCfg.imeDataUidList; + return ret; +} // LCOV_EXCL_STOP } // 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 61e21da48..ee6d44102 100644 --- a/test/fuzztest/perusersession_fuzzer/perusersession_fuzzer.cpp +++ b/test/fuzztest/perusersession_fuzzer/perusersession_fuzzer.cpp @@ -96,7 +96,7 @@ bool FuzzPerUserSession(const uint8_t *rawData, size_t size) userSessions->OnRegisterProxyIme(core, agent->AsObject()); 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 22231f939..26b76b8c1 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 72cfb645b..9c102f1e4 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 @@ -674,14 +676,51 @@ 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"); + auto ret = InputMethodAbilityInterface::GetInstance().RegisterProxyIme(0); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + std::shared_ptr property = imc_->GetCurrentInputMethod(); + ASSERT_TRUE(property != nullptr); + EXPECT_EQ(property->name, BUNDLENAME); + ret = InputMethodAbilityInterface::GetInstance().UnregisterProxyIme(0); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); +} + +/** + * @tc.name: TestRegisterProxyIme + * @tc.desc: Test RegisterProxyIme sucess + * @tc.type: FUNC + */ +HWTEST_F(ImeProxyTest, RegisterProxyImeTest003, TestSize.Level0) +{ + IMSA_HILOGI("ImeProxyTest::RegisterProxyImeTest003 start"); + std::vector tmp = ImeInfoInquirer::GetInstance().GetImeUidList(); + ImeInfoInquirer::GetInstance().imeDataUidList_.clear(); + ImeInfoInquirer::GetInstance().InitImeUidList(); + ImeInfoInquirer::GetInstance().imeDataUidList_.push_back(IPCSkeleton::GetCallingUid()); + auto ret = InputMethodAbilityInterface::GetInstance().RegisterProxyIme(0); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + std::shared_ptr property = imc_->GetCurrentInputMethod(); + ret = InputMethodAbilityInterface::GetInstance().UnregisterProxyIme(0); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + ImeInfoInquirer::GetInstance().imeDataUidList_ = tmp; +} } // 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 ec1ed4cfc..465c6733f 100644 --- a/test/unittest/cpp_test/src/input_method_controller_test.cpp +++ b/test/unittest/cpp_test/src/input_method_controller_test.cpp @@ -2158,7 +2158,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 eceb33e34..43e56958a 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 @@ -369,10 +369,10 @@ HWTEST_F(InputMethodPrivateMemberTest, PerUserSessionParameterNullptr003, TestSi 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); + userSession->OnImeDied(nullptr, ImeType::IME, IPCSkeleton::GetCallingPid()); bool isShowKeyboard = false; clientGroup->UpdateClientInfo(nullptr, { { UpdateFlag::ISSHOWKEYBOARD, isShowKeyboard } }); - int32_t ret = userSession->RemoveIme(nullptr, ImeType::IME); + int32_t ret = userSession->RemoveIme(nullptr, ImeType::IME, IPCSkeleton::GetCallingPid()); EXPECT_EQ(ret, ErrorCode::ERROR_NULL_POINTER); } @@ -1173,10 +1173,10 @@ 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); + ret = userSession->OnUnRegisteredProxyIme(type, core, IPCSkeleton::GetCallingPid()); EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_BOUND); userSession->clientGroupMap_.clear(); ret = userSession->RemoveAllCurrentClient(); @@ -1748,7 +1748,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); @@ -1893,7 +1895,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; @@ -1921,7 +1925,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 @@ -2482,7 +2488,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_); @@ -2498,7 +2506,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_); @@ -2598,7 +2607,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); @@ -2643,7 +2654,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(); diff --git a/test/unittest/cpp_test/src/json_operate_test.cpp b/test/unittest/cpp_test/src/json_operate_test.cpp index bafd6b4a4..bc02f6be9 100644 --- a/test/unittest/cpp_test/src/json_operate_test.cpp +++ b/test/unittest/cpp_test/src/json_operate_test.cpp @@ -411,5 +411,26 @@ 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().imeDataUidList_.clear(); + ImeInfoInquirer::GetInstance().InitImeUidList(); + ASSERT_EQ(ImeInfoInquirer::GetInstance().imeDataUidList_.size(), 2); + auto ret = ImeInfoInquirer::GetInstance().IsContainUid(0); + ASSERT_FALSE(ret); + ret = ImeInfoInquirer::GetInstance().IsContainUid(5521); + ASSERT_TRUE(ret); + ret = ImeInfoInquirer::GetInstance().IsContainUid(7101); + ASSERT_TRUE(ret); +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file -- Gitee