diff --git a/common/include/global.h b/common/include/global.h index 677fde23257155cb07307be3c96b7972bfee70b9..3748e1939ebbd035879152555e0820043c36fc31 100644 --- a/common/include/global.h +++ b/common/include/global.h @@ -140,6 +140,8 @@ enum { ERROR_SA_TASK_MANAGER_PEND_ACTION_FAILED, ERROR_IMSA_REQUEST_COUNT_OVER_MAXIMUM, ERROR_SA_POST_TASK_FAILED, + ERROR_IME_HAS_STARTED, + ERROR_OPERATION_NOT_ALLOWED, ERROR_IMSA_END, }; }; // namespace ErrorCode diff --git a/common/include/inputmethod_message_handler.h b/common/include/inputmethod_message_handler.h index 6f81b714eb555cf5c81772e3a7042bd7515fd474..7852a75bf4e1c20d2f6d8af17438fadf6d2aa2e7 100644 --- a/common/include/inputmethod_message_handler.h +++ b/common/include/inputmethod_message_handler.h @@ -36,6 +36,7 @@ enum { MSG_ID_PACKAGE_ADDED, MSG_ID_PACKAGE_CHANGED, MSG_ID_SYS_LANGUAGE_CHANGED, + MSG_ID_SYS_MEMORY_CHANGED, MSG_ID_OS_ACCOUNT_STARTED, MSG_ID_BOOT_COMPLETED, MSG_ID_SCREEN_UNLOCK, diff --git a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp index 03339b1d0426e0f40518d9655353c10366628d36..04a611eafa4123b898f6f6ae10eb4e0c97b792b6 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp @@ -589,7 +589,7 @@ int32_t InputMethodAbility::InvokeStartInputCallback(const TextTotalConfig &text } AttachOptions options; options.requestKeyboardReason = textConfig.requestKeyboardReason; - options.isSimpleKeyboardEnabled = IsDefaultIme() ? textConfig.isSimpleKeyboardEnabled : false; + options.isSimpleKeyboardEnabled = textConfig.isSimpleKeyboardEnabled; InvokeAttachOptionsCallback(options, isNotifyInputStart || !isNotify_); if (isNotifyInputStart || !isNotify_) { isNotify_ = true; @@ -1194,7 +1194,7 @@ int32_t InputMethodAbility::NotifyPanelStatus(bool isUseParameterFlag, PanelFlag sysPanelStatus.isPanelRaised = false; sysPanelStatus.needFuncButton = false; } - if (GetAttachOptions().isSimpleKeyboardEnabled && !GetInputAttribute().IsOneTimeCodeFlag()) { + if (GetAttachOptions().isSimpleKeyboardEnabled && IsDefaultIme() && !GetInputAttribute().IsOneTimeCodeFlag()) { sysPanelStatus.needFuncButton = false; } auto systemChannel = GetSystemCmdChannelProxy(); diff --git a/services/BUILD.gn b/services/BUILD.gn index ed11296d0f0966fc936e7608439718018b925812..44a174e44db1dfdd24502b254526e11cb519f90b 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -28,7 +28,7 @@ config("inputmethod_services_native_config") { "${inputmethod_path}/services/adapter/ime_connection_manager/include", "${inputmethod_path}/services/adapter/keyboard/include", "${inputmethod_path}/services/adapter/os_account_adapter/include", - "${inputmethod_path}/services/adapter/system_language_observer/include", + "${inputmethod_path}/services/adapter/system_param_adapter/include", "${inputmethod_path}/services/adapter/window_adapter/include", "${inputmethod_path}/services/adapter/wms_connection_monitor/include", "${inputmethod_path}/services/identity_checker/include", @@ -61,7 +61,7 @@ ohos_shared_library("inputmethod_service") { "${inputmethod_path}/services/adapter/focus_monitor/src/focus_change_listener.cpp", "${inputmethod_path}/services/adapter/focus_monitor/src/focus_monitor_manager.cpp", "${inputmethod_path}/services/adapter/ime_connection_manager/src/ime_connection.cpp", - "${inputmethod_path}/services/adapter/system_language_observer/src/system_language_observer.cpp", + "${inputmethod_path}/services/adapter/system_param_adapter/src/system_param_adapter.cpp", "${inputmethod_path}/services/adapter/window_adapter/src/window_adapter.cpp", "${inputmethod_path}/services/adapter/window_adapter/src/window_display_changed_listener.cpp", "${inputmethod_path}/services/adapter/wms_connection_monitor/src/wms_connection_monitor_manager.cpp", @@ -174,7 +174,7 @@ ohos_static_library("inputmethod_service_static") { "adapter/focus_monitor/src/focus_monitor_manager.cpp", "adapter/ime_connection_manager/src/ime_connection.cpp", "adapter/os_account_adapter/src/os_account_adapter.cpp", - "adapter/system_language_observer/src/system_language_observer.cpp", + "adapter/system_param_adapter/src/system_param_adapter.cpp", "adapter/window_adapter/src/window_adapter.cpp", "adapter/window_adapter/src/window_display_changed_listener.cpp", "adapter/wms_connection_monitor/src/wms_connection_monitor_manager.cpp", diff --git a/services/adapter/settings_data_provider/include/ime_enabled_info_manager.h b/services/adapter/settings_data_provider/include/ime_enabled_info_manager.h index 0381b33cba0a2dcb9d2c4a2671f78eab2d930de1..7ebefde72ebfb54f19ef8a126be96dc614673236 100644 --- a/services/adapter/settings_data_provider/include/ime_enabled_info_manager.h +++ b/services/adapter/settings_data_provider/include/ime_enabled_info_manager.h @@ -133,7 +133,7 @@ public: bool IsDefaultFullMode(int32_t userId, const std::string &bundleName); int32_t SetCurrentIme(int32_t userId, const std::string &imeId, const std::string &subName, bool isSetByUser); int32_t SetTmpIme(int32_t userId, const std::string &imeId); - std::shared_ptr GetCurrentImeCfg(int32_t userId); + std::shared_ptr GetCurrentImeCfg(int32_t userId); // Return value is never nullptr. bool IsDefaultImeSet(int32_t userId); /* add for compatibility that sys ime mod full experience table in it's full experience switch changed */ void OnFullExperienceTableChanged(int32_t userId); diff --git a/services/adapter/settings_data_provider/src/ime_enabled_info_manager.cpp b/services/adapter/settings_data_provider/src/ime_enabled_info_manager.cpp index 918ce7a64af71aa96d97a43799a1dcb2ff7c7006..a16da27491b0ea2d9cd8ed71bf1c605b96c97f13 100644 --- a/services/adapter/settings_data_provider/src/ime_enabled_info_manager.cpp +++ b/services/adapter/settings_data_provider/src/ime_enabled_info_manager.cpp @@ -194,10 +194,6 @@ int32_t ImeEnabledInfoManager::Update( if (ret != ErrorCode::NO_ERROR) { return ret; } - if (!HasEnabledSwitch()) { - IMSA_HILOGD("has no enabled switch."); - return ErrorCode::NO_ERROR; - } ImeEnabledCfg enabledCfg; ret = GetEnabledCacheWithCorrect(userId, bundleName, extensionName, enabledCfg); if (ret != ErrorCode::NO_ERROR) { @@ -238,10 +234,6 @@ int32_t ImeEnabledInfoManager::GetEnabledState(int32_t userId, const std::string IMSA_HILOGW("%{public}d bundleName is empty.", userId); return ErrorCode::ERROR_BAD_PARAMETERS; } - if (!HasEnabledSwitch()) { - status = EnabledStatus::FULL_EXPERIENCE_MODE; - return ErrorCode::NO_ERROR; - } if (bundleName == ImeInfoInquirer::GetInstance().GetSystemSpecialIme()) { status = EnabledStatus::FULL_EXPERIENCE_MODE; return ErrorCode::NO_ERROR; @@ -265,12 +257,6 @@ int32_t ImeEnabledInfoManager::GetEnabledStates(int32_t userId, std::vector namespace OHOS { namespace MiscServices { -class SystemLanguageObserver { +class SystemParamAdapter { public: - static SystemLanguageObserver &GetInstance(); - void Watch(); + static constexpr const char *SYSTEM_LANGUAGE_KEY = "persist.global.language"; + static constexpr const char *MEMORY_WATERMARK_KEY = "resourceschedule.memmgr.min.memmory.watermark"; + static SystemParamAdapter &GetInstance(); + int32_t WatchParam(const std::string &key); + bool GetBoolParam(const std::string &key); private: - static constexpr const char *SYSTEM_LANGUAGE_KEY = "persist.global.language"; - SystemLanguageObserver() = default; - static void OnChange(const char *key, const char *value, void *context); + SystemParamAdapter() = default; + using CbHandler = void (*)(const char *key, const char *value, void *context); + static const std::unordered_map PARAM_CB_HANDLERS; + static void OnLanguageChange(const char *key, const char *value, void *context); + static void OnMemoryChange(const char *key, const char *value, void *context); + static void HandleSysParamChanged(const char *key, const char *value, const char *expectedKey, int32_t messageId); }; } // namespace MiscServices } // namespace OHOS -#endif // IMF_SYSTEM_LANGUAGE_OBSERVER_H +#endif // IMF_SYSTEM_PARAM_ADAPTER_H diff --git a/services/adapter/system_language_observer/src/system_language_observer.cpp b/services/adapter/system_param_adapter/src/system_param_adapter.cpp similarity index 33% rename from services/adapter/system_language_observer/src/system_language_observer.cpp rename to services/adapter/system_param_adapter/src/system_param_adapter.cpp index 239954dd1775c2a03810aecad5b86af7de0d90a6..3bfc7bd41206faa451282d6815a08f61d5cb8c34 100644 --- a/services/adapter/system_language_observer/src/system_language_observer.cpp +++ b/services/adapter/system_param_adapter/src/system_param_adapter.cpp @@ -13,36 +13,67 @@ * limitations under the License. */ -#include "system_language_observer.h" +#include "system_param_adapter.h" + #include "inputmethod_message_handler.h" #include "parameter.h" - +#include "parameters.h" namespace OHOS { namespace MiscServices { -SystemLanguageObserver &SystemLanguageObserver::GetInstance() +const std::unordered_map SystemParamAdapter::PARAM_CB_HANDLERS = { + { SystemParamAdapter::SYSTEM_LANGUAGE_KEY, SystemParamAdapter::OnLanguageChange }, + { SystemParamAdapter::MEMORY_WATERMARK_KEY, SystemParamAdapter::OnMemoryChange }, +}; +SystemParamAdapter &SystemParamAdapter::GetInstance() +{ + static SystemParamAdapter adapter; + return adapter; +} + +int32_t SystemParamAdapter::WatchParam(const std::string &key) +{ + auto it = PARAM_CB_HANDLERS.find(key); + if (it == PARAM_CB_HANDLERS.end() || it->second == nullptr) { + return ErrorCode::ERROR_BAD_PARAMETERS; + } + auto errNo = WatchParameter(key.c_str(), it->second, nullptr); + IMSA_HILOGD("key/ret: %{public}s/%{public}d.", key.c_str(), errNo); + return errNo; +} + +bool SystemParamAdapter::GetBoolParam(const std::string &key) { - static SystemLanguageObserver observer; - return observer; + return system::GetBoolParameter(key, false); } -void SystemLanguageObserver::Watch() +void SystemParamAdapter::OnLanguageChange(const char *key, const char *value, void *context) { - auto errNo = WatchParameter(SYSTEM_LANGUAGE_KEY, OnChange, nullptr); - IMSA_HILOGD("ret: %{public}d.", errNo); + HandleSysParamChanged(key, value, SYSTEM_LANGUAGE_KEY, MessageID::MSG_ID_SYS_LANGUAGE_CHANGED); } -void SystemLanguageObserver::OnChange(const char *key, const char *value, void *context) +void SystemParamAdapter::OnMemoryChange(const char *key, const char *value, void *context) { - if (strncmp(key, SYSTEM_LANGUAGE_KEY, strlen(SYSTEM_LANGUAGE_KEY)) != 0) { + HandleSysParamChanged(key, value, MEMORY_WATERMARK_KEY, MessageID::MSG_ID_SYS_MEMORY_CHANGED); +} + +void SystemParamAdapter::HandleSysParamChanged( + const char *key, const char *value, const char *expectedKey, int32_t messageId) +{ + if (strcmp(key, expectedKey) != 0) { IMSA_HILOGE("key: %{public}s is error!", key); return; } - IMSA_HILOGD("value: %{public}s.", value); - Message *msg = new (std::nothrow) Message(MessageID::MSG_ID_SYS_LANGUAGE_CHANGED, nullptr); + IMSA_HILOGI("value: %{public}s.", value); + Message *msg = new (std::nothrow) Message(messageId, nullptr); if (msg == nullptr) { return; } - MessageHandler::Instance()->SendMessage(msg); + auto mesHandler = MessageHandler::Instance(); + if (mesHandler == nullptr) { + delete msg; + return; + } + mesHandler->SendMessage(msg); } } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/services/include/ime_cfg_manager.h b/services/include/ime_cfg_manager.h index fd0e6ad9223390d77e53255e04364dd7a5571aaa..37839761dc0efc7dd5e51b280007930a29dbaffe 100644 --- a/services/include/ime_cfg_manager.h +++ b/services/include/ime_cfg_manager.h @@ -34,7 +34,7 @@ public: void ModifyImeCfg(const ImePersistInfo &cfg); void ModifyTempScreenLockImeCfg(int32_t userId, const std::string &ime); void DeleteImeCfg(int32_t userId); - std::shared_ptr GetCurrentImeCfg(int32_t userId); + std::shared_ptr GetCurrentImeCfg(int32_t userId); // Return value is never nullptr. bool IsDefaultImeSet(int32_t userId); void SetEventHandler(const std::shared_ptr &eventHandler); diff --git a/services/include/input_method_system_ability.h b/services/include/input_method_system_ability.h index 5945177bc8b4684dc612268cb8e0596474e99b62..0109ceaa0c154ae89f067d31dc490ccbd3ccfbe1 100644 --- a/services/include/input_method_system_ability.h +++ b/services/include/input_method_system_ability.h @@ -119,6 +119,7 @@ private: int32_t OnUserRemoved(const Message *msg); int32_t OnUserStop(const Message *msg); int32_t OnHideKeyboardSelf(const Message *msg); + void OnSysMemChanged(); bool IsNeedSwitch(int32_t userId, const std::string &bundleName, const std::string &subName); int32_t CheckEnableAndSwitchPermission(); int32_t CheckSwitchPermission(int32_t userId, const SwitchInfo &switchInfo, SwitchTrigger trigger); diff --git a/services/include/peruser_session.h b/services/include/peruser_session.h index ff2a811bf4e538a04aa535f232d75e7496a1185d..cb36cbadc60a9a2ca3a83dc8a347899114730324 100644 --- a/services/include/peruser_session.h +++ b/services/include/peruser_session.h @@ -23,6 +23,7 @@ #include "event_status_manager.h" #include "iinput_method_core.h" #include "ime_cfg_manager.h" +#include "ime_connection.h" #include "input_method_types.h" #include "input_type_manager.h" #include "inputmethod_message_handler.h" @@ -167,6 +168,8 @@ public: void DecreaseAttachCount(); uint32_t GetAttachCount(); void IncreaseScbStartCount(); + int32_t TryStartIme(); + int32_t TryDisconnectIme(); private: struct ResetManager { @@ -265,6 +268,9 @@ private: bool IsAttachFinished(); uint32_t GetScbStartCount(); void ResetRestartTasks(); + void SetImeConnection(const sptr &connection); + sptr GetImeConnection(); + void ClearImeConnection(const sptr &connection); std::mutex imeStartLock_; @@ -314,6 +320,9 @@ private: uint32_t attachingCount_ { 0 }; std::mutex scbStartCountMtx_{}; uint32_t scbStartCount_ { 0 }; + std::mutex connectionLock_{}; + sptr connection_ = nullptr; + std::atomic isBlockStartedByLowMem_ = false; }; } // namespace MiscServices } // namespace OHOS diff --git a/services/src/input_method_system_ability.cpp b/services/src/input_method_system_ability.cpp index 36508d4e2386a4f2e4695b0070355c61cffe9947..c1171c25e627a47b84ae7cc2cde35ae4b8d791e8 100644 --- a/services/src/input_method_system_ability.cpp +++ b/services/src/input_method_system_ability.cpp @@ -39,7 +39,7 @@ #ifdef IMF_SCREENLOCK_MGR_ENABLE #include "screenlock_manager.h" #endif -#include "system_language_observer.h" +#include "system_param_adapter.h" #include "wms_connection_observer.h" #include "xcollie/xcollie.h" #ifdef IMF_ON_DEMAND_START_STOP_SA_ENABLE @@ -1527,6 +1527,10 @@ void InputMethodSystemAbility::WorkThread() } break; } + case MSG_ID_SYS_MEMORY_CHANGED: { + OnSysMemChanged(); + break; + } default: { IMSA_HILOGD("the message is %{public}d.", msg->msgId_); break; @@ -1973,7 +1977,7 @@ bool InputMethodSystemAbility::InitPasteboardMonitor() void InputMethodSystemAbility::InitSystemLanguageMonitor() { - SystemLanguageObserver::GetInstance().Watch(); + SystemParamAdapter::GetInstance().WatchParam(SystemParamAdapter::SYSTEM_LANGUAGE_KEY); } void InputMethodSystemAbility::InitFocusChangedMonitor() @@ -2294,6 +2298,7 @@ void InputMethodSystemAbility::HandleMemStarted() // singleton IMSA_HILOGI("MemMgr start."); Memory::MemMgrClient::GetInstance().NotifyProcessStatus(getpid(), 1, 1, INPUT_METHOD_SYSTEM_ABILITY_ID); + SystemParamAdapter::GetInstance().WatchParam(SystemParamAdapter::MEMORY_WATERMARK_KEY); auto session = UserSessionManager::GetInstance().GetUserSession(userId_); RestartSessionIme(session); } @@ -2680,5 +2685,18 @@ int32_t InputMethodSystemAbility::StartSecurityIme(int32_t &userId, InputClientI } return ErrorCode::NO_ERROR; } + +void InputMethodSystemAbility::OnSysMemChanged() +{ + auto session = UserSessionManager::GetInstance().GetUserSession(userId_); + if (session == nullptr) { + return; + } + if (SystemParamAdapter::GetInstance().GetBoolParam(SystemParamAdapter::MEMORY_WATERMARK_KEY)) { + session->TryDisconnectIme(); + return; + } + session->TryStartIme(); +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/services/src/peruser_session.cpp b/services/src/peruser_session.cpp index c67651e7e9f31c76ff2ae14e7cf4d7fecc8ea117..c3c131562f60189b6b9efa2b17951008acf68325 100644 --- a/services/src/peruser_session.cpp +++ b/services/src/peruser_session.cpp @@ -24,7 +24,6 @@ #include "full_ime_info_manager.h" #include "identity_checker_impl.h" #include "im_common_event_manager.h" -#include "ime_connection.h" #include "ime_enabled_info_manager.h" #include "ime_info_inquirer.h" #include "input_control_channel_service_impl.h" @@ -36,6 +35,7 @@ #include "os_account_adapter.h" #include "scene_board_judgement.h" #include "system_ability_definition.h" +#include "system_param_adapter.h" #include "wms_connection_observer.h" #include "dm_common.h" #include "display_manager.h" @@ -244,7 +244,11 @@ void PerUserSession::OnImeDied(const sptr &remote, ImeType typ return; } if (type == ImeType::IME && currentImeInfo->bundleName == defaultImeInfo->name) { - StartImeInImeDied(); + if (!SystemParamAdapter::GetInstance().GetBoolParam(SystemParamAdapter::MEMORY_WATERMARK_KEY)) { + StartImeInImeDied(); + } else { + isBlockStartedByLowMem_.store(true); + } } } @@ -1083,6 +1087,8 @@ void PerUserSession::OnScreenLock() auto imeData = GetImeData(ImeType::IME); if (imeData == nullptr) { IMSA_HILOGD("imeData is nullptr"); + std::pair ime{ "", "" }; + SetImeUsedBeforeScreenLocked(ime); return; } SetImeUsedBeforeScreenLocked(imeData->ime); @@ -1121,10 +1127,13 @@ std::shared_ptr PerUserSession::GetRealCurrentIme(bool needMinGuar InputTypeManager::GetInstance().GetImeByInputType(type, inputTypeIme); currentIme = GetImeNativeCfg(userId_, inputTypeIme.bundleName, inputTypeIme.subName); if (currentIme != nullptr) { + IMSA_HILOGD("get inputType ime:%{public}d!", type); return currentIme; } } if (IsPreconfiguredDefaultImeSpecified(*clientInfo)) { + IMSA_HILOGD("get preconfigured default ime:%{public}d/%{public}d!", + clientInfo->config.isSimpleKeyboardEnabled, clientInfo->config.inputAttribute.IsOneTimeCodeFlag()); auto preconfiguredIme = ImeInfoInquirer::GetInstance().GetDefaultImeCfg(); auto defaultIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_); if (preconfiguredIme != nullptr && defaultIme != nullptr && defaultIme->imeId == preconfiguredIme->imeId) { @@ -1138,6 +1147,7 @@ std::shared_ptr PerUserSession::GetRealCurrentIme(bool needMinGuar #ifdef IMF_SCREENLOCK_MGR_ENABLE auto screenLockMgr = ScreenLock::ScreenLockManager::GetInstance(); if (screenLockMgr != nullptr && screenLockMgr->IsScreenLocked()) { + IMSA_HILOGD("get screen locked ime!"); auto preconfiguredIme = ImeInfoInquirer::GetInstance().GetDefaultImeCfg(); auto defaultIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_); if (preconfiguredIme != nullptr && (defaultIme == nullptr || defaultIme->imeId != preconfiguredIme->imeId)) { @@ -1145,6 +1155,7 @@ std::shared_ptr PerUserSession::GetRealCurrentIme(bool needMinGuar } } #endif + IMSA_HILOGD("get user set ime:%{public}d!", needMinGuarantee); return needMinGuarantee ? ImeInfoInquirer::GetInstance().GetImeToStart(userId_) : ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_); } @@ -1199,6 +1210,7 @@ int32_t PerUserSession::StartCurrentIme(bool isStopCurrentIme) IMSA_HILOGE("imeToStart is nullptr!"); return ErrorCode::ERROR_IMSA_IME_TO_START_NULLPTR; } + IMSA_HILOGI("ime info:%{public}s/%{public}s.", imeToStart->bundleName.c_str(), imeToStart->subName.c_str()); auto ret = StartIme(imeToStart, isStopCurrentIme); if (ret != ErrorCode::NO_ERROR) { IMSA_HILOGE("failed to start ime!"); @@ -1294,6 +1306,7 @@ int32_t PerUserSession::StartInputService(const std::shared_ptr &i IMSA_HILOGE("failed to create connection!"); return ErrorCode::ERROR_IMSA_MALLOC_FAILED; } + SetImeConnection(connection); auto want = GetWant(imeToStart); IMSA_HILOGI("connect %{public}s start!", imeToStart->imeId.c_str()); ret = AAFwk::AbilityManagerClient::GetInstance()->ConnectExtensionAbility(want, connection, userId_); @@ -1301,6 +1314,7 @@ int32_t PerUserSession::StartInputService(const std::shared_ptr &i IMSA_HILOGE("connect %{public}s failed, ret: %{public}d!", imeToStart->imeId.c_str(), ret); InputMethodSysEvent::GetInstance().InputmethodFaultReporter( ErrorCode::ERROR_IMSA_IME_CONNECT_FAILED, imeToStart->imeId, "failed to start ability."); + SetImeConnection(nullptr); return ErrorCode::ERROR_IMSA_IME_CONNECT_FAILED; } if (!isImeStarted_.GetValue()) { @@ -1847,6 +1861,7 @@ int32_t PerUserSession::StartIme(const std::shared_ptr &ime, bool } return StartCurrentIme(ime); } + IMSA_HILOGD("%{public}s switch to %{public}s!", imeData->ime.first.c_str(), ime->bundleName.c_str()); return StartNewIme(ime); } @@ -1889,8 +1904,11 @@ int32_t PerUserSession::StartCurrentIme(const std::shared_ptr &ime imeData->ime.second.c_str()); return HandleStartImeTimeout(ime); } + IMSA_HILOGW("%{public}s/%{public}s start retry!", imeData->ime.first.c_str(), imeData->ime.second.c_str()); return StartInputService(ime); } + IMSA_HILOGW("%{public}s/%{public}s start in exiting, force stop firstly!", imeData->ime.first.c_str(), + imeData->ime.second.c_str()); auto ret = ForceStopCurrentIme(); if (ret != ErrorCode::NO_ERROR) { return ret; @@ -2512,5 +2530,85 @@ uint32_t PerUserSession::GetAttachCount() std::lock_guard lock(attachCountMtx_); return attachingCount_; } + +int32_t PerUserSession::TryStartIme() +{ + if (!isBlockStartedByLowMem_.load()) { + IMSA_HILOGI("ime is not blocked in starting by low mem, no need to deal."); + return ErrorCode::ERROR_OPERATION_NOT_ALLOWED; + } + isBlockStartedByLowMem_.store(false); + auto imeData = GetImeData(ImeType::IME); + if (imeData != nullptr) { + IMSA_HILOGI("has running ime:%{public}s, no need to deal.", imeData->ime.first.c_str()); + return ErrorCode::ERROR_IME_HAS_STARTED; + } + auto cfgIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_); + if (cfgIme == nullptr || ImeInfoInquirer::GetInstance().GetDefaultIme().bundleName != cfgIme->bundleName) { + IMSA_HILOGI("has no cfgIme or cfg ime is not sys preconfigured ime, can not start."); + return ErrorCode::ERROR_OPERATION_NOT_ALLOWED; + } +#ifndef IMF_ON_DEMAND_START_STOP_SA_ENABLE + if (!ImeStateManagerFactory::GetInstance().GetDynamicStartIme()) { + StartImeIfInstalled(); + } +#endif + return ErrorCode::NO_ERROR; +} + +int32_t PerUserSession::TryDisconnectIme() +{ + auto imeData = GetImeData(ImeType::IME); + if (imeData == nullptr) { + return ErrorCode::ERROR_IME_NOT_STARTED; + } + if (GetAttachCount() != 0) { + IMSA_HILOGI("attaching, can not disconnect."); + return ErrorCode::ERROR_OPERATION_NOT_ALLOWED; + } + auto clientInfo = GetCurrentClientInfo(); + if (clientInfo != nullptr) { + IMSA_HILOGI("has current client, can not disconnect."); + return ErrorCode::ERROR_OPERATION_NOT_ALLOWED; + } + auto abilityMgr = AAFwk::AbilityManagerClient::GetInstance(); + if (abilityMgr == nullptr) { + return ErrorCode::ERROR_IMSA_NULLPTR; + } + auto imeConnection = GetImeConnection(); + if (imeConnection == nullptr) { + return ErrorCode::ERROR_IME_NOT_STARTED; + } + auto ret = abilityMgr->DisconnectAbility(imeConnection); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("disConnect %{public}s/%{public}s failed, ret:%{public}d.", imeData->ime.first.c_str(), + imeData->ime.second.c_str(), ret); + return ErrorCode::ERROR_IMSA_IME_DISCONNECT_FAILED; + } + ClearImeConnection(imeConnection); + return ErrorCode::NO_ERROR; +} + +void PerUserSession::SetImeConnection(const sptr &connection) +{ + std::lock_guard lock(connectionLock_); + connection_ = connection; +} + +sptr PerUserSession::GetImeConnection() +{ + std::lock_guard lock(connectionLock_); + return connection_; +} + +void PerUserSession::ClearImeConnection(const sptr &connection) +{ + std::lock_guard lock(connectionLock_); + if (connection == nullptr || connection_ == nullptr || connection->AsObject() != connection_->AsObject()) { + return; + } + IMSA_HILOGI("clear imeConnection."); + connection_ = nullptr; +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/test/unittest/cpp_test/BUILD.gn b/test/unittest/cpp_test/BUILD.gn index 7ab89b7e71dee84c7568b2067a5ff0f621e0312e..22231f939f4766909268105c6b2d4c0a63581b3a 100644 --- a/test/unittest/cpp_test/BUILD.gn +++ b/test/unittest/cpp_test/BUILD.gn @@ -584,6 +584,7 @@ ohos_unittest("InputMethodPrivateMemberTest") { external_deps = [ "ability_runtime:ability_manager", "ability_runtime:runtime", + "ability_runtime:ability_connect_callback_stub", "access_token:libaccesstoken_sdk", "bundle_framework:appexecfwk_base", "bundle_framework:appexecfwk_core", diff --git a/test/unittest/cpp_test/common/BUILD.gn b/test/unittest/cpp_test/common/BUILD.gn index 0c4bd0b144e2fdc8e59f50c9a77c4e52234ba135..1ff1ca55ad3c2ec20f79fa4c365202b3482fdc80 100644 --- a/test/unittest/cpp_test/common/BUILD.gn +++ b/test/unittest/cpp_test/common/BUILD.gn @@ -58,6 +58,7 @@ ohos_static_library("inputmethod_tdd_util") { "access_token:libaccesstoken_sdk", "access_token:libnativetoken", "access_token:libtoken_setproc", + "ability_runtime:ability_connect_callback_stub", "bundle_framework:appexecfwk_base", "bundle_framework:appexecfwk_core", "cJSON:cjson", diff --git a/test/unittest/cpp_test/src/identity_checker_test.cpp b/test/unittest/cpp_test/src/identity_checker_test.cpp index e7fd0c2e1b2aca2efdb6d470a1a7e8907eded390..22d824b2e6bb7ae02d181a36ceae2e93c5fc7e05 100644 --- a/test/unittest/cpp_test/src/identity_checker_test.cpp +++ b/test/unittest/cpp_test/src/identity_checker_test.cpp @@ -87,6 +87,7 @@ public: static const constexpr char *CURRENT_IME = "testBundleName/testExtname"; static const constexpr char *CURRENT_SUBNAME = "testSubName"; static const constexpr char *CURRENT_BUNDLENAME = "testBundleName"; + static const constexpr char *CURRENT_EXTNAME = "testExtName"; static void SetUpTestCase(void); static void TearDownTestCase(void); void SetUp(); @@ -681,6 +682,11 @@ HWTEST_F(IdentityCheckerTest, testDisplayOptionalInputMethod_001, TestSize.Level HWTEST_F(IdentityCheckerTest, testSwitchInputMethod_001, TestSize.Level1) { IMSA_HILOGI("IdentityCheckerTest testSwitchInputMethod_001 start"); + ImeEnabledCfg cfg; + ImeEnabledInfo enabledInfo{ CURRENT_BUNDLENAME, CURRENT_EXTNAME, EnabledStatus::BASIC_MODE }; + enabledInfo.extraInfo.isDefaultIme = true; + cfg.enabledInfos.push_back(enabledInfo); + ImeEnabledInfoManager::GetInstance().imeEnabledCfg_.insert_or_assign(MAIN_USER_ID, cfg); service_->identityChecker_ = identityCheckerImpl_; int32_t ret = IdentityCheckerTest::service_->SwitchInputMethod( CURRENT_BUNDLENAME, CURRENT_SUBNAME, static_cast(SwitchTrigger::CURRENT_IME)); @@ -697,6 +703,11 @@ HWTEST_F(IdentityCheckerTest, testSwitchInputMethod_001, TestSize.Level1) HWTEST_F(IdentityCheckerTest, testSwitchInputMethod_002, TestSize.Level1) { IMSA_HILOGI("IdentityCheckerTest testSwitchInputMethod_002 start"); + ImeEnabledCfg cfg; + ImeEnabledInfo enabledInfo{ CURRENT_BUNDLENAME, CURRENT_EXTNAME, EnabledStatus::BASIC_MODE }; + enabledInfo.extraInfo.isDefaultIme = true; + cfg.enabledInfos.push_back(enabledInfo); + ImeEnabledInfoManager::GetInstance().imeEnabledCfg_.insert_or_assign(MAIN_USER_ID, cfg); IdentityCheckerTest::IdentityCheckerMock::hasPermission_ = false; IdentityCheckerTest::IdentityCheckerMock::isBundleNameValid_ = true; int32_t ret = IdentityCheckerTest::service_->SwitchInputMethod( @@ -714,6 +725,11 @@ HWTEST_F(IdentityCheckerTest, testSwitchInputMethod_002, TestSize.Level1) HWTEST_F(IdentityCheckerTest, testSwitchInputMethod_003, TestSize.Level1) { IMSA_HILOGI("IdentityCheckerTest testSwitchInputMethod_003 start"); + ImeEnabledCfg cfg; + ImeEnabledInfo enabledInfo{ CURRENT_BUNDLENAME, CURRENT_EXTNAME, EnabledStatus::BASIC_MODE }; + enabledInfo.extraInfo.isDefaultIme = true; + cfg.enabledInfos.push_back(enabledInfo); + ImeEnabledInfoManager::GetInstance().imeEnabledCfg_.insert_or_assign(MAIN_USER_ID, cfg); IdentityCheckerTest::IdentityCheckerMock::hasPermission_ = true; IdentityCheckerTest::IdentityCheckerMock::isBundleNameValid_ = false; int32_t ret = IdentityCheckerTest::service_->SwitchInputMethod( @@ -731,6 +747,11 @@ HWTEST_F(IdentityCheckerTest, testSwitchInputMethod_003, TestSize.Level1) HWTEST_F(IdentityCheckerTest, testSwitchInputMethod_004, TestSize.Level1) { IMSA_HILOGI("IdentityCheckerTest testSwitchInputMethod_004 start"); + ImeEnabledCfg cfg; + ImeEnabledInfo enabledInfo{ CURRENT_BUNDLENAME, CURRENT_EXTNAME, EnabledStatus::BASIC_MODE }; + enabledInfo.extraInfo.isDefaultIme = true; + cfg.enabledInfos.push_back(enabledInfo); + ImeEnabledInfoManager::GetInstance().imeEnabledCfg_.insert_or_assign(MAIN_USER_ID, cfg); service_->identityChecker_ = identityCheckerImpl_; IdentityCheckerTest::IdentityCheckerMock::isFromShell_ = true; IdentityCheckerTest::IdentityCheckerMock::isBundleNameValid_ = false; 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 88f8f24c18f647b5ef82d379ef9f8f81b57941b3..c48ea68ccdb27cdfaa6ce40dce65a47c3d6355df 100644 --- a/test/unittest/cpp_test/src/input_method_controller_test.cpp +++ b/test/unittest/cpp_test/src/input_method_controller_test.cpp @@ -1776,7 +1776,7 @@ HWTEST_F(InputMethodControllerTest, testGetInputMethodState_002, TestSize.Level0 EnabledStatus status = EnabledStatus::DISABLED; auto ret = inputMethodController_->GetInputMethodState(status); EXPECT_EQ(ret, ErrorCode::NO_ERROR); - EXPECT_TRUE(status == EnabledStatus::FULL_EXPERIENCE_MODE); + EXPECT_TRUE(status == EnabledStatus::BASIC_MODE); } /** @@ -1827,23 +1827,6 @@ HWTEST_F(InputMethodControllerTest, testGetInputMethodState_004, TestSize.Level0 EXPECT_TRUE(status == EnabledStatus::BASIC_MODE); } -/** - * @tc.name: testGetInputMethodState_005 - * @tc.desc: IMA - * @tc.type: FUNC - * @tc.require: - */ -HWTEST_F(InputMethodControllerTest, testGetInputMethodState_005, TestSize.Level0) -{ - IMSA_HILOGI("InputMethodControllerTest testGetInputMethodState_005 Test START"); - EnabledStatus status = EnabledStatus::DISABLED; - ImeInfoInquirer::GetInstance().systemConfig_.enableFullExperienceFeature = false; - ImeInfoInquirer::GetInstance().systemConfig_.enableInputMethodFeature = false; - auto ret = inputMethodController_->GetInputMethodState(status); - EXPECT_EQ(ret, ErrorCode::NO_ERROR); - EXPECT_TRUE(status == EnabledStatus::FULL_EXPERIENCE_MODE); -} - /** * @tc.name: testIsDefaultImeSetAndEnableIme * @tc.desc: test IMC Reset 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 d56e08653ec73b9a68a16e44674271740ed5c513..eceb33e3423846a4ab3651697b42fd8b223b158e 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 @@ -26,6 +26,9 @@ #include "wms_connection_observer.h" #include "settings_data_utils.h" #include "input_type_manager.h" +#include "user_session_manager.h" +#include "system_param_adapter.h" +#include "ime_state_manager_factory.h" #undef private #include #include @@ -50,7 +53,6 @@ #include "keyboard_event.h" #include "os_account_manager.h" #include "tdd_util.h" -#include "user_session_manager.h" using namespace testing::ext; using namespace testing::mt; @@ -1974,7 +1976,9 @@ HWTEST_F(InputMethodPrivateMemberTest, SA_GetRealCurrentIme_001, TestSize.Level0 ImeEnabledCfg cfg; ImeEnabledInfo enabledInfo{ bundleName1, extName1, EnabledStatus::BASIC_MODE }; enabledInfo.extraInfo.isDefaultIme = true; + ImeEnabledInfo enabledInfo1{ realPreIme->name, realPreIme->id, EnabledStatus::BASIC_MODE }; cfg.enabledInfos.push_back(enabledInfo); + cfg.enabledInfos.push_back(enabledInfo1); ImeEnabledInfoManager::GetInstance().imeEnabledCfg_.insert_or_assign(MAIN_USER_ID, cfg); std::string bundleName2 = "bundleName2"; @@ -2553,5 +2557,150 @@ HWTEST_F(InputMethodPrivateMemberTest, SA_GetRealCurrentIme_004, TestSize.Level0 EXPECT_EQ(ime->bundleName, bundleName2); EXPECT_TRUE(ime->subName.empty()); } + +/** + * @tc.name: SA_TestSysParamChanged_001 + * @tc.desc: SA_TestSysParamChanged_001 + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(InputMethodPrivateMemberTest, SA_TestSysParamChanged_001, TestSize.Level0) +{ + IMSA_HILOGI("InputMethodPrivateMemberTest::SA_TestSysParamChanged_001 start."); + auto ret = SystemParamAdapter::GetInstance().WatchParam("abnormal"); + EXPECT_EQ(ret, ErrorCode::ERROR_BAD_PARAMETERS); + SystemParamAdapter::HandleSysParamChanged("key", "value", "key", 0); + SystemParamAdapter::HandleSysParamChanged("key", "value", "abnormalKey", 0); + InputMethodSystemAbility sysAbility; + UserSessionManager::GetInstance().userSessions_.clear(); + sysAbility.OnSysMemChanged(); + auto userSession = std::make_shared(MAIN_USER_ID); + UserSessionManager::GetInstance().userSessions_.insert_or_assign(MAIN_USER_ID, userSession); + sysAbility.OnSysMemChanged(); + service_->userId_ = -1; + ret = SystemParamAdapter::GetInstance().WatchParam(SystemParamAdapter::MEMORY_WATERMARK_KEY); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); +} + +/** + * @tc.name: SA_TryStartIme_001 + * @tc.desc: SA_TryStartIme_001 + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(InputMethodPrivateMemberTest, SA_TryStartIme_001, TestSize.Level0) +{ + IMSA_HILOGI("InputMethodPrivateMemberTest::SA_TryStartIme_001 start."); + auto userSession = std::make_shared(MAIN_USER_ID); + userSession->isBlockStartedByLowMem_ = false; + auto ret = userSession->TryStartIme(); + EXPECT_EQ(ret, ErrorCode::ERROR_OPERATION_NOT_ALLOWED); + + userSession->isBlockStartedByLowMem_ = true; + auto imeData = std::make_shared(nullptr, nullptr, nullptr, 10); + userSession->imeData_.insert_or_assign(ImeType::IME, imeData); + ret = userSession->TryStartIme(); + EXPECT_EQ(ret, ErrorCode::ERROR_IME_HAS_STARTED); + + userSession->imeData_.clear(); + std::string bundleName1 = "bundleName1"; + std::string extName1 = "extName1"; + ImeEnabledCfg cfg; + ImeEnabledInfo enabledInfo{ bundleName1, extName1, EnabledStatus::BASIC_MODE }; + enabledInfo.extraInfo.isDefaultIme = true; + cfg.enabledInfos.push_back(enabledInfo); + ImeEnabledInfoManager::GetInstance().imeEnabledCfg_.insert_or_assign(MAIN_USER_ID, cfg); + + std::string bundleName2 = "bundleName2"; + std::string extName2 = "extName2"; + ImeInfoInquirer::GetInstance().systemConfig_.defaultInputMethod = bundleName2 + "/" + extName2; + userSession->isBlockStartedByLowMem_ = true; + ret = userSession->TryStartIme(); + EXPECT_EQ(ret, ErrorCode::ERROR_OPERATION_NOT_ALLOWED); + + ImeInfoInquirer::GetInstance().systemConfig_.defaultInputMethod = bundleName1 + "/" + extName1; + userSession->isBlockStartedByLowMem_ = true; + ImeStateManagerFactory::GetInstance().ifDynamicStartIme_ = false; + ret = userSession->TryStartIme(); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + userSession->isBlockStartedByLowMem_ = true; + ImeStateManagerFactory::GetInstance().ifDynamicStartIme_ = true; + ret = userSession->TryStartIme(); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); +} + +/** + * @tc.name: SA_TryDisconnectIme_001 + * @tc.desc: SA_TryDisconnectIme_001 + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(InputMethodPrivateMemberTest, SA_TryDisconnectIme_001, TestSize.Level0) +{ + IMSA_HILOGI("InputMethodPrivateMemberTest::SA_TryDisconnectIme_001 start."); + auto userSession = std::make_shared(MAIN_USER_ID); + userSession->imeData_.clear(); + 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); + + userSession->attachingCount_ = 1; + ret = userSession->TryDisconnectIme(); + EXPECT_EQ(ret, ErrorCode::ERROR_OPERATION_NOT_ALLOWED); + + userSession->attachingCount_ = 0; + auto group = std::make_shared(DEFAULT_DISPLAY_ID, nullptr); + sptr client = new (std::nothrow) InputClientServiceImpl(); + group->currentClient_ = client; + auto info = std::make_shared(); + group->mapClients_.insert_or_assign(client->AsObject(), info); + userSession->clientGroupMap_.insert_or_assign(DEFAULT_DISPLAY_ID, group); + ret = userSession->TryDisconnectIme(); + EXPECT_EQ(ret, ErrorCode::ERROR_OPERATION_NOT_ALLOWED); + + userSession->clientGroupMap_.clear(); + userSession->SetImeConnection(nullptr); + ret = userSession->TryDisconnectIme(); + EXPECT_EQ(ret, ErrorCode::ERROR_IME_NOT_STARTED); + sptr connection = new (std::nothrow) ImeConnection(); + userSession->SetImeConnection(connection); + ret = userSession->TryDisconnectIme(); + EXPECT_EQ(ret, ErrorCode::ERROR_IMSA_IME_DISCONNECT_FAILED); +} + +/** + * @tc.name: SA_TestClearImeConnection_001 + * @tc.desc: SA_TestClearImeConnection_001 + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(InputMethodPrivateMemberTest, SA_TestClearImeConnection_001, TestSize.Level0) +{ + IMSA_HILOGI("InputMethodPrivateMemberTest::SA_TestClearImeConnection_001 start."); + sptr connection = new (std::nothrow) ImeConnection(); + sptr connection1 = new (std::nothrow) ImeConnection(); + auto userSession = std::make_shared(MAIN_USER_ID); + + userSession->SetImeConnection(connection); + EXPECT_EQ(userSession->GetImeConnection(), connection); + userSession->ClearImeConnection(connection); + EXPECT_EQ(userSession->GetImeConnection(), nullptr); + + userSession->SetImeConnection(connection); + EXPECT_EQ(userSession->GetImeConnection(), connection); + userSession->ClearImeConnection(nullptr); + EXPECT_EQ(userSession->GetImeConnection(), connection); + + userSession->SetImeConnection(nullptr); + EXPECT_EQ(userSession->GetImeConnection(), nullptr); + userSession->ClearImeConnection(connection); + EXPECT_EQ(userSession->GetImeConnection(), nullptr); + + userSession->SetImeConnection(connection); + EXPECT_EQ(userSession->GetImeConnection(), connection); + userSession->ClearImeConnection(connection1); + EXPECT_EQ(userSession->GetImeConnection(), connection); +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file