diff --git a/services/src/input_method_system_ability.cpp b/services/src/input_method_system_ability.cpp index 694bcb94ff63ec9cb25e26a7e9abc3cbd59cc40b..eef2c5cdb534b727253cdb3f647dd6b11bf9df96 100644 --- a/services/src/input_method_system_ability.cpp +++ b/services/src/input_method_system_ability.cpp @@ -2301,7 +2301,10 @@ int32_t InputMethodSystemAbility::CheckSwitchPermission(int32_t userId, const Sw return ErrorCode::NO_ERROR; } IMSA_HILOGE("have not PERMISSION_CONNECT_IME_ABILITY!"); - if (IsCurrentIme(userId, tokenId)) { + auto currentBundleName = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId)->bundleName; + if (identityChecker_->IsBundleNameValid(IPCSkeleton::GetCallingTokenID(), currentBundleName) || + IsTmpIme(userId, tokenId)) { + IMSA_HILOGD("current ime!"); return ErrorCode::NO_ERROR; } IMSA_HILOGE("not current ime!"); diff --git a/test/unittest/cpp_test/BUILD.gn b/test/unittest/cpp_test/BUILD.gn index 10bd24d5456e98c76131d00180e5c8723402daaa..a9962a674b7dea2ba773de8fd8117a75e283ee8a 100644 --- a/test/unittest/cpp_test/BUILD.gn +++ b/test/unittest/cpp_test/BUILD.gn @@ -1758,3 +1758,71 @@ ohos_executable("ImeMirrorDemo") { subsystem_name = "inputmethod" part_name = "imf" } + +ohos_executable("InputStatusChangedCbDemo") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + + sources = [ "src/input_status_changed_cb_demo.cpp" ] + include_dirs = [ + "${inputmethod_path}/common/include", + "${inputmethod_path}/interfaces/inner_api/inputmethod_controller/include" + ] + + deps = [ "${inputmethod_path}/interfaces/inner_api/inputmethod_controller:inputmethod_client" ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "access_token:libaccesstoken_sdk", + "access_token:libnativetoken", + "access_token:libtoken_setproc", + "c_utils:utils", + ] + + install_enable = false + subsystem_name = "inputmethod" + part_name = "imf" +} + +ohos_executable("ProxyImeTestDemo") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + + sources = [ + "${inputmethod_path}/services/src/sys_cfg_parser.cpp", + "src/proxy_ime_test_demo.cpp" + ] + include_dirs = [ + "${inputmethod_path}/common/include", + "${inputmethod_path}/interfaces/inner_api/inputmethod_ability/include" + ] + + deps = [ + "${inputmethod_path}/interfaces/inner_api/inputmethod_ability:inputmethod_ability", + "${inputmethod_path}/services/file:imf_file_static", + "${inputmethod_path}/services/json:imf_json_static", + ] + + configs = [ ":module_private_config" ] + + external_deps = [ + "c_utils:utils", + "config_policy:configpolicy_util", + "hilog:libhilog", + "input:libmmi-client", + "ipc:ipc_single", + ] + + install_enable = false + subsystem_name = "inputmethod" + part_name = "imf" +} diff --git a/test/unittest/cpp_test/common/include/tdd_util.h b/test/unittest/cpp_test/common/include/tdd_util.h index 8dd63691bd61e80f58a0b055618b31100713b4e1..c13afbe69357fe63f35be6cda6948ada4a553559 100644 --- a/test/unittest/cpp_test/common/include/tdd_util.h +++ b/test/unittest/cpp_test/common/include/tdd_util.h @@ -74,7 +74,7 @@ public: static void DisabledAllIme(); static void StartApp(const std::string &bundleName); static void StopApp(const std::string &bundleName); - static void ClickApp(const std::string &cmd); + static void ClickApp(); static bool WaitTaskEmpty(); static std::string currentBundleNameMock_; class WindowManager { diff --git a/test/unittest/cpp_test/common/src/tdd_util.cpp b/test/unittest/cpp_test/common/src/tdd_util.cpp index a25ff1dda842a2177d35e7efe5eb1235426f02ba..1fa2a75ac863ac09d31c43b219db5047aeb345c0 100644 --- a/test/unittest/cpp_test/common/src/tdd_util.cpp +++ b/test/unittest/cpp_test/common/src/tdd_util.cpp @@ -30,6 +30,8 @@ #include "accesstoken_kit.h" #include "datashare_helper.h" +#include "display_info.h" +#include "display_manager_lite.h" #include "global.h" #include "if_system_ability_manager.h" #include "input_method_controller.h" @@ -58,6 +60,7 @@ constexpr int32_t FOURTH_PARAM_INDEX = 3; constexpr int32_t FIFTH_PARAM_INDEX = 4; constexpr int32_t SIXTH_PARAM_INDEX = 5; static constexpr int32_t MAX_TIMEOUT_WAIT_FOCUS = 2000; +constexpr int32_t WAIT_CLICK_COMPLETE = 100; uint64_t TddUtil::selfTokenID_ = 0; int32_t TddUtil::userID_ = INVALID_USER_ID; std::string TddUtil::currentBundleNameMock_; @@ -504,11 +507,33 @@ void TddUtil::StopApp(const std::string &bundleName) IMSA_HILOGI("ExecuteCmd ret = %{public}d", ret); } -void TddUtil::ClickApp(const std::string &cmd) +void TddUtil::ClickApp() { + auto displayInfo = Rosen::DisplayManagerLite::GetInstance().GetDefaultDisplay(); + if (displayInfo == nullptr) { + return; + } + int32_t Height = displayInfo->GetHeight() / 2; + int32_t Width = displayInfo->GetWidth() / 2; + std::string cmd = "uinput"; + cmd.append(" ") + .append("-T") + .append(" ") + .append("-d") + .append(" ") + .append(std::to_string(Width)) + .append(" ") + .append(std::to_string(Height)) + .append(" ") + .append("-u") + .append(" ") + .append(std::to_string(Width)) + .append(" ") + .append(std::to_string(Height)); std::string result; auto ret = TddUtil::ExecuteCmd(cmd, result); IMSA_HILOGI("ExecuteCmd ret = %{public}d", ret); + usleep(WAIT_CLICK_COMPLETE); // ensure click complete } bool TddUtil::WaitTaskEmpty() diff --git a/test/unittest/cpp_test/mock/ime_info_inquirer.cpp b/test/unittest/cpp_test/mock/ime_info_inquirer.cpp index de5fd592a483013baa10e2bc8755628f3da946f4..394b4eeb045d62f01324f1a9a7b5edbb643cab6e 100644 --- a/test/unittest/cpp_test/mock/ime_info_inquirer.cpp +++ b/test/unittest/cpp_test/mock/ime_info_inquirer.cpp @@ -18,9 +18,6 @@ #include "global.h" namespace OHOS { namespace MiscServices { -std::shared_ptr ImeInfoInquirer::defaultIme_ = nullptr; -std::shared_ptr ImeInfoInquirer::defaultImeProperty_ = nullptr; -std::shared_ptr ImeInfoInquirer::currentIme_ = nullptr; constexpr const char *MOCK_APP_ID = "MockAppId"; ImeInfoInquirer &ImeInfoInquirer::GetInstance() { @@ -28,19 +25,48 @@ ImeInfoInquirer &ImeInfoInquirer::GetInstance() return instance; } -std::shared_ptr ImeInfoInquirer::GetDefaultImeInfo(int32_t userId) +void ImeInfoInquirer::SetDefaultInputMethod(const std::shared_ptr &imeInfo) { - return defaultIme_; + std::lock_guard lock(defaultImeInfoLock_); + defaultImeInfo_ = imeInfo; } -std::shared_ptr ImeInfoInquirer::GetCurrentInputMethod(int32_t userId) +std::shared_ptr ImeInfoInquirer::GetDefaultImeCfg() +{ + std::lock_guard lock(defaultImeInfoLock_); + if (defaultImeInfo_ == nullptr || defaultImeInfo_->prop.name.empty()) { + return nullptr; + } + auto imeCfg = std::make_shared(); + imeCfg->bundleName = defaultImeInfo_->prop.name; + imeCfg->extName = defaultImeInfo_->prop.id; + imeCfg->imeId = imeCfg->bundleName + "/" + imeCfg->extName; + return imeCfg; +} + +int32_t ImeInfoInquirer::GetDefaultInputMethod(const int32_t userId, std::shared_ptr &prop, bool isBrief) +{ + std::lock_guard lock(defaultImeInfoLock_); + if (defaultImeInfo_ == nullptr || defaultImeInfo_->prop.name.empty()) { + return ErrorCode::ERROR_IME_NOT_FOUND; + } + prop = std::make_shared(defaultImeInfo_->prop); + return ErrorCode::NO_ERROR; +} + +std::shared_ptr ImeInfoInquirer::GetDefaultImeInfo(int32_t userId) { - return currentIme_; + std::lock_guard lock(defaultImeInfoLock_); + return defaultImeInfo_; } std::shared_ptr ImeInfoInquirer::GetDefaultImeCfgProp() { - return defaultImeProperty_; + std::lock_guard lock(defaultImeInfoLock_); + if (defaultImeInfo_ == nullptr || defaultImeInfo_->prop.name.empty()) { + return nullptr; + } + return std::make_shared(defaultImeInfo_->prop); } bool ImeInfoInquirer::GetImeAppId(int32_t userId, const std::string &bundleName, std::string &appId) @@ -55,6 +81,354 @@ bool ImeInfoInquirer::GetImeVersionCode(int32_t userId, const std::string &bundl return true; } +void ImeInfoInquirer::SetDumpInfo(int32_t userId, const std::string &dumpInfo) +{ + std::lock_guard lock(dumpInfosLock_); + dumpInfos_.insert_or_assign(userId, dumpInfo); +} + +std::string ImeInfoInquirer::GetDumpInfo(int32_t userId) +{ + std::lock_guard lock(dumpInfosLock_); + auto iter = dumpInfos_.find(userId); + if (iter == dumpInfos_.end()) { + return ""; + } + return iter->second; +} + +void ImeInfoInquirer::SetImeToStart(int32_t userId, const std::shared_ptr &imeToStart) +{ + std::lock_guard lock(imeToStartLock_); + imeToStart_.insert_or_assign(userId, imeToStart); +} + +std::shared_ptr ImeInfoInquirer::GetImeToStart(int32_t userId) +{ + std::lock_guard lock(imeToStartLock_); + auto iter = imeToStart_.find(userId); + if (iter == imeToStart_.end()) { + return nullptr; + } + return iter->second; +} + +void ImeInfoInquirer::SetImeProperty(int32_t userId, const std::shared_ptr &prop) +{ + std::lock_guard lock(imePropsLock_); + imeProps_.insert_or_assign(userId, prop); +} + +std::shared_ptr ImeInfoInquirer::GetImeProperty( + int32_t userId, const std::string &bundleName, const std::string &extName) +{ + std::lock_guard lock(imePropsLock_); + auto iter = imeProps_.find(userId); + if (iter == imeProps_.end() || iter->second == nullptr) { + return nullptr; + } + if (iter->second->name == bundleName && iter->second->id == extName) { + return iter->second; + } + return nullptr; +} + +std::shared_ptr ImeInfoInquirer::GetCurrentInputMethod(int32_t userId) +{ + std::lock_guard lock(imePropsLock_); + auto iter = imeProps_.find(userId); + if (iter == imeProps_.end()) { + return nullptr; + } + return iter->second; +} + +void ImeInfoInquirer::SetCurrentSubtype(int32_t userId, const std::shared_ptr &subProp) +{ + std::lock_guard lock(imeSubPropsLock_); + imeSubProps_.insert_or_assign(userId, subProp); +} + +std::shared_ptr ImeInfoInquirer::GetCurrentSubtype(int32_t userId) +{ + std::lock_guard lock(imeSubPropsLock_); + auto iter = imeSubProps_.find(userId); + if (iter == imeSubProps_.end()) { + return nullptr; + } + return iter->second; +} + +void ImeInfoInquirer::SetImeInfo(int32_t userId, const std::vector> &imeInfos) +{ + std::lock_guard lock(imeInfosLock_); + imeInfos_.insert_or_assign(userId, imeInfos); +} + +std::shared_ptr ImeInfoInquirer::GetImeInfo( + int32_t userId, const std::string &bundleName, const std::string &subName) +{ + std::lock_guard lock(imeInfosLock_); + auto iter = imeInfos_.find(userId); + if (iter == imeInfos_.end()) { + return nullptr; + } + auto it = + std::find_if(iter->second.begin(), iter->second.end(), [&bundleName](const std::shared_ptr &imeInfo) { + return imeInfo != nullptr && bundleName == imeInfo->prop.name; + }); + if (it == iter->second.end()) { + return nullptr; + } + auto imeInfo = *it; + auto it1 = std::find_if(imeInfo->subProps.begin(), imeInfo->subProps.end(), + [&subName](const SubProperty &subPropTmp) { return subName == subPropTmp.id; }); + if (it1 == imeInfo->subProps.end()) { + return nullptr; + } + return imeInfo; +} + +std::shared_ptr ImeInfoInquirer::FindTargetSubtypeByCondition( + const std::vector &subProps, const Condition &condition) +{ + return nullptr; +} + +int32_t ImeInfoInquirer::ListInputMethod(int32_t userId, InputMethodStatus status, std::vector &props) +{ + return ErrorCode::NO_ERROR; +} + +int32_t ImeInfoInquirer::ListInputMethodSubtype( + int32_t userId, const std::string &bundleName, std::vector &subProps) +{ + std::lock_guard lock(imeInfosLock_); + auto iter = imeInfos_.find(userId); + if (iter == imeInfos_.end()) { + return ErrorCode::ERROR_IME_NOT_FOUND; + } + auto it = + std::find_if(iter->second.begin(), iter->second.end(), [&bundleName](const std::shared_ptr &imeInfo) { + return imeInfo != nullptr && bundleName == imeInfo->prop.name; + }); + if (it == iter->second.end()) { + return ErrorCode::ERROR_IME_NOT_FOUND; + } + subProps = (*it)->subProps; + return ErrorCode::NO_ERROR; +} + +int32_t ImeInfoInquirer::ListCurrentInputMethodSubtype(int32_t userId, std::vector &subProps) +{ + std::string bundleName; + { + std::lock_guard lock(imePropsLock_); + auto iter = imeProps_.find(userId); + if (iter == imeProps_.end() || iter->second == nullptr) { + return ErrorCode::ERROR_IME_NOT_FOUND; + } + bundleName = iter->second->name; + } + std::lock_guard lock(imeInfosLock_); + auto iter = imeInfos_.find(userId); + if (iter == imeInfos_.end()) { + return ErrorCode::ERROR_IME_NOT_FOUND; + } + auto it = + std::find_if(iter->second.begin(), iter->second.end(), [&bundleName](const std::shared_ptr &imeInfo) { + return imeInfo != nullptr && bundleName == imeInfo->prop.name; + }); + if (it == iter->second.end()) { + return ErrorCode::ERROR_IME_NOT_FOUND; + } + subProps = (*it)->subProps; + return ErrorCode::NO_ERROR; +} + +int32_t ImeInfoInquirer::GetSwitchInfoBySwitchCount(SwitchInfo &switchInfo, int32_t userId, uint32_t cacheCount) +{ + return ErrorCode::NO_ERROR; +} + +bool ImeInfoInquirer::IsDefaultImeSet(int32_t userId) +{ + return true; +} + +bool ImeInfoInquirer::IsImeInstalled(const int32_t userId, const std::string &bundleName, const std::string &extName) +{ + std::lock_guard lock(imePropsLock_); + auto iter = imeProps_.find(userId); + if (iter == imeProps_.end() || iter->second == nullptr) { + return false; + } + return iter->second->name == bundleName && iter->second->id == extName; +} + +bool ImeInfoInquirer::IsEnableInputMethod() +{ + std::lock_guard lock(sysCfgLock_); + return sysCfg_.enableInputMethodFeature; +} + +bool ImeInfoInquirer::IsEnableSecurityMode() +{ + std::lock_guard lock(sysCfgLock_); + return sysCfg_.enableFullExperienceFeature; +} + +bool ImeInfoInquirer::IsEnableAppAgent() +{ + std::lock_guard lock(sysCfgLock_); + return sysCfg_.enableAppAgentFeature; +} + +bool ImeInfoInquirer::IsEnableNumKey() +{ + std::lock_guard lock(sysCfgLock_); + return sysCfg_.enableNumKeyFeature; +} + +bool ImeInfoInquirer::IsProxyIme(int32_t callingUid) +{ + std::lock_guard lock(sysCfgLock_); + return sysCfg_.proxyImeUidList.count(callingUid); +} + +bool ImeInfoInquirer::IsSpecialSaUid(int32_t callingUid) +{ + std::lock_guard lock(sysCfgLock_); + return sysCfg_.specialSaUidList.count(callingUid); +} + +void ImeInfoInquirer::InitSystemConfig() +{ +} + +void ImeInfoInquirer::SetSystemConfig(const SystemConfig &sysCfg) +{ + std::lock_guard lock(sysCfgLock_); + sysCfg_ = sysCfg; +} + +SystemConfig ImeInfoInquirer::GetSystemConfig() +{ + std::lock_guard lock(sysCfgLock_); + return sysCfg_; +} + +std::string ImeInfoInquirer::GetSystemSpecialIme() +{ + std::lock_guard lock(sysCfgLock_); + return sysCfg_.systemSpecialInputMethod; +} + +void ImeInfoInquirer::SetRunningIme(int32_t userId, const std::vector &ime) +{ + std::lock_guard lock(runningImeLock_); + runningIme_.insert_or_assign(userId, ime); +} + +bool ImeInfoInquirer::IsRunningIme(int32_t userId, const std::string &bundleName) +{ + std::lock_guard lock(runningImeLock_); + auto iter = runningIme_.find(userId); + if (iter == runningIme_.end()) { + return false; + } + auto it = std::find_if(iter->second.begin(), iter->second.end(), + [&bundleName](const std::string &bundleNameTmp) { return bundleName == bundleNameTmp; }); + return it != iter->second.end(); +} + +std::vector ImeInfoInquirer::GetRunningIme(int32_t userId) +{ + std::lock_guard lock(runningImeLock_); + auto iter = runningIme_.find(userId); + if (iter == runningIme_.end()) { + return {}; + } + return iter->second; +} + +void ImeInfoInquirer::SetInputMethodExtension(pid_t pid) +{ + inputMethodExt_ = pid; +} + +bool ImeInfoInquirer::IsInputMethodExtension(pid_t pid) +{ + return inputMethodExt_ == pid; +} + +void ImeInfoInquirer::SetRestrictedDefaultImeDisplay(uint64_t displayId) +{ + restrictedDefaultImeDisplayId_.store(displayId); +} + +bool ImeInfoInquirer::IsRestrictedDefaultImeByDisplay(uint64_t displayId) +{ + return restrictedDefaultImeDisplayId_.load() == displayId; +} + +void ImeInfoInquirer::SetDynamicStartImeFlag(bool isDynamicStart) +{ + isDynamicStartIme_.store(isDynamicStart); +} + +bool ImeInfoInquirer::IsDynamicStartIme() +{ + return isDynamicStartIme_.load(); +} + +void ImeInfoInquirer::SetDisableNumKeyAppDeviceTypes(const std::unordered_set &types) +{ + std::lock_guard lock(disableNumKeyAppDeviceTypesLock_); + disableNumKeyAppDeviceTypes_ = types; +} + +std::unordered_set ImeInfoInquirer::GetDisableNumKeyAppDeviceTypes() +{ + std::lock_guard lock(disableNumKeyAppDeviceTypesLock_); + return disableNumKeyAppDeviceTypes_; +} + +void ImeInfoInquirer::SetCapacitySupportFlag(const std::string &capacityName, bool isSupport) +{ + std::lock_guard lock(capacitySupportInfosLock_); + capacitySupportInfos_.clear(); + capacitySupportInfos_.insert_or_assign(capacityName, isSupport); +} + +bool ImeInfoInquirer::IsCapacitySupport(const std::string &capacityName) +{ + std::lock_guard lock(capacitySupportInfosLock_); + auto iter = capacitySupportInfos_.find(capacityName); + if (iter == capacitySupportInfos_.end()) { + return false; + } + return iter->second; +} + +void ImeInfoInquirer::SetCompatibleDeviceType(const std::string &bundleName, const std::string &compatibleDeviceType) +{ + std::lock_guard lock(compatibleDeviceTypeLock_); + compatibleDeviceType_.clear(); + compatibleDeviceType_.insert_or_assign(bundleName, compatibleDeviceType); +} + +bool ImeInfoInquirer::GetCompatibleDeviceType(const std::string &bundleName, std::string &compatibleDeviceType) +{ + std::lock_guard lock(compatibleDeviceTypeLock_); + auto iter = compatibleDeviceType_.find(bundleName); + if (iter == compatibleDeviceType_.end()) { + return false; + } + compatibleDeviceType = iter->second; + return true; +} + int32_t ImeInfoInquirer::QueryFullImeInfo(std::vector>> &fullImeInfos) const { if (!isQueryAllFullImeInfosOk_) { @@ -64,7 +438,7 @@ int32_t ImeInfoInquirer::QueryFullImeInfo(std::vector &imeInfos) const +int32_t ImeInfoInquirer::QueryFullImeInfo(int32_t userId, std::vector &imeInfos, bool needBrief) const { if (!isQueryFullImeInfosOk_) { return ErrorCode::ERROR_PACKAGE_MANAGER; diff --git a/test/unittest/cpp_test/mock/ime_info_inquirer.h b/test/unittest/cpp_test/mock/ime_info_inquirer.h index 542b26f4ab04b3c42281d91e8f86eae522ef71c1..995a9aa58b7a95a1b4116e1261afd1ef239fdfe4 100644 --- a/test/unittest/cpp_test/mock/ime_info_inquirer.h +++ b/test/unittest/cpp_test/mock/ime_info_inquirer.h @@ -16,9 +16,11 @@ #ifndef SERVICES_INCLUDE_IME_INFO_ENQUIRER_H #define SERVICES_INCLUDE_IME_INFO_ENQUIRER_H +#include #include #include #include +#include #include #include "input_method_property.h" @@ -33,31 +35,126 @@ struct ImeNativeCfg { std::string extName; }; +struct SystemConfig { + std::string systemInputMethodConfigAbility; + std::string defaultInputMethod; + std::string systemSpecialInputMethod; + bool enableInputMethodFeature = false; + bool enableFullExperienceFeature = false; + EnabledStatus initEnabledState{ EnabledStatus::DISABLED }; + bool enableAppAgentFeature = false; + bool enableNumKeyFeature = false; + std::unordered_set disableNumKeyAppDeviceTypes; + std::unordered_set proxyImeUidList; + std::unordered_set specialSaUidList; + std::unordered_set defaultImeScreenList; + std::unordered_set supportedCapacityList; + std::string dynamicStartImeSysParam; + std::string dynamicStartImeValue; +}; + +enum class Condition { + UPPER = 0, + LOWER, + ENGLISH, + CHINESE, +}; class ImeInfoInquirer { public: static ImeInfoInquirer &GetInstance(); std::shared_ptr GetDefaultImeInfo(int32_t userId); - std::shared_ptr GetCurrentInputMethod(int32_t userId); std::shared_ptr GetDefaultImeCfgProp(); + ImeNativeCfg GetDefaultIme(); + std::shared_ptr GetDefaultImeCfg(); + std::shared_ptr GetCurrentInputMethod(int32_t userId); void SetFullImeInfo(bool isReturnOk, const FullImeInfo &imeInfo); void SetFullImeInfo(bool isReturnOk, const std::vector &imeInfos); void SetFullImeInfo(bool isReturnOk, const std::vector>> &fullImeInfos); int32_t QueryFullImeInfo(std::vector>> &fullImeInfos) const; - int32_t QueryFullImeInfo(int32_t userId, std::vector &imeInfos) const; + int32_t QueryFullImeInfo(int32_t userId, std::vector &imeInfos, bool needBrief = false) const; int32_t GetFullImeInfo(int32_t userId, const std::string &bundleName, FullImeInfo &imeInfo) const; static bool GetImeAppId(int32_t userId, const std::string &bundleName, std::string &appId); static bool GetImeVersionCode(int32_t userId, const std::string &bundleName, uint32_t &versionCode); - ImeNativeCfg GetDefaultIme(); + std::string GetDumpInfo(int32_t userId); + std::shared_ptr GetImeToStart(int32_t userId); + std::shared_ptr GetImeProperty( + int32_t userId, const std::string &bundleName, const std::string &extName = ""); + std::shared_ptr GetCurrentSubtype(int32_t userId); + std::shared_ptr GetImeInfo(int32_t userId, const std::string &bundleName, const std::string &subName); + std::shared_ptr FindTargetSubtypeByCondition( + const std::vector &subProps, const Condition &condition); + int32_t GetDefaultInputMethod(const int32_t userId, std::shared_ptr &prop, bool isBrief = false); + int32_t ListInputMethod(int32_t userId, InputMethodStatus status, std::vector &props); + int32_t ListInputMethodSubtype(int32_t userId, const std::string &bundleName, std::vector &subProps); + int32_t ListCurrentInputMethodSubtype(int32_t userId, std::vector &subProps); + int32_t GetSwitchInfoBySwitchCount(SwitchInfo &switchInfo, int32_t userId, uint32_t cacheCount); + bool IsEnableInputMethod(); + bool IsEnableSecurityMode(); + bool IsEnableAppAgent(); + bool IsEnableNumKey(); + bool IsProxyIme(int32_t callingUid); + bool IsSpecialSaUid(int32_t callingUid); + void InitSystemConfig(); + SystemConfig GetSystemConfig(); + std::string GetSystemSpecialIme(); + bool IsInputMethod(int32_t userId, const std::string &bundleName); + bool IsRunningIme(int32_t userId, const std::string &bundleName); + std::vector GetRunningIme(int32_t userId); + bool IsDefaultImeSet(int32_t userId); + bool IsImeInstalled(const int32_t userId, const std::string &bundleName, const std::string &extName); + bool IsInputMethodExtension(pid_t pid); + bool IsRestrictedDefaultImeByDisplay(uint64_t displayId); + bool IsDynamicStartIme(); + std::unordered_set GetDisableNumKeyAppDeviceTypes(); + bool IsCapacitySupport(const std::string &capacityName); + bool GetCompatibleDeviceType(const std::string &bundleName, std::string &compatibleDeviceType); + void SetDumpInfo(int32_t userId, const std::string &dumpInfo); + void SetImeToStart(int32_t userId, const std::shared_ptr &imeToStart); + void SetImeProperty(int32_t userId, const std::shared_ptr &prop); + void SetCompatibleDeviceType(const std::string &bundleName, const std::string &compatibleDeviceType); + void SetCapacitySupportFlag(const std::string &capacityName, bool isSupport); + void SetDynamicStartImeFlag(bool isDynamicStart); + void SetDisableNumKeyAppDeviceTypes(const std::unordered_set &types); + void SetRunningIme(int32_t userId, const std::vector &ime); + void SetRestrictedDefaultImeDisplay(uint64_t displayId); + void SetInputMethodExtension(pid_t pid); + void SetSystemConfig(const SystemConfig &sysCfg); + void SetDefaultInputMethod(const std::shared_ptr &imeInfo); + void SetCurrentSubtype(int32_t userId, const std::shared_ptr &subProp); + void SetImeInfo(int32_t userId, const std::vector> &imeInfos); + private: - static std::shared_ptr defaultIme_; - static std::shared_ptr currentIme_; - static std::shared_ptr defaultImeProperty_; - bool isQueryAllFullImeInfosOk_ { false }; + bool isQueryAllFullImeInfosOk_{ false }; std::vector>> allFullImeInfos_; - bool isQueryFullImeInfosOk_ { false }; + bool isQueryFullImeInfosOk_{ false }; std::vector fullImeInfos_; - bool isGetFullImeInfoOk_ { false }; + bool isGetFullImeInfoOk_{ false }; FullImeInfo fullImeInfo_; + std::mutex dumpInfosLock_; + std::map dumpInfos_; + std::mutex imeToStartLock_; + std::map> imeToStart_; + std::mutex imePropsLock_; + std::map> imeProps_; + std::mutex imeSubPropsLock_; + std::map> imeSubProps_; + std::mutex compatibleDeviceTypeLock_; + std::map compatibleDeviceType_; + std::mutex capacitySupportInfosLock_; + std::map capacitySupportInfos_; + std::atomic isDynamicStartIme_{ false }; + std::mutex disableNumKeyAppDeviceTypesLock_; + std::unordered_set disableNumKeyAppDeviceTypes_; + std::mutex runningImeLock_; + std::map> runningIme_; + std::atomic restrictedDefaultImeDisplayId_{ 0 }; + pid_t inputMethodExt_{ 0 }; + std::mutex sysCfgLock_; + SystemConfig sysCfg_; + std::mutex defaultImeInfoLock_; + std::shared_ptr defaultImeInfo_; + std::mutex imeInfosLock_; + std::map>> imeInfos_; }; } // namespace MiscServices } // namespace OHOS diff --git a/test/unittest/cpp_test/src/ima_text_edit_test.cpp b/test/unittest/cpp_test/src/ima_text_edit_test.cpp index bbdb8f4a86336df860474ac6175a84cd45c65242..5b41a7b76bcc81563c9709783a396614ed78a7b8 100644 --- a/test/unittest/cpp_test/src/ima_text_edit_test.cpp +++ b/test/unittest/cpp_test/src/ima_text_edit_test.cpp @@ -40,7 +40,6 @@ namespace MiscServices { class ImaTextEditTest : public testing::Test { public: static constexpr const char *NORMAL_EDITOR_BOX_BUNDLE_NAME = "com.example.editorbox"; - static constexpr const char *CLICK_CMD = "uinput -T -d 200 200 -u 200 200"; static const std::string INSERT_TEXT; static constexpr int32_t GET_LENGTH = 2; static constexpr int32_t DEL_LENGTH = 1; @@ -60,7 +59,7 @@ public: InputMethodAbility::GetInstance().SetImeListener(std::make_shared()); InputMethodAbility::GetInstance().SetKdListener(std::make_shared()); TddUtil::StartApp(NORMAL_EDITOR_BOX_BUNDLE_NAME); - TddUtil::ClickApp(CLICK_CMD); + TddUtil::ClickApp(); EXPECT_TRUE(InputMethodEngineListenerImpl::WaitInputStart()); EXPECT_TRUE(TddUtil::WaitTaskEmpty()); } diff --git a/test/unittest/cpp_test/src/ime_proxy_test.cpp b/test/unittest/cpp_test/src/ime_proxy_test.cpp index 284666f78f088867f7dabea9bbb5b4726c604bfe..fb8a6d770494c788d781a8894e472f970e27d8e3 100644 --- a/test/unittest/cpp_test/src/ime_proxy_test.cpp +++ b/test/unittest/cpp_test/src/ime_proxy_test.cpp @@ -41,7 +41,6 @@ constexpr int32_t RETRY_INTERVAL = 100; constexpr int32_t RETRY_TIME = 30; constexpr int32_t WAIT_APP_START_COMPLETE = 1; constexpr int32_t WAIT_BIND_COMPLETE = 1; -constexpr int32_t WAIT_CLICK_COMPLETE = 100; constexpr const char *BUNDLENAME = "com.example.editorbox"; class ImeProxyTest : public testing::Test { public: @@ -119,11 +118,7 @@ public: static void ClickEditor(bool isPc) { isPc ? InputMethodEngineListenerImpl::isEnable_ = true : InputMethodEngineListenerImpl::isEnable_ = false; - static std::string cmd = "uinput -T -d 200 200 -u 200 200"; - std::string result; - auto ret = TddUtil::ExecuteCmd(cmd, result); - EXPECT_TRUE(ret); - usleep(WAIT_CLICK_COMPLETE); // ensure click complete + TddUtil::ClickApp(); } static void StopApp() diff --git a/test/unittest/cpp_test/src/input_method_panel_test.cpp b/test/unittest/cpp_test/src/input_method_panel_test.cpp index f1ebe9353cbd2566410dc9ffe35524efc286bdba..9ac6edf120f2423c2c651a7e2cbdba2a3584c43b 100644 --- a/test/unittest/cpp_test/src/input_method_panel_test.cpp +++ b/test/unittest/cpp_test/src/input_method_panel_test.cpp @@ -370,7 +370,7 @@ void InputMethodPanelTest::ImcPanelShowNumCheck(uint32_t num) } bool ret = imcPanelStatusListenerCv_.wait_for(lock, std::chrono::milliseconds(IMC_WAIT_PANEL_STATUS_LISTEN_TIME), [&num] { - return num == imeShowCallbackNum_; + return imeShowCallbackNum_ >= num; }); EXPECT_TRUE(ret); } diff --git a/test/unittest/cpp_test/src/input_status_changed_cb_demo.cpp b/test/unittest/cpp_test/src/input_status_changed_cb_demo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0ed2f775f7281b735581b899a2eab92460b22a78 --- /dev/null +++ b/test/unittest/cpp_test/src/input_status_changed_cb_demo.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include + +#include "accesstoken_kit.h" +#include "global.h" +#include "ime_event_listener.h" +#include "ime_event_monitor_manager.h" +#include "nativetoken_kit.h" +#include "token_setproc.h" + +using namespace std; +using namespace OHOS::Security::AccessToken; +using namespace OHOS::MiscServices; +std::vector> listeners_; +const int32_t PERMISSION_NUM = 1; + +void GrantNativePermission() +{ + const char **perms = new const char *[PERMISSION_NUM]; + TokenInfoParams infoInstance = { + .dcapsNum = 0, + .permsNum = PERMISSION_NUM, + .aclsNum = 0, + .dcaps = nullptr, + .perms = perms, + .acls = nullptr, + .processName = "imf_test", + .aplStr = "system_core", + }; + uint64_t tokenId = GetAccessTokenId(&infoInstance); + int32_t ret = SetSelfTokenID(tokenId); + if (ret == 0) { + IMSA_HILOGI("SetSelfTokenID success!"); + } else { + IMSA_HILOGE("SetSelfTokenID fail!"); + } + AccessTokenKit::ReloadNativeTokenInfo(); + delete[] perms; +} + +class InputStatusChangedListener : public ImeEventListener { +public: + void OnInputStart(uint32_t callingWndId, int32_t requestKeyboardReason) override + { + printf("=====callingWndId:%u.=====\n", callingWndId); + } + void OnInputStop() override + { + printf("=====run in.=====\n."); + } +}; + +void RegisterInputStatusChangedListener() +{ + auto listener = std::make_shared(); + auto ret = + ImeEventMonitorManager::GetInstance().RegisterImeEventListener(EVENT_INPUT_STATUS_CHANGED_MASK, listener); + if (ret != ErrorCode::NO_ERROR) { + printf("=====Register input status changed listener failed:%d.=====\n", ret); + return; + } + listeners_.push_back(listener); + printf("=====Register input status changed listener succeed, current listener nums:%zu.=====\n", listeners_.size()); +} + +void RegisterSameInputStatusChangedListener() +{ + if (listeners_.empty()) { + printf("=====has no listener.=====\n"); + return; + } + auto listener = listeners_.back(); + auto ret = + ImeEventMonitorManager::GetInstance().RegisterImeEventListener(EVENT_INPUT_STATUS_CHANGED_MASK, listener); + if (ret != ErrorCode::NO_ERROR) { + printf("=====Register same input status changed listener failed:%d.=====\n", ret); + return; + } + printf("=====Register same input status changed succeed, current listener nums:%zu.=====\n", listeners_.size()); +} + +void UnRegisterInputStatusChangedListener() +{ + if (listeners_.empty()) { + printf("=====has no listener.=====\n"); + return; + } + auto listener = listeners_.back(); + auto ret = + ImeEventMonitorManager::GetInstance().UnRegisterImeEventListener(EVENT_INPUT_STATUS_CHANGED_MASK, listener); + if (ret != ErrorCode::NO_ERROR) { + printf("=====UnRegister input status changed listener failed:%d.=====\n", ret); + return; + } + listeners_.pop_back(); + printf("=====UnRegister input status changed succeed, current listener nums:%zu.=====\n", listeners_.size()); +} + +int main() +{ + GrantNativePermission(); + int32_t input = 0; + // 4: input 4 + while (input != 4) { + printf("=====1:RegisterListener 2:RegisterSameListener 3:UnRegisterListener 4:exit=====\n"); + printf("input: "); + cin >> input; + switch (input) { + // 1: input 1 + case 1: + RegisterInputStatusChangedListener(); + break; + // 2: input 2 + case 2: + RegisterSameInputStatusChangedListener(); + break; + // 3: input 3 + case 3: + UnRegisterInputStatusChangedListener(); + break; + // 4: input 4 + case 4: + printf("=====EXIT=====\n"); + break; + default: + printf("=====input error!=====\n"); + } + } + return 0; +} \ No newline at end of file diff --git a/test/unittest/cpp_test/src/proxy_ime_test_demo.cpp b/test/unittest/cpp_test/src/proxy_ime_test_demo.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dc6a30ad9ec22f13775e829f26b336a572809f2b --- /dev/null +++ b/test/unittest/cpp_test/src/proxy_ime_test_demo.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#include "global.h" +#include "input_method_ability_interface.h" +#include "input_method_engine_listener.h" +#include "sys_cfg_parser.h" + +using namespace std; +using namespace OHOS::MiscServices; +const uint32_t INSERT_TEXT_MAX_NUM = 1000; +const uint32_t REGISTER_MAX_NUM = 10; +void InsertText() +{ + for (uint32_t i = 0; i < INSERT_TEXT_MAX_NUM; i++) { + InputMethodAbilityInterface::GetInstance().InsertText("A"); + } +} +class InputMethodEngineListenerImpl : public InputMethodEngineListener { +public: + void OnKeyboardStatus(bool isShow) override + { + } + void OnInputStart() override + { + printf("=====OnInputStart.=====\n"); + std::thread t(InsertText); + t.detach(); + } + int32_t OnInputStop() override + { + printf("=====OnInputStop.=====\n"); + return 0; + } + void OnSetCallingWindow(uint32_t windowId) override + { + } + void OnSetSubtype(const SubProperty &property) override + { + } + void ReceivePrivateCommand(const std::unordered_map &privateCommand) override + { + } + void OnInputFinish() override + { + } + bool IsEnable() override + { + printf("=====IsEnable.=====\n"); + return true; + } + void NotifyPreemption() override + { + printf("=====NotifyPreemption.=====\n"); + } +}; + +void RegisterProxy() +{ + InputMethodAbilityInterface::GetInstance().SetImeListener(std::make_shared()); + auto ret = InputMethodAbilityInterface::GetInstance().RegisteredProxy(); + if (ret != ErrorCode::NO_ERROR) { + printf("=====Register proxy ime failed:%d.=====\n", ret); + return; + } + printf("=====Register proxy ime succeed.=====\n"); +} + +void RegisterProxyLoop() +{ + for (uint32_t i = 0; i < REGISTER_MAX_NUM; i++) { + InputMethodAbilityInterface::GetInstance().SetImeListener(std::make_shared()); + auto ret = InputMethodAbilityInterface::GetInstance().RegisteredProxy(); + if (ret != ErrorCode::NO_ERROR) { + printf("=====RegisterProxyLoop::Register proxy ime failed:%d.=====\n", ret); + return; + } + printf("=====RegisterProxyLoop::Register proxy ime succeed.=====\n"); + } +} + +void UnRegisterProxy() +{ + auto ret = InputMethodAbilityInterface::GetInstance().UnRegisteredProxy(UnRegisteredType::REMOVE_PROXY_IME); + if (ret != ErrorCode::NO_ERROR) { + printf("=====UnRegister proxy ime failed:%d.=====\n", ret); + return; + } + printf("=====UnRegister proxy ime succeed.=====\n"); +} + +int32_t GetProxyImeUid() +{ + SystemConfig systemConfig; + SysCfgParser::ParseSystemConfig(systemConfig); + if (systemConfig.proxyImeUidList.empty()) { + return -1; + } + return *systemConfig.proxyImeUidList.begin(); +} + +int main() +{ + setuid(GetProxyImeUid()); + int32_t input = 0; + // 4: input 4 + while (input != 4) { + printf("=====1:RegisterProxy 2:UnRegisterProxy 3:RegisterProxyLoop 4:exit=====\n"); + printf("input: "); + cin >> input; + switch (input) { + // 1: input 1 + case 1: + RegisterProxy(); + break; + // 2: input 2 + case 2: + UnRegisterProxy(); + break; + // 3: input 3 + case 3: + RegisterProxyLoop(); + break; + // 4: input 4 + case 4: + printf("=====EXIT=====\n"); + break; + default: + printf("=====input error!=====\n"); + } + } + return 0; +} \ No newline at end of file