From 1cc8d0dd9de4889b0174b01b64090bf95575ec8e Mon Sep 17 00:00:00 2001 From: cy7717 Date: Tue, 5 Sep 2023 20:38:35 +0800 Subject: [PATCH] =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E8=AF=AD=E8=A8=80=E5=8F=98?= =?UTF-8?q?=E5=8C=96=E7=9B=91=E5=90=AC=E6=9B=B4=E6=96=B0=E5=BD=93=E5=89=8D?= =?UTF-8?q?ime=E4=BF=A1=E6=81=AF=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: cy7717 --- services/BUILD.gn | 3 + .../include/system_language_observer.h | 39 ++++ .../src/system_language_observer.cpp | 52 +++++ services/include/ime_info_inquirer.h | 22 ++- .../include/input_method_system_ability.h | 8 +- services/src/ime_info_inquirer.cpp | 184 ++++++++---------- services/src/input_method_system_ability.cpp | 84 ++++---- .../src/input_method_private_member_test.cpp | 38 ++-- 8 files changed, 256 insertions(+), 174 deletions(-) create mode 100644 services/adapter/system_language_observer/include/system_language_observer.h create mode 100644 services/adapter/system_language_observer/src/system_language_observer.cpp diff --git a/services/BUILD.gn b/services/BUILD.gn index 246d8f872..b490d89a0 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -24,6 +24,7 @@ config("inputmethod_services_native_config") { "${inputmethod_path}/frameworks/native/inputmethod_controller/include", "${inputmethod_path}/services/adapter/focus_monitor/include", "${inputmethod_path}/services/adapter/keyboard/include", + "${inputmethod_path}/services/adapter/system_language_observer/include", "${inputmethod_path}/services/identity_checker/include", "${inputmethod_path}/services/dfx/include", ] @@ -37,6 +38,7 @@ ohos_shared_library("inputmethod_service") { "${inputmethod_path}/frameworks/native/inputmethod_controller/src/input_death_recipient.cpp", "${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/system_language_observer/src/system_language_observer.cpp", "${inputmethod_path}/services/identity_checker/src/identity_checker_impl.cpp", "src/global.cpp", "src/im_common_event_manager.cpp", @@ -75,6 +77,7 @@ ohos_shared_library("inputmethod_service") { "common_event_service:cesfwk_innerkits", "eventhandler:libeventhandler", "hilog:libhilog", + "init:libbeget_proxy", "init:libbegetutil", "input:libmmi-client", "ipc:ipc_single", diff --git a/services/adapter/system_language_observer/include/system_language_observer.h b/services/adapter/system_language_observer/include/system_language_observer.h new file mode 100644 index 000000000..623204473 --- /dev/null +++ b/services/adapter/system_language_observer/include/system_language_observer.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 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. + */ + +#ifndef IMF_SYSTEM_LANGUAGE_OBSERVER_H +#define IMF_SYSTEM_LANGUAGE_OBSERVER_H + +#include +#include + +namespace OHOS { +namespace MiscServices { +class SystemLanguageObserver { +public: + using ChangeHandler = std::function; + static SystemLanguageObserver &GetInstance(); + void Watch(ChangeHandler handler); + +private: + static constexpr const char *SYSTEM_LANGUAGE_KEY = "persist.global.language"; + SystemLanguageObserver() = default; + static void OnChange(const char *key, const char *value, void *context); + static ChangeHandler handler_; +}; +} // namespace MiscServices +} // namespace OHOS + +#endif // IMF_SYSTEM_LANGUAGE_OBSERVER_H diff --git a/services/adapter/system_language_observer/src/system_language_observer.cpp b/services/adapter/system_language_observer/src/system_language_observer.cpp new file mode 100644 index 000000000..5ad1e206f --- /dev/null +++ b/services/adapter/system_language_observer/src/system_language_observer.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023 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 "system_language_observer.h" + +#include "global.h" +#include "parameter.h" +namespace OHOS { +namespace MiscServices { +constexpr int32_t HANDLE_OK = 0; +SystemLanguageObserver::ChangeHandler SystemLanguageObserver::handler_; +SystemLanguageObserver &SystemLanguageObserver::GetInstance() +{ + static SystemLanguageObserver observer; + return observer; +} + +void SystemLanguageObserver::Watch(ChangeHandler handler) +{ + IMSA_HILOGI("run in"); + handler_ = std::move(handler); + auto errNo = WatchParameter(SYSTEM_LANGUAGE_KEY, OnChange, nullptr); + if (errNo != HANDLE_OK) { + IMSA_HILOGE("watch failed: %{public}d", errNo); + } +} + +void SystemLanguageObserver::OnChange(const char *key, const char *value, void *context) +{ + if (strncmp(key, SYSTEM_LANGUAGE_KEY, strlen(SYSTEM_LANGUAGE_KEY)) != 0) { + IMSA_HILOGE("key: %{public}s is error", key); + return; + } + IMSA_HILOGD("value: %{public}s", value); + if (handler_ != nullptr) { + handler_(); + } +} +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/services/include/ime_info_inquirer.h b/services/include/ime_info_inquirer.h index 73aeb0376..940ce593d 100644 --- a/services/include/ime_info_inquirer.h +++ b/services/include/ime_info_inquirer.h @@ -32,6 +32,7 @@ namespace OHOS { namespace MiscServices { struct ImeInfo { + std::string moduleName; Property prop; SubProperty subProp; std::vector subProps; @@ -55,10 +56,12 @@ public: std::shared_ptr GetCurrentInputMethodSubtype(const int32_t userId); std::string GetStartedIme(const int32_t userId); std::shared_ptr GetDefaultImeInfo(const int32_t userId); - int32_t GetImeInfo( - const int32_t userId, const std::string &bundleName, const std::string &subName, ImeInfo &info); - void SetCurrentImeInfo(const ImeInfo &info); + std::shared_ptr GetImeInfo( + const int32_t userId, const std::string &bundleName, const std::string &subName); + void SetCurrentImeInfo(std::shared_ptr info); void SetCurrentImeInfo(const int32_t userId); + std::shared_ptr GetCurrentImeInfo(); + void UpdateCurrentImeInfo(const int32_t userId); void ResetCurrentImeInfo(); int32_t ListInputMethod(const int32_t userId, const InputMethodStatus status, std::vector &props); int32_t ListInputMethodSubtype( @@ -73,9 +76,10 @@ private: std::string GetDefaultIme(); std::string GetStringById( const std::string &bundleName, const std::string &moduleName, const int32_t labelId, const int32_t userId); - int32_t GetImeInfoFromNative(const int32_t userId, const std::string &subName, ImeInfo &info); - int32_t GetImeInfoFromBundleMgr( - const int32_t userId, const std::string &bundleName, const std::string &subName, ImeInfo &info); + std::shared_ptr GetImeInfoFromCache( + const int32_t userId, const std::string &bundleName, const std::string &subName); + std::shared_ptr GetImeInfoFromBundleMgr( + const int32_t userId, const std::string &bundleName, const std::string &subName); int32_t GetExtInfosByBundleName(const int32_t userId, const std::string &bundleName, std::vector &extInfos); bool IsNewExtInfos(const std::vector &extInfos); @@ -94,10 +98,8 @@ private: void ParseLanguage(const std::string &locale, std::string &language); bool QueryImeExtInfos(const int32_t userId, std::vector &infos); - std::recursive_mutex currentImeInfoLock_; - std::shared_ptr currentImeInfo_{ nullptr }; - std::mutex defaultImeInfoLock_; - std::shared_ptr defaultImeInfo_{ nullptr }; + std::mutex currentImeInfoLock_; + std::shared_ptr currentImeInfo_{ nullptr }; // current imeInfo of current user }; } // namespace MiscServices } // namespace OHOS diff --git a/services/include/input_method_system_ability.h b/services/include/input_method_system_ability.h index c646667ad..5637f1819 100644 --- a/services/include/input_method_system_ability.h +++ b/services/include/input_method_system_ability.h @@ -105,9 +105,9 @@ private: void StartUserIdListener(); bool IsNeedSwitch(const std::string &bundleName, const std::string &subName); int32_t OnSwitchInputMethod(const SwitchInfo &switchInfo, bool isCheckPermission); - int32_t Switch(const std::string &bundleName, const ImeInfo &info); - int32_t SwitchExtension(const ImeInfo &info); - int32_t SwitchSubType(const ImeInfo &info); + int32_t Switch(const std::string &bundleName, const std::shared_ptr &info); + int32_t SwitchExtension(const std::shared_ptr &info); + int32_t SwitchSubType(const std::shared_ptr &info); ServiceRunningState state_; void InitServiceHandler(); static std::shared_ptr serviceHandler_; @@ -118,8 +118,10 @@ private: static constexpr int32_t MAX_WAIT_TIME = 5000; BlockQueue switchQueue_{ MAX_WAIT_TIME }; bool stop_ = false; + void InitMonitors(); int32_t InitKeyEventMonitor(); bool InitFocusChangeMonitor(); + void InitSystemLanguageMonitor(); int32_t SwitchByCombinationKey(uint32_t state); int32_t SwitchMode(); int32_t SwitchLanguage(); diff --git a/services/src/ime_info_inquirer.cpp b/services/src/ime_info_inquirer.cpp index 40a3811a0..9191c3e17 100644 --- a/services/src/ime_info_inquirer.cpp +++ b/services/src/ime_info_inquirer.cpp @@ -79,48 +79,43 @@ int32_t ImeInfoInquirer::GetExtInfosByBundleName( return ErrorCode::NO_ERROR; } -int32_t ImeInfoInquirer::GetImeInfo( - const int32_t userId, const std::string &bundleName, const std::string &subName, ImeInfo &info) +std::shared_ptr ImeInfoInquirer::GetImeInfo( + const int32_t userId, const std::string &bundleName, const std::string &subName) { - // if current ime, get info from currentImeInfos_ - std::lock_guard lock(currentImeInfoLock_); - if (currentImeInfo_ != nullptr && bundleName == currentImeInfo_->prop.name) { - return GetImeInfoFromNative(userId, subName, info); - } - return GetImeInfoFromBundleMgr(userId, bundleName, subName, info); + auto info = GetImeInfoFromCache(userId, bundleName, subName); + return info == nullptr ? GetImeInfoFromBundleMgr(userId, bundleName, subName) : info; } -int32_t ImeInfoInquirer::GetImeInfoFromNative(const int32_t userId, const std::string &subName, ImeInfo &info) +std::shared_ptr ImeInfoInquirer::GetImeInfoFromCache( + const int32_t userId, const std::string &bundleName, const std::string &subName) { - IMSA_HILOGD("userId: %{public}d, subName: %{public}s", userId, subName.c_str()); - std::lock_guard lock(currentImeInfoLock_); - if (currentImeInfo_ == nullptr) { - return ErrorCode::ERROR_BAD_PARAMETERS; + IMSA_HILOGD("userId: %{public}d, bundleName: %{public}s, subName: %{public}s", userId, bundleName.c_str(), + subName.c_str()); + auto info = GetCurrentImeInfo(); + if (info == nullptr || bundleName != info->prop.name) { + return nullptr; } - info.subProps = currentImeInfo_->subProps; - info.prop = currentImeInfo_->prop; - info.isNewIme = currentImeInfo_->isNewIme; - if (subName == currentImeInfo_->subProp.id) { - info.subProp = currentImeInfo_->subProp; - return ErrorCode::NO_ERROR; + if (subName == info->subProp.id) { + return std::make_shared(*info); } - auto it = std::find_if(currentImeInfo_->subProps.begin(), currentImeInfo_->subProps.end(), + auto newInfo = std::make_shared(*info); + auto it = std::find_if(newInfo->subProps.begin(), newInfo->subProps.end(), [&subName](const SubProperty &subProp) { return subProp.id == subName; }); - if (it == currentImeInfo_->subProps.end()) { + if (it == newInfo->subProps.end()) { IMSA_HILOGE("Find subName: %{public}s failed", subName.c_str()); - return ErrorCode::ERROR_BAD_PARAMETERS; + return nullptr; } - info.subProp = *it; + newInfo->subProp = *it; // old ime, make the id of prop same with the id of subProp. - if (!info.isNewIme) { - info.prop.id = info.subProp.id; + if (!newInfo->isNewIme) { + newInfo->prop.id = newInfo->subProp.id; } - return ErrorCode::NO_ERROR; + return newInfo; } -int32_t ImeInfoInquirer::GetImeInfoFromBundleMgr( - const int32_t userId, const std::string &bundleName, const std::string &subName, ImeInfo &info) +std::shared_ptr ImeInfoInquirer::GetImeInfoFromBundleMgr( + const int32_t userId, const std::string &bundleName, const std::string &subName) { IMSA_HILOGD("userId: %{public}d, bundleName: %{public}s, subName: %{public}s", userId, bundleName.c_str(), subName.c_str()); @@ -128,67 +123,85 @@ int32_t ImeInfoInquirer::GetImeInfoFromBundleMgr( auto ret = ImeInfoInquirer::GetInstance().GetExtInfosByBundleName(userId, bundleName, extInfos); if (ret != ErrorCode::NO_ERROR || extInfos.empty()) { IMSA_HILOGE("userId: %{public}d getExtInfosByBundleName %{public}s failed", userId, bundleName.c_str()); - return ErrorCode::ERROR_BAD_PARAMETERS; + return nullptr; } - info.prop.name = extInfos[0].bundleName; - info.prop.id = extInfos[0].name; - info.prop.label = + auto info = std::make_shared(); + info->moduleName = extInfos[0].moduleName; + info->prop.name = extInfos[0].bundleName; + info->prop.id = extInfos[0].name; + info->prop.label = GetStringById(extInfos[0].bundleName, extInfos[0].moduleName, extInfos[0].applicationInfo.labelId, userId); - info.prop.labelId = extInfos[0].applicationInfo.labelId; - info.prop.iconId = extInfos[0].applicationInfo.iconId; + info->prop.labelId = extInfos[0].applicationInfo.labelId; + info->prop.iconId = extInfos[0].applicationInfo.iconId; std::vector subProps; - info.isNewIme = IsNewExtInfos(extInfos); - ret = info.isNewIme ? ListInputMethodSubtype(userId, extInfos[0], subProps) - : ListInputMethodSubtype(userId, extInfos, subProps); + info->isNewIme = IsNewExtInfos(extInfos); + ret = info->isNewIme ? ListInputMethodSubtype(userId, extInfos[0], subProps) + : ListInputMethodSubtype(userId, extInfos, subProps); if (ret != ErrorCode::NO_ERROR || subProps.empty()) { IMSA_HILOGE("userId: %{public}d listInputMethodSubtype failed", userId); - return ErrorCode::ERROR_BAD_PARAMETERS; + return nullptr; } - info.subProps = subProps; + info->subProps = subProps; if (subName.empty()) { - info.subProp = subProps[0]; + info->subProp = subProps[0]; } else { auto it = std::find_if(subProps.begin(), subProps.end(), [&subName](const SubProperty &subProp) { return subProp.id == subName; }); if (it == subProps.end()) { IMSA_HILOGE("Find subName: %{public}s failed", subName.c_str()); - return ErrorCode::ERROR_BAD_PARAMETERS; + return nullptr; } - info.subProp = *it; + info->subProp = *it; } // old ime, make the id of prop same with the id of subProp. - if (!info.isNewIme) { - info.prop.id = info.subProp.id; + if (!info->isNewIme) { + info->prop.id = info->subProp.id; } - return ErrorCode::NO_ERROR; + return info; } -void ImeInfoInquirer::SetCurrentImeInfo(const ImeInfo &info) +void ImeInfoInquirer::SetCurrentImeInfo(std::shared_ptr info) { - std::lock_guard lock(currentImeInfoLock_); - currentImeInfo_ = std::make_shared(info); + std::lock_guard lock(currentImeInfoLock_); + currentImeInfo_ = std::move(info); } void ImeInfoInquirer::SetCurrentImeInfo(const int32_t userId) { IMSA_HILOGD("userId: %{public}d", userId); auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId); - ImeInfo info; - auto ret = GetImeInfoFromBundleMgr(userId, currentImeCfg->bundleName, currentImeCfg->subName, info); - if (ret != ErrorCode::NO_ERROR) { + auto info = GetImeInfoFromBundleMgr(userId, currentImeCfg->bundleName, currentImeCfg->subName); + if (info == nullptr) { IMSA_HILOGE("userId: %{public}d, bundleName: %{public}s, subName: %{public}s getImeInfoFromBundleMgr failed", userId, currentImeCfg->bundleName.c_str(), currentImeCfg->subName.c_str()); return; } - std::lock_guard lock(currentImeInfoLock_); - currentImeInfo_ = std::make_shared(info); + SetCurrentImeInfo(info); +} + +std::shared_ptr ImeInfoInquirer::GetCurrentImeInfo() +{ + std::lock_guard lock(currentImeInfoLock_); + return currentImeInfo_; } -void ImeInfoInquirer::ResetCurrentImeInfo() +void ImeInfoInquirer::UpdateCurrentImeInfo(const int32_t userId) { - std::lock_guard lock(currentImeInfoLock_); - currentImeInfo_ = nullptr; + IMSA_HILOGD("run in"); + std::lock_guard lock(currentImeInfoLock_); + if (currentImeInfo_ == nullptr) { + IMSA_HILOGD("currentImeInfo is nullptr"); + return; + } + for (auto &subProp : currentImeInfo_->subProps) { + subProp.label = GetStringById(subProp.name, currentImeInfo_->moduleName, subProp.labelId, userId); + if (currentImeInfo_->subProp.id == subProp.id) { + currentImeInfo_->subProp.label = subProp.label; + } + } + currentImeInfo_->prop.label = + GetStringById(currentImeInfo_->prop.name, currentImeInfo_->moduleName, currentImeInfo_->prop.labelId, userId); } std::string ImeInfoInquirer::GetInputMethodParam(const int32_t userId) @@ -316,13 +329,6 @@ int32_t ImeInfoInquirer::ListInputMethodSubtype( const int32_t userId, const std::string &bundleName, std::vector &subProps) { IMSA_HILOGD("userId: %{public}d, bundleName: %{public}s", userId, bundleName.c_str()); - { - std::lock_guard lock(currentImeInfoLock_); - if (currentImeInfo_ != nullptr && currentImeInfo_->prop.name == bundleName) { - subProps = currentImeInfo_->subProps; - return ErrorCode::NO_ERROR; - } - } std::vector extInfos; auto ret = GetExtInfosByBundleName(userId, bundleName, extInfos); if (ret != ErrorCode::NO_ERROR) { @@ -335,14 +341,6 @@ int32_t ImeInfoInquirer::ListInputMethodSubtype( int32_t ImeInfoInquirer::ListCurrentInputMethodSubtype(const int32_t userId, std::vector &subProps) { - // If the local currentImeInfo_ exists, the value is taken directly form currentImeInfo_ - { - std::lock_guard lock(currentImeInfoLock_); - if (currentImeInfo_ != nullptr) { - subProps = currentImeInfo_->subProps; - return ErrorCode::NO_ERROR; - } - } auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId); IMSA_HILOGD("currentIme: %{public}s", currentImeCfg->imeId.c_str()); return ListInputMethodSubtype(userId, currentImeCfg->bundleName, subProps); @@ -470,13 +468,6 @@ SubProperty ImeInfoInquirer::GetExtends(const std::vector &metaData) std::shared_ptr ImeInfoInquirer::GetCurrentInputMethod(const int32_t userId) { - // If the local currentImeInfo_ exists, the value is taken directly form currentImeInfo_ - { - std::lock_guard lock(currentImeInfoLock_); - if (currentImeInfo_ != nullptr) { - return std::make_shared(currentImeInfo_->prop); - } - } auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId); IMSA_HILOGD("currentIme: %{public}s", currentImeCfg->imeId.c_str()); std::vector extInfos; @@ -497,13 +488,6 @@ std::shared_ptr ImeInfoInquirer::GetCurrentInputMethod(const int32_t u std::shared_ptr ImeInfoInquirer::GetCurrentInputMethodSubtype(const int32_t userId) { - // If the local currentImeInfo_ exists, the value is taken directly form currentImeInfo_ - { - std::lock_guard lock(currentImeInfoLock_); - if (currentImeInfo_ != nullptr) { - return std::make_shared(currentImeInfo_->subProp); - } - } auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId); IMSA_HILOGD("currentIme: %{public}s", currentImeCfg->imeId.c_str()); std::vector subProps = {}; @@ -553,13 +537,13 @@ std::string ImeInfoInquirer::GetStartedIme(const int32_t userId) subName = ""; } else { subName = info->subProp.id; - SetCurrentImeInfo(*info); + SetCurrentImeInfo(info); } currentImeCfg->imeId.empty() ? ImeCfgManager::GetInstance().AddImeCfg({ userId, newUserIme, subName }) : ImeCfgManager::GetInstance().ModifyImeCfg({ userId, newUserIme, subName }); return newUserIme; } - // service start, user switch, set the currentImeInfo_. + // service start, user switch, set the currentImeInfo. SetCurrentImeInfo(userId); return currentImeCfg->imeId; } @@ -574,31 +558,21 @@ std::shared_ptr ImeInfoInquirer::GetDefaultImeInfo(const int32_t userId } auto bundleName = ime.substr(0, pos); auto extName = ime.substr(pos + 1); - { - std::lock_guard lock(defaultImeInfoLock_); - if (defaultImeInfo_ != nullptr && defaultImeInfo_->prop.name == bundleName - && defaultImeInfo_->prop.id == extName) { - return defaultImeInfo_; - } - } - ImeInfo info; - auto ret = GetImeInfoFromBundleMgr(userId, bundleName, "", info); - if (ret != ErrorCode::NO_ERROR) { + auto info = GetImeInfoFromBundleMgr(userId, bundleName, ""); + if (info == nullptr) { IMSA_HILOGE( "userId: %{public}d, bundleName: %{public}s getImeInfoFromBundleMgr failed", userId, bundleName.c_str()); return nullptr; } - if (!info.isNewIme) { - info.prop.id = extName; - auto it = std::find_if(info.subProps.begin(), info.subProps.end(), + if (!info->isNewIme) { + info->prop.id = extName; + auto it = std::find_if(info->subProps.begin(), info->subProps.end(), [&extName](const SubProperty &subProp) { return subProp.id == extName; }); - if (it != info.subProps.end()) { - info.subProp = *it; + if (it != info->subProps.end()) { + info->subProp = *it; } } - std::lock_guard lock(defaultImeInfoLock_); - defaultImeInfo_ = std::make_shared(info); - return defaultImeInfo_; + return info; } std::string ImeInfoInquirer::GetDefaultIme() diff --git a/services/src/input_method_system_ability.cpp b/services/src/input_method_system_ability.cpp index fe3c45bd1..463afb952 100644 --- a/services/src/input_method_system_ability.cpp +++ b/services/src/input_method_system_ability.cpp @@ -35,6 +35,7 @@ #include "os_account_manager.h" #include "sys/prctl.h" #include "system_ability_definition.h" +#include "system_language_observer.h" namespace OHOS { namespace MiscServices { @@ -144,11 +145,7 @@ int32_t InputMethodSystemAbility::Init() InputMethodSysEvent::GetInstance().SetUserId(userId_); userSession_->UpdateCurrentUserId(userId_); } - StartUserIdListener(); - int32_t ret = InitKeyEventMonitor(); - IMSA_HILOGI("init KeyEvent monitor %{public}s", ret == ErrorCode::NO_ERROR ? "success" : "failed"); - ret = InitFocusChangeMonitor(); - IMSA_HILOGI("init focus change monitor %{public}s", ret ? "success" : "failed"); + InitMonitors(); return ErrorCode::NO_ERROR; } @@ -406,13 +403,12 @@ int32_t InputMethodSystemAbility::OnSwitchInputMethod(const SwitchInfo &switchIn switchQueue_.Pop(); return ErrorCode::NO_ERROR; } - ImeInfo info; - int32_t ret = ImeInfoInquirer::GetInstance().GetImeInfo(userId_, switchInfo.bundleName, switchInfo.subName, info); - if (ret != ErrorCode::NO_ERROR) { + auto info = ImeInfoInquirer::GetInstance().GetImeInfo(userId_, switchInfo.bundleName, switchInfo.subName); + if (info == nullptr) { switchQueue_.Pop(); - return ret; + return ErrorCode::ERROR_BAD_PARAMETERS; } - ret = info.isNewIme ? Switch(switchInfo.bundleName, info) : SwitchExtension(info); + auto ret = info->isNewIme ? Switch(switchInfo.bundleName, info) : SwitchExtension(info); switchQueue_.Pop(); if (ret != ErrorCode::NO_ERROR) { InputMethodSysEvent::GetInstance().InputmethodFaultReporter( @@ -434,37 +430,37 @@ bool InputMethodSystemAbility::IsNeedSwitch(const std::string &bundleName, const return true; } -int32_t InputMethodSystemAbility::Switch(const std::string &bundleName, const ImeInfo &info) +int32_t InputMethodSystemAbility::Switch(const std::string &bundleName, const std::shared_ptr &info) { auto currentImeBundleName = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->bundleName; return bundleName != currentImeBundleName ? SwitchExtension(info) : SwitchSubType(info); } // Switch the current InputMethodExtension to the new InputMethodExtension -int32_t InputMethodSystemAbility::SwitchExtension(const ImeInfo &info) +int32_t InputMethodSystemAbility::SwitchExtension(const std::shared_ptr &info) { auto currentIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->imeId; StopInputService(currentIme); - std::string targetIme = info.prop.name + "/" + info.prop.id; - ImeCfgManager::GetInstance().ModifyImeCfg({ userId_, targetIme, info.subProp.id }); + std::string targetIme = info->prop.name + "/" + info->prop.id; + ImeCfgManager::GetInstance().ModifyImeCfg({ userId_, targetIme, info->subProp.id }); ImeInfoInquirer::GetInstance().SetCurrentImeInfo(info); if (!StartInputService(targetIme)) { IMSA_HILOGE("start input method failed"); return ErrorCode::ERROR_IME_START_FAILED; } - userSession_->OnSwitchIme(info.prop, info.subProp, false); + userSession_->OnSwitchIme(info->prop, info->subProp, false); return ErrorCode::NO_ERROR; } // Inform current InputMethodExtension to switch subtype -int32_t InputMethodSystemAbility::SwitchSubType(const ImeInfo &info) +int32_t InputMethodSystemAbility::SwitchSubType(const std::shared_ptr &info) { - auto ret = userSession_->OnSwitchIme(info.prop, info.subProp, true); + auto ret = userSession_->OnSwitchIme(info->prop, info->subProp, true); if (ret != ErrorCode::NO_ERROR) { return ret; } auto currentIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->imeId; - ImeCfgManager::GetInstance().ModifyImeCfg({ userId_, currentIme, info.subProp.id }); + ImeCfgManager::GetInstance().ModifyImeCfg({ userId_, currentIme, info->subProp.id }); ImeInfoInquirer::GetInstance().SetCurrentImeInfo(info); return ErrorCode::NO_ERROR; } @@ -581,7 +577,7 @@ int32_t InputMethodSystemAbility::OnUserStarted(const Message *msg) auto currentIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(oldUserId)->imeId; StopInputService(currentIme); // user switch, reset currentImeInfo_ = nullptr - ImeInfoInquirer::GetInstance().ResetCurrentImeInfo(); + ImeInfoInquirer::GetInstance().SetCurrentImeInfo(nullptr); auto newIme = ImeInfoInquirer::GetInstance().GetStartedIme(userId_); InputMethodSysEvent::GetInstance().SetUserId(userId_); if (!StartInputService(newIme)) { @@ -639,7 +635,7 @@ int32_t InputMethodSystemAbility::OnPackageRemoved(const Message *msg) if (info == nullptr) { return ErrorCode::ERROR_PERSIST_CONFIG; } - int32_t ret = SwitchExtension(*info); + int32_t ret = SwitchExtension(info); IMSA_HILOGI("InputMethodSystemAbility::OnPackageRemoved ret = %{public}d", ret); } return ErrorCode::NO_ERROR; @@ -681,20 +677,19 @@ int32_t InputMethodSystemAbility::SwitchByCombinationKey(uint32_t state) int32_t InputMethodSystemAbility::SwitchMode() { - ImeInfo info; auto bundleName = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->bundleName; auto subName = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->subName; - auto ret = ImeInfoInquirer::GetInstance().GetImeInfo(userId_, bundleName, subName, info); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("current ime is abnormal, ret: %{public}d", ret); - return ret; + auto info = ImeInfoInquirer::GetInstance().GetImeInfo(userId_, bundleName, subName); + if (info == nullptr) { + IMSA_HILOGE("current ime is abnormal"); + return ErrorCode::ERROR_BAD_PARAMETERS; } - if (info.isNewIme) { + if (info->isNewIme) { IMSA_HILOGD("the switching operation is handed over to ime"); return ErrorCode::NO_ERROR; } - auto condition = info.subProp.mode == "upper" ? Condition::LOWER : Condition::UPPER; - auto target = ImeInfoInquirer::GetInstance().GetImeSubProp(info.subProps, condition); + auto condition = info->subProp.mode == "upper" ? Condition::LOWER : Condition::UPPER; + auto target = ImeInfoInquirer::GetInstance().GetImeSubProp(info->subProps, condition); if (target == nullptr) { IMSA_HILOGE("target is empty"); return ErrorCode::ERROR_BAD_PARAMETERS; @@ -706,23 +701,22 @@ int32_t InputMethodSystemAbility::SwitchMode() int32_t InputMethodSystemAbility::SwitchLanguage() { - ImeInfo info; auto bundleName = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->bundleName; auto subName = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_)->subName; - auto ret = ImeInfoInquirer::GetInstance().GetImeInfo(userId_, bundleName, subName, info); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("current ime is abnormal, ret: %{public}d", ret); - return ret; + auto info = ImeInfoInquirer::GetInstance().GetImeInfo(userId_, bundleName, subName); + if (info == nullptr) { + IMSA_HILOGE("current ime is abnormal"); + return ErrorCode::ERROR_BAD_PARAMETERS; } - if (info.isNewIme) { + if (info->isNewIme) { IMSA_HILOGD("the switching operation is handed over to ime"); return ErrorCode::NO_ERROR; } - if (info.subProp.language != "chinese" && info.subProp.language != "english") { + if (info->subProp.language != "chinese" && info->subProp.language != "english") { return ErrorCode::NO_ERROR; } - auto condition = info.subProp.language == "chinese" ? Condition::ENGLISH : Condition::CHINESE; - auto target = ImeInfoInquirer::GetInstance().GetImeSubProp(info.subProps, condition); + auto condition = info->subProp.language == "chinese" ? Condition::ENGLISH : Condition::CHINESE; + auto target = ImeInfoInquirer::GetInstance().GetImeSubProp(info->subProps, condition); if (target == nullptr) { IMSA_HILOGE("target is empty"); return ErrorCode::ERROR_BAD_PARAMETERS; @@ -751,6 +745,16 @@ int32_t InputMethodSystemAbility::SwitchType() return ErrorCode::NO_ERROR; } +void InputMethodSystemAbility::InitMonitors() +{ + StartUserIdListener(); + int32_t ret = InitKeyEventMonitor(); + IMSA_HILOGI("init KeyEvent monitor, ret: %{public}d", ret); + ret = InitFocusChangeMonitor(); + IMSA_HILOGI("init focus change monitor, ret: %{public}d", ret); + InitSystemLanguageMonitor(); +} + int32_t InputMethodSystemAbility::InitKeyEventMonitor() { IMSA_HILOGI("InputMethodSystemAbility::InitKeyEventMonitor"); @@ -767,5 +771,11 @@ bool InputMethodSystemAbility::InitFocusChangeMonitor() }, [this]() { StartInputService(ImeInfoInquirer::GetInstance().GetStartedIme(userId_)); }); } + +void InputMethodSystemAbility::InitSystemLanguageMonitor() +{ + SystemLanguageObserver::GetInstance().Watch( + [this]() { ImeInfoInquirer::GetInstance().UpdateCurrentImeInfo(userId_); }); +} } // namespace MiscServices } // namespace OHOS 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 feabba0e4..d754ceb3d 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 @@ -72,14 +72,14 @@ void InputMethodPrivateMemberTest::SetUp(void) { IMSA_HILOGI("InputMethodPrivateMemberTest::SetUp"); ImeCfgManager::GetInstance().imeConfigs_.clear(); - ImeInfoInquirer::GetInstance().ResetCurrentImeInfo(); + ImeInfoInquirer::GetInstance().SetCurrentImeInfo(nullptr); } void InputMethodPrivateMemberTest::TearDown(void) { IMSA_HILOGI("InputMethodPrivateMemberTest::TearDown"); ImeCfgManager::GetInstance().imeConfigs_.clear(); - ImeInfoInquirer::GetInstance().ResetCurrentImeInfo(); + ImeInfoInquirer::GetInstance().SetCurrentImeInfo(nullptr); } sptr InputMethodPrivateMemberTest::service_; @@ -436,10 +436,10 @@ HWTEST_F(InputMethodPrivateMemberTest, SA_SwitchByCombinationKey_003, TestSize.L IMSA_HILOGI("InputMethodPrivateMemberTest SA_SwitchByCombinationKey_003 TEST START"); ImeCfgManager cfgManager; service_->userId_ = 50; - ImeInfo info; - info.isNewIme = true; - info.prop = { .name = "testBundleName" }; - info.subProp = { .id = "testSubName" }; + auto info = std::make_shared(); + info->isNewIme = true; + info->prop = { .name = "testBundleName" }; + info->subProp = { .id = "testSubName" }; ImeInfoInquirer::GetInstance().SetCurrentImeInfo(info); ImeCfgManager::GetInstance().imeConfigs_.push_back({ 50, "testBundleName/testExtName", "testSubName" }); auto ret = service_->SwitchByCombinationKey(KeyboardEvent::SHIFT_RIGHT_MASK); @@ -459,9 +459,9 @@ HWTEST_F(InputMethodPrivateMemberTest, SA_SwitchByCombinationKey_004, TestSize.L { IMSA_HILOGI("InputMethodPrivateMemberTest SA_SwitchByCombinationKey_004 TEST START"); service_->userId_ = 50; - ImeInfo info; - info.prop = { .name = "testBundleName", .id = "testExtName" }; - info.subProp = { .name = "testBundleName", .id = "testSubName", .language = "French" }; + auto info = std::make_shared(); + info->prop = { .name = "testBundleName", .id = "testExtName" }; + info->subProp = { .name = "testBundleName", .id = "testSubName", .language = "French" }; ImeInfoInquirer::GetInstance().SetCurrentImeInfo(info); ImeCfgManager::GetInstance().imeConfigs_.push_back({ 50, "testBundleName/testExtName", "testSubName" }); auto ret = service_->SwitchByCombinationKey(KeyboardEvent::SHIFT_RIGHT_MASK); @@ -479,15 +479,15 @@ HWTEST_F(InputMethodPrivateMemberTest, SA_SwitchByCombinationKey_005, TestSize.L { IMSA_HILOGI("InputMethodPrivateMemberTest SA_SwitchByCombinationKey_005 TEST START"); service_->userId_ = 50; - ImeInfo info; - info.prop = { .name = "testBundleName", .id = "testExtName" }; - info.subProp = { + auto info = std::make_shared(); + info->prop = { .name = "testBundleName", .id = "testExtName" }; + info->subProp = { .name = "testBundleName", .id = "testSubName", .mode = "upper", .language = "english", }; - info.subProps = { { .name = "testBundleName", .id = "testSubName", .mode = "upper", .language = "english" } }; + info->subProps = { { .name = "testBundleName", .id = "testSubName", .mode = "upper", .language = "english" } }; ImeInfoInquirer::GetInstance().SetCurrentImeInfo(info); ImeCfgManager::GetInstance().imeConfigs_.push_back({ 50, "testBundleName/testExtName", "testSubName" }); auto ret = service_->SwitchByCombinationKey(KeyboardEvent::SHIFT_RIGHT_MASK); @@ -507,10 +507,10 @@ HWTEST_F(InputMethodPrivateMemberTest, SA_SwitchByCombinationKey_006, TestSize.L { IMSA_HILOGI("InputMethodPrivateMemberTest SA_SwitchByCombinationKey_006 TEST START"); service_->userId_ = 50; - ImeInfo info; - info.prop = { .name = "testBundleName", .id = "testExtName" }; - info.subProp = { .name = "testBundleName", .id = "testSubName", .mode = "upper", .language = "english" }; - info.subProps = { { .name = "testBundleName", .id = "testSubName", .mode = "upper", .language = "english" }, + auto info = std::make_shared(); + info->prop = { .name = "testBundleName", .id = "testExtName" }; + info->subProp = { .name = "testBundleName", .id = "testSubName", .mode = "upper", .language = "english" }; + info->subProps = { { .name = "testBundleName", .id = "testSubName", .mode = "upper", .language = "english" }, { .name = "testBundleName", .id = "testSubName1", .mode = "lower", .language = "chinese" } }; ImeInfoInquirer::GetInstance().SetCurrentImeInfo(info); ImeCfgManager::GetInstance().imeConfigs_.push_back({ 50, "testBundleName/testExtName", "testSubName" }); @@ -521,8 +521,8 @@ HWTEST_F(InputMethodPrivateMemberTest, SA_SwitchByCombinationKey_006, TestSize.L ret = service_->SwitchByCombinationKey(KeyboardEvent::CAPS_MASK); EXPECT_EQ(ret, ErrorCode::ERROR_IME_START_FAILED); - info.subProp = { .name = "testBundleName", .id = "testSubName1", .mode = "upper", .language = "chinese" }; - info.subProps = { { .name = "testBundleName", .id = "testSubName", .mode = "lower", .language = "english" }, + info->subProp = { .name = "testBundleName", .id = "testSubName1", .mode = "upper", .language = "chinese" }; + info->subProps = { { .name = "testBundleName", .id = "testSubName", .mode = "lower", .language = "english" }, { .name = "testBundleName", .id = "testSubName1", .mode = "lower", .language = "chinese" } }; ImeInfoInquirer::GetInstance().SetCurrentImeInfo(info); ImeCfgManager::GetInstance().imeConfigs_.push_back({ 50, "testBundleName/testExtName", "testSubName1" }); -- Gitee