From 8bdbebb1a811423dd9b9e7ff5e5dc165cf1e08ff Mon Sep 17 00:00:00 2001 From: cy7717 Date: Sat, 2 Aug 2025 19:55:48 +0800 Subject: [PATCH 1/3] mod for Restricted Main DisplayId Signed-off-by: cy7717 --- services/BUILD.gn | 3 ++ .../display_adapter/include/display_adapter.h | 29 ++++++++++++ .../display_adapter/src/display_adapter.cpp | 46 +++++++++++++++++++ services/include/ime_info_inquirer.h | 1 + services/include/peruser_session.h | 3 +- services/include/sys_cfg_parser.h | 2 + services/src/ime_info_inquirer.cpp | 22 ++++----- services/src/input_method_system_ability.cpp | 2 +- services/src/peruser_session.cpp | 13 +++++- 9 files changed, 105 insertions(+), 16 deletions(-) create mode 100644 services/adapter/display_adapter/include/display_adapter.h create mode 100644 services/adapter/display_adapter/src/display_adapter.cpp diff --git a/services/BUILD.gn b/services/BUILD.gn index 44a174e44..b4d636b2a 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}/interfaces/inner_api/inputmethod_ability/include", "${inputmethod_path}/interfaces/inner_api/inputmethod_controller/include", + "${inputmethod_path}/services/adapter/display_adapter/include", "${inputmethod_path}/services/adapter/focus_monitor/include", "${inputmethod_path}/services/adapter/ime_connection_manager/include", "${inputmethod_path}/services/adapter/keyboard/include", @@ -58,6 +59,7 @@ ohos_shared_library("inputmethod_service") { "${inputmethod_path}/frameworks/native/inputmethod_controller/src/input_client_info.cpp", "${inputmethod_path}/frameworks/native/inputmethod_controller/src/input_method_tools.cpp", "${inputmethod_path}/frameworks/native/inputmethod_controller/src/input_method_utils.cpp", + "${inputmethod_path}/services/adapter/display_adapter/src/display_adapter.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/ime_connection_manager/src/ime_connection.cpp", @@ -170,6 +172,7 @@ ohos_static_library("inputmethod_service_static") { "-Oz", ] sources = [ + "adapter/display_adapter/src/display_adapter.cpp", "adapter/focus_monitor/src/focus_change_listener.cpp", "adapter/focus_monitor/src/focus_monitor_manager.cpp", "adapter/ime_connection_manager/src/ime_connection.cpp", diff --git a/services/adapter/display_adapter/include/display_adapter.h b/services/adapter/display_adapter/include/display_adapter.h new file mode 100644 index 000000000..29eccb54b --- /dev/null +++ b/services/adapter/display_adapter/include/display_adapter.h @@ -0,0 +1,29 @@ +/* + * 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. + */ + +#ifndef INPUTMETHOD_IMF_DISPLAY_ADAPTER_H +#define INPUTMETHOD_IMF_DISPLAY_ADAPTER_H +#include +#include +namespace OHOS { +namespace MiscServices { +class DisplayAdapter final { +public: + static std::string GetDisplayName(uint64_t displayId); + static uint64_t GetDefaultDisplayId(); +}; +} // namespace MiscServices +} // namespace OHOS +#endif //INPUTMETHOD_IMF_DISPLAY_ADAPTER_H diff --git a/services/adapter/display_adapter/src/display_adapter.cpp b/services/adapter/display_adapter/src/display_adapter.cpp new file mode 100644 index 000000000..cff4f2cb5 --- /dev/null +++ b/services/adapter/display_adapter/src/display_adapter.cpp @@ -0,0 +1,46 @@ +/* + * 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 "display_adapter.h" + +#include + +#include "display_info.h" +#include "display_manager_lite.h" +#include "global.h" + +namespace OHOS { +namespace MiscServices { +using namespace OHOS::Rosen; +std::string DisplayAdapter::GetDisplayName(uint64_t displayId) +{ + sptr display = DisplayManagerLite::GetInstance().GetDisplayById(displayId); + if (display == nullptr) { + IMSA_HILOGE("%{public}" PRIu64 ":display is null!", displayId); + return ""; + } + sptr displayInfo = display->GetDisplayInfo(); + if (displayInfo == nullptr) { + IMSA_HILOGE("%{public}" PRIu64 ":displayInfo is null!", displayId); + return ""; + } + return displayInfo->GetName(); +} + +uint64_t DisplayAdapter::GetDefaultDisplayId() +{ + return DisplayManagerLite::GetInstance().GetDefaultDisplayId(); +} +} // namespace MiscServices +} // namespace OHOS diff --git a/services/include/ime_info_inquirer.h b/services/include/ime_info_inquirer.h index e7b0ada42..e696e7bb8 100644 --- a/services/include/ime_info_inquirer.h +++ b/services/include/ime_info_inquirer.h @@ -105,6 +105,7 @@ public: 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 IsRestrictedMainDisplayId(uint64_t displayId); bool IsDynamicStartIme(); std::unordered_set GetDisableNumKeyAppDeviceTypes(); bool GetCompatibleDeviceType(const std::string &bundleName, std::string &compatibleDeviceType); diff --git a/services/include/peruser_session.h b/services/include/peruser_session.h index cb36cbadc..3c375fa2b 100644 --- a/services/include/peruser_session.h +++ b/services/include/peruser_session.h @@ -151,7 +151,7 @@ public: bool IsSaReady(int32_t saId); void TryUnloadSystemAbility(); void OnCallingDisplayIdChanged(const int32_t windowId, const int32_t callingPid, const uint64_t displayId); - ImfCallingWindowInfo GetCallingWindowInfo(const InputClientInfo &clientInfo); + ImfCallingWindowInfo GetFinalCallingWindowInfo(const InputClientInfo &clientInfo); bool SpecialScenarioCheck(); bool IsScreenLockOrSecurityFlag(); int32_t SpecialSendPrivateData(const std::unordered_map &privateCommand); @@ -255,6 +255,7 @@ private: bool GetInputTypeToStart(std::shared_ptr &imeToStart); void HandleImeBindTypeChanged(InputClientInfo &newClientInfo, const std::shared_ptr &clientGroup); int32_t NotifyCallingDisplayChanged(uint64_t displayId); + ImfCallingWindowInfo GetCallingWindowInfo(const InputClientInfo &clientInfo); bool GetCallingWindowInfo(const InputClientInfo &clientInfo, Rosen::CallingWindowInfo &callingWindowInfo); int32_t SendPrivateData(const std::unordered_map &privateCommand); void ClearRequestKeyboardReason(std::shared_ptr &clientInfo); diff --git a/services/include/sys_cfg_parser.h b/services/include/sys_cfg_parser.h index 664f7c1d3..c980d0db1 100644 --- a/services/include/sys_cfg_parser.h +++ b/services/include/sys_cfg_parser.h @@ -34,6 +34,7 @@ struct SystemConfig : public Serializable { std::unordered_set proxyImeUidList; std::unordered_set specialSaUidList; std::unordered_set defaultImeScreenList; + std::unordered_set defaultMainDisplayIdScreenList; std::unordered_set supportedCapacityList; std::string dynamicStartImeSysParam; std::string dynamicStartImeValue; @@ -53,6 +54,7 @@ struct SystemConfig : public Serializable { GetValue(node, GET_NAME(proxyImeUidList), proxyImeUidList); GetValue(node, GET_NAME(specialSaUidList), specialSaUidList); GetValue(node, GET_NAME(defaultImeScreenList), defaultImeScreenList); + GetValue(node, GET_NAME(defaultMainDisplayIdScreenList), defaultMainDisplayIdScreenList); GetValue(node, GET_NAME(supportedCapacityList), supportedCapacityList); GetValue(node, GET_NAME(dynamicStartImeSysParam), dynamicStartImeSysParam); GetValue(node, GET_NAME(dynamicStartImeValue), dynamicStartImeValue); diff --git a/services/src/ime_info_inquirer.cpp b/services/src/ime_info_inquirer.cpp index f1bcf5a1c..f273addae 100644 --- a/services/src/ime_info_inquirer.cpp +++ b/services/src/ime_info_inquirer.cpp @@ -27,8 +27,7 @@ #include "parameters.h" #include "singleton.h" #include "system_ability_definition.h" -#include "display_manager_lite.h" -#include "display_info.h" +#include "display_adapter.h" namespace OHOS { namespace MiscServices { @@ -1222,17 +1221,7 @@ bool ImeInfoInquirer::IsInputMethodExtension(pid_t pid) bool ImeInfoInquirer::IsRestrictedDefaultImeByDisplay(uint64_t displayId) { - sptr display = Rosen::DisplayManagerLite::GetInstance().GetDisplayById(displayId); - if (display == nullptr) { - IMSA_HILOGE("display is null!"); - return false; - } - sptr displayInfo = display->GetDisplayInfo(); - if (displayInfo == nullptr) { - IMSA_HILOGE("displayInfo is null!"); - return false; - } - auto screenName = displayInfo->GetName(); + auto screenName = DisplayAdapter::GetDisplayName(displayId); return systemConfig_.defaultImeScreenList.find(screenName) != systemConfig_.defaultImeScreenList.end(); } @@ -1262,5 +1251,12 @@ bool ImeInfoInquirer::GetCompatibleDeviceType( compatibleDeviceType = deviceType; return true; } + +bool ImeInfoInquirer::IsRestrictedMainDisplayId(uint64_t displayId) +{ + auto screenName = DisplayAdapter::GetDisplayName(displayId); + return systemConfig_.defaultMainDisplayIdScreenList.find(screenName) + != systemConfig_.defaultMainDisplayIdScreenList.end(); +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/services/src/input_method_system_ability.cpp b/services/src/input_method_system_ability.cpp index caac6c8c6..a0b748de3 100644 --- a/services/src/input_method_system_ability.cpp +++ b/services/src/input_method_system_ability.cpp @@ -584,7 +584,7 @@ int32_t InputMethodSystemAbility::GenerateClientInfo(int32_t userId, InputClient clientInfo.name = ImfHiSysEventUtil::GetAppName(tokenId); auto session = UserSessionManager::GetInstance().GetUserSession(userId); if (session != nullptr) { - auto callingWindowInfo = session->GetCallingWindowInfo(clientInfo); + auto callingWindowInfo = session->GetFinalCallingWindowInfo(clientInfo); clientInfo.config.inputAttribute.windowId = callingWindowInfo.windowId; clientInfo.config.inputAttribute.callingDisplayId = callingWindowInfo.displayId; clientInfo.config.inputAttribute.needAutoInputNumkey = diff --git a/services/src/peruser_session.cpp b/services/src/peruser_session.cpp index 51cc5f8c7..cfe23319b 100644 --- a/services/src/peruser_session.cpp +++ b/services/src/peruser_session.cpp @@ -48,6 +48,7 @@ #include "ime_state_manager_factory.h" #include "inputmethod_trace.h" #include "notify_service_impl.h" +#include "display_adapter.h" namespace OHOS { namespace MiscServices { @@ -1423,7 +1424,7 @@ int32_t PerUserSession::OnSetCallingWindow(uint32_t callingWindowId, clientGroup->NotifyInputStartToClients(callingWindowId, static_cast(clientInfo->requestKeyboardReason)); if (callingWindowId != INVALID_WINDOW_ID) { - auto callingWindowInfo = GetCallingWindowInfo(*clientInfo); + auto callingWindowInfo = GetFinalCallingWindowInfo(*clientInfo); clientInfo->config.inputAttribute.windowId = callingWindowInfo.windowId; bool isNotifyDisplayChanged = clientInfo->config.inputAttribute.callingDisplayId != callingWindowInfo.displayId && @@ -2317,6 +2318,16 @@ int32_t PerUserSession::NotifyCallingDisplayChanged(uint64_t displayId) return ret; } +ImfCallingWindowInfo PerUserSession::GetFinalCallingWindowInfo(const InputClientInfo &clientInfo) +{ + auto windowInfo = GetCallingWindowInfo(clientInfo); + if (SceneBoardJudgement::IsSceneBoardEnabled() && + ImeInfoInquirer::GetInstance().IsRestrictedMainDisplayId(windowInfo.displayId)) { + windowInfo.displayId = DisplayAdapter::GetDefaultDisplayId(); + } + return windowInfo; +} + ImfCallingWindowInfo PerUserSession::GetCallingWindowInfo(const InputClientInfo &clientInfo) { InputMethodSyncTrace tracer("GetCallingWindowInfo trace"); -- Gitee From 56921e7f628d3eaba1feafd99784a03849cb71d5 Mon Sep 17 00:00:00 2001 From: cy7717 Date: Fri, 8 Aug 2025 10:51:52 +0800 Subject: [PATCH 2/3] mod for retry Signed-off-by: cy7717 --- common/include/global.h | 3 +++ common/src/global.cpp | 16 ++++++++++++++++ .../js/napi/inputmethodclient/js_utils.cpp | 1 + .../src/input_method_controller.cpp | 14 ++++++++++++++ frameworks/ndk/src/native_capi_utils.cpp | 1 + .../include/input_method_system_ability.h | 1 + services/src/input_method_system_ability.cpp | 19 +++++++++++++++++-- 7 files changed, 53 insertions(+), 2 deletions(-) diff --git a/common/include/global.h b/common/include/global.h index 3748e1939..c1e2e2a3e 100644 --- a/common/include/global.h +++ b/common/include/global.h @@ -142,6 +142,7 @@ enum { ERROR_SA_POST_TASK_FAILED, ERROR_IME_HAS_STARTED, ERROR_OPERATION_NOT_ALLOWED, + ERROR_IMSA_TASK_RUNNING, ERROR_IMSA_END, }; }; // namespace ErrorCode @@ -169,7 +170,9 @@ static constexpr HiviewDFX::HiLogLabel g_SMALL_SERVICES_LABEL = { LOG_CORE, 0xD0 OHOS::MiscServices::g_SMALL_SERVICES_LABEL.tag, "line: %{public}d, function: %{public}s," fmt, __LINE__, \ __FUNCTION__, ##__VA_ARGS__) using Function = std::function; +using RetFunction = std::function; bool BlockRetry(uint32_t interval, uint32_t maxRetryTimes, Function func); +bool BlockRetry(uint32_t interval, uint32_t maxRetryTimes, RetFunction func, int32_t &ret); } // namespace MiscServices } // namespace OHOS #endif // SERVICES_INCLUDE_GLOBAL_H diff --git a/common/src/global.cpp b/common/src/global.cpp index 93b578c2d..b099ce757 100644 --- a/common/src/global.cpp +++ b/common/src/global.cpp @@ -35,5 +35,21 @@ bool BlockRetry(uint32_t interval, uint32_t maxRetryTimes, Function func) IMSA_HILOGI("retry failed"); return false; } + +bool BlockRetry(uint32_t interval, uint32_t maxRetryTimes, RetFunction func, int32_t &ret) +{ + IMSA_HILOGD("retry start"); + uint32_t times = 0; + do { + times++; + if (func(ret)) { + IMSA_HILOGD("success, retry times is: %{public}d", times); + return true; + } + std::this_thread::sleep_for(std::chrono::milliseconds(interval)); + } while (times < maxRetryTimes); + IMSA_HILOGI("retry failed"); + return false; +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/frameworks/js/napi/inputmethodclient/js_utils.cpp b/frameworks/js/napi/inputmethodclient/js_utils.cpp index 737d2e7a2..8d9d1f35e 100644 --- a/frameworks/js/napi/inputmethodclient/js_utils.cpp +++ b/frameworks/js/napi/inputmethodclient/js_utils.cpp @@ -94,6 +94,7 @@ const std::map JsUtils::ERROR_CODE_MAP = { { ErrorCode::ERROR_IMA_DATA_CHANNEL_ABNORMAL, EXCEPTION_IMCLIENT }, { ErrorCode::ERROR_IMA_INVALID_IMMERSIVE_EFFECT, EXCEPTION_INVALID_IMMERSIVE_EFFECT }, { ErrorCode::ERROR_IMA_PRECONDITION_REQUIRED, EXCEPTION_PRECONDITION_REQUIRED }, + { ErrorCode::ERROR_IMSA_TASK_RUNNING, EXCEPTION_IMMS }, }; const std::map JsUtils::ERROR_CODE_CONVERT_MESSAGE_MAP = { diff --git a/frameworks/native/inputmethod_controller/src/input_method_controller.cpp b/frameworks/native/inputmethod_controller/src/input_method_controller.cpp index f7d5e5362..422037ddc 100644 --- a/frameworks/native/inputmethod_controller/src/input_method_controller.cpp +++ b/frameworks/native/inputmethod_controller/src/input_method_controller.cpp @@ -301,6 +301,20 @@ int32_t InputMethodController::IsValidTextConfig(const TextConfig &textConfig) int32_t InputMethodController::Attach(sptr listener, const AttachOptions &attachOptions, const TextConfig &textConfig, ClientType type) +{ + auto task = [listener, attachOptions, textConfig, type, this](int32_t &ret) { + ret = AttachExec(listener, attachOptions, textConfig, type); + return ret != ErrorCode::ERROR_IMSA_TASK_RUNNING; + }; + int32_t ret = ErrorCode::NO_ERROR; + if (BlockRetry(200, 3, task, ret)) { + return ret; + } + return ret; +} + +int32_t InputMethodController::AttachExec(sptr listener, const AttachOptions &attachOptions, + const TextConfig &textConfig, ClientType type) { IMSA_HILOGI("isShowKeyboard %{public}d.", attachOptions.isShowKeyboard); InputMethodSyncTrace tracer("InputMethodController Attach with textConfig trace."); diff --git a/frameworks/ndk/src/native_capi_utils.cpp b/frameworks/ndk/src/native_capi_utils.cpp index 6023564f8..85d627309 100644 --- a/frameworks/ndk/src/native_capi_utils.cpp +++ b/frameworks/ndk/src/native_capi_utils.cpp @@ -72,6 +72,7 @@ static const std::map ERROR_CODE_MAP = { { ErrorCode::ERROR_IMSA_FORCE_STOP_IME_TIMEOUT, IME_ERR_IMMS }, { ErrorCode::ERROR_IMC_NULLPTR, IME_ERR_IMMS }, { ErrorCode::ERROR_IMA_DATA_CHANNEL_ABNORMAL, IME_ERR_IMCLIENT }, + { ErrorCode::ERROR_IMSA_TASK_RUNNING, IME_ERR_IMMS }, }; InputMethod_ErrorCode ErrorCodeConvert(int32_t code) diff --git a/services/include/input_method_system_ability.h b/services/include/input_method_system_ability.h index 0109ceaa0..63115d6c4 100644 --- a/services/include/input_method_system_ability.h +++ b/services/include/input_method_system_ability.h @@ -229,6 +229,7 @@ private: std::mutex switchImeMutex_; std::atomic switchTaskExecuting_ = false; std::atomic targetSwitchCount_ = 0; + std::atomic bindTaskExecuting_ = false; }; } // namespace MiscServices } // namespace OHOS diff --git a/services/src/input_method_system_ability.cpp b/services/src/input_method_system_ability.cpp index a0b748de3..bfc55d1e8 100644 --- a/services/src/input_method_system_ability.cpp +++ b/services/src/input_method_system_ability.cpp @@ -670,9 +670,14 @@ int32_t InputMethodSystemAbility::StartInputInner( IdentityChecker::INVALID_PID, true, inputClientInfo.config.abilityToken)) { return ErrorCode::ERROR_CLIENT_NOT_FOCUSED; } + if (bindTaskExecuting_.exchange(true)) { + IMSA_HILOGW("%{public}d task is running!", userId); + return ErrorCode::ERROR_IMSA_TASK_RUNNING; + } auto session = UserSessionManager::GetInstance().GetUserSession(userId); if (session == nullptr) { IMSA_HILOGE("%{public}d session is nullptr!", userId); + bindTaskExecuting_.store(false); return ErrorCode::ERROR_IMSA_USER_SESSION_NOT_FOUND; } auto displayId = GetCallingDisplayId(); @@ -689,6 +694,7 @@ int32_t InputMethodSystemAbility::StartInputInner( auto ret = CheckInputTypeOption(userId, inputClientInfo); if (ret != ErrorCode::NO_ERROR) { IMSA_HILOGE("%{public}d failed to CheckInputTypeOption!", userId); + bindTaskExecuting_.store(false); return ret; } } @@ -696,10 +702,13 @@ int32_t InputMethodSystemAbility::StartInputInner( int32_t ret = PrepareInput(userId, inputClientInfo); if (ret != ErrorCode::NO_ERROR) { IMSA_HILOGE("failed to PrepareInput!"); + bindTaskExecuting_.store(false); return ret; } session->SetInputType(); - return session->OnStartInput(inputClientInfo, agent, imeInfo); + ret = session->OnStartInput(inputClientInfo, agent, imeInfo); + bindTaskExecuting_.store(false); + return ret; } int32_t InputMethodSystemAbility::CheckInputTypeOption(int32_t userId, InputClientInfo &inputClientInfo) @@ -836,7 +845,13 @@ ErrCode InputMethodSystemAbility::SetCoreAndAgent(const sptr & return ErrorCode::ERROR_NULL_POINTER; } if (identityChecker_->IsNativeSa(IPCSkeleton::GetCallingTokenID())) { - return session->OnRegisterProxyIme(core, agent); + if (bindTaskExecuting_.exchange(true)) { + IMSA_HILOGE("%{public}d task is running!", userId); + return ErrorCode::ERROR_IMSA_TASK_RUNNING; + } + auto ret = session->OnRegisterProxyIme(core, agent); + bindTaskExecuting_.store(false); + return ret; } if (!IsCurrentIme(userId)) { IMSA_HILOGE("not current ime, userId:%{public}d", userId); -- Gitee From 0b93dfabafe4165239da83625a4e268f3ce18aae Mon Sep 17 00:00:00 2001 From: cy7717 Date: Sat, 9 Aug 2025 15:17:14 +0800 Subject: [PATCH 3/3] mod for tmp ime switch Signed-off-by: cy7717 --- .../include/input_method_property.h | 1 + .../include/input_method_system_ability.h | 3 +- services/src/input_method_system_ability.cpp | 70 ++++++++++++++----- 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/frameworks/native/inputmethod_controller/include/input_method_property.h b/frameworks/native/inputmethod_controller/include/input_method_property.h index 1b61e2a4b..f737ed917 100644 --- a/frameworks/native/inputmethod_controller/include/input_method_property.h +++ b/frameworks/native/inputmethod_controller/include/input_method_property.h @@ -166,6 +166,7 @@ struct SwitchInfo { std::chrono::system_clock::time_point timestamp{}; std::string bundleName; std::string subName; + bool isTmpImeSwitchSubtype{ false }; bool operator==(const SwitchInfo &info) const { return (timestamp == info.timestamp && bundleName == info.bundleName && subName == info.subName); diff --git a/services/include/input_method_system_ability.h b/services/include/input_method_system_ability.h index 63115d6c4..854dfc297 100644 --- a/services/include/input_method_system_ability.h +++ b/services/include/input_method_system_ability.h @@ -177,7 +177,7 @@ private: int32_t CheckInputTypeOption(int32_t userId, InputClientInfo &inputClientInfo); int32_t IsDefaultImeFromTokenId(int32_t userId, uint32_t tokenId); void DealSwitchRequest(); - bool IsCurrentIme(int32_t userId); + bool IsCurrentIme(int32_t userId, uint32_t tokenId); int32_t StartInputType(int32_t userId, InputType type); // if switch input type need to switch ime, then no need to hide panel first. void NeedHideWhenSwitchInputType(int32_t userId, InputType type, bool &needHide); @@ -208,6 +208,7 @@ private: int32_t RestoreInputmethod(std::string &bundleName); void IncreaseAttachCount(); void DecreaseAttachCount(); + bool IsTmpImeSwitchSubtype(int32_t userId, uint32_t tokenId, const SwitchInfo &switchInfo); class AttachStateGuard { public: diff --git a/services/src/input_method_system_ability.cpp b/services/src/input_method_system_ability.cpp index bfc55d1e8..37dc553d2 100644 --- a/services/src/input_method_system_ability.cpp +++ b/services/src/input_method_system_ability.cpp @@ -839,12 +839,13 @@ ErrCode InputMethodSystemAbility::SetCoreAndAgent(const sptr & { IMSA_HILOGD("InputMethodSystemAbility start."); auto userId = GetCallingUserId(); + auto tokenId = GetCallingTokenID(); auto session = UserSessionManager::GetInstance().GetUserSession(userId); if (session == nullptr) { IMSA_HILOGE("%{public}d session is nullptr!", userId); return ErrorCode::ERROR_NULL_POINTER; } - if (identityChecker_->IsNativeSa(IPCSkeleton::GetCallingTokenID())) { + if (identityChecker_->IsNativeSa(tokenId)) { if (bindTaskExecuting_.exchange(true)) { IMSA_HILOGE("%{public}d task is running!", userId); return ErrorCode::ERROR_IMSA_TASK_RUNNING; @@ -853,7 +854,7 @@ ErrCode InputMethodSystemAbility::SetCoreAndAgent(const sptr & bindTaskExecuting_.store(false); return ret; } - if (!IsCurrentIme(userId)) { + if (!IsCurrentIme(userId, tokenId)) { IMSA_HILOGE("not current ime, userId:%{public}d", userId); return ErrorCode::ERROR_NOT_CURRENT_IME; } @@ -903,15 +904,17 @@ ErrCode InputMethodSystemAbility::InitConnect() { IMSA_HILOGD("InputMethodSystemAbility init connect."); auto userId = GetCallingUserId(); + auto tokenId = GetCallingTokenID(); + auto pid = IPCSkeleton::GetCallingPid(); auto session = UserSessionManager::GetInstance().GetUserSession(userId); if (session == nullptr) { IMSA_HILOGE("%{public}d session is nullptr!", userId); return ErrorCode::ERROR_NULL_POINTER; } - if (!IsCurrentIme(userId)) { + if (!IsCurrentIme(userId, tokenId)) { return ErrorCode::ERROR_NOT_CURRENT_IME; } - return session->InitConnect(IPCSkeleton::GetCallingPid()); + return session->InitConnect(pid); } ErrCode InputMethodSystemAbility::HideCurrentInput() @@ -953,7 +956,8 @@ ErrCode InputMethodSystemAbility::ShowCurrentInputInner() ErrCode InputMethodSystemAbility::PanelStatusChange(uint32_t status, const ImeWindowInfo &info) { auto userId = GetCallingUserId(); - if (!IsCurrentIme(userId)) { + auto tokenId = GetCallingTokenID(); + if (!IsCurrentIme(userId, tokenId)) { IMSA_HILOGE("not current ime!"); return ErrorCode::ERROR_NOT_CURRENT_IME; } @@ -1035,7 +1039,9 @@ ErrCode InputMethodSystemAbility::GetInputStartInfo(bool& isInputStart, ErrCode InputMethodSystemAbility::IsCurrentIme(bool& resultValue) { - resultValue = IsCurrentIme(GetCallingUserId()); + auto userId = GetCallingUserId(); + auto tokenId = GetCallingTokenID(); + resultValue = IsCurrentIme(userId, tokenId); return ERR_OK; } @@ -1155,8 +1161,9 @@ ErrCode InputMethodSystemAbility::SwitchInputMethod(const std::string &bundleNam IMSA_HILOGW("caller counterfeit!"); return ErrorCode::ERROR_BAD_PARAMETERS; } - SwitchInfo switchInfo = { std::chrono::system_clock::now(), bundleName, subName }; int32_t userId = GetCallingUserId(); + auto tokenId = GetCallingTokenID(); + SwitchInfo switchInfo = { std::chrono::system_clock::now(), bundleName, subName }; auto session = UserSessionManager::GetInstance().GetUserSession(userId); if (session == nullptr) { IMSA_HILOGE("%{public}d session is nullptr!", userId); @@ -1177,6 +1184,7 @@ ErrCode InputMethodSystemAbility::SwitchInputMethod(const std::string &bundleNam switchInfo.subName = currentImeCfg->subName; } switchInfo.timestamp = std::chrono::system_clock::now(); + switchInfo.isTmpImeSwitchSubtype = IsTmpImeSwitchSubtype(userId, tokenId, switchInfo); session->GetSwitchQueue().Push(switchInfo); return InputTypeManager::GetInstance().IsInputType({ bundleName, subName }) ? OnStartInputType(userId, switchInfo, true) @@ -1218,7 +1226,9 @@ int32_t InputMethodSystemAbility::StartSwitch(int32_t userId, const SwitchInfo & { InputMethodSyncTrace tracer("InputMethodSystemAbility_OnSwitchInputMethod"); std::string targetImeName = info->prop.name + "/" + info->prop.id; - ImeCfgManager::GetInstance().ModifyImeCfg({ userId, targetImeName, switchInfo.subName, true }); + if (!switchInfo.isTmpImeSwitchSubtype) { + ImeCfgManager::GetInstance().ModifyImeCfg({ userId, targetImeName, switchInfo.subName, true }); + } auto targetIme = std::make_shared( ImeNativeCfg{ targetImeName, info->prop.name, switchInfo.subName, info->prop.id }); ret = session->StartIme(targetIme); @@ -1228,7 +1238,9 @@ int32_t InputMethodSystemAbility::StartSwitch(int32_t userId, const SwitchInfo & return ret; } GetValidSubtype(switchInfo.subName, info); - session->NotifyImeChangeToClients(info->prop, info->subProp); + if (!switchInfo.isTmpImeSwitchSubtype) { + session->NotifyImeChangeToClients(info->prop, info->subProp); + } ret = session->SwitchSubtype(info->subProp); } ret = info->isSpecificSubName ? ret : ErrorCode::NO_ERROR; @@ -1239,6 +1251,28 @@ int32_t InputMethodSystemAbility::StartSwitch(int32_t userId, const SwitchInfo & return ret; } +bool InputMethodSystemAbility::IsTmpImeSwitchSubtype(int32_t userId, uint32_t tokenId, const SwitchInfo &switchInfo) +{ + if (!IsCurrentIme(userId, tokenId)) { + IMSA_HILOGD("caller is not current running ime!"); + return false; + } + auto currentImeCfg = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId); + if (currentImeCfg == nullptr || currentImeCfg->bundleName.empty()) { + return false; + } + auto session = UserSessionManager::GetInstance().GetUserSession(userId); + if (session == nullptr) { + IMSA_HILOGE("%{public}d session is nullptr!", userId); + return false; + } + auto imeData = session->GetImeData(ImeType::IME); + if (imeData == nullptr) { + return false; + } + return imeData->ime.first == switchInfo.bundleName && imeData->ime.first != currentImeCfg->bundleName; +} + int32_t InputMethodSystemAbility::OnSwitchInputMethod(int32_t userId, const SwitchInfo &switchInfo, SwitchTrigger trigger) { @@ -2182,6 +2216,7 @@ int32_t InputMethodSystemAbility::CheckSwitchPermission(int32_t userId, const Sw SwitchTrigger trigger) { IMSA_HILOGD("trigger: %{public}d.", static_cast(trigger)); + auto tokenId = IPCSkeleton::GetCallingTokenID(); if (trigger == SwitchTrigger::IMSA) { return ErrorCode::NO_ERROR; } @@ -2193,8 +2228,7 @@ int32_t InputMethodSystemAbility::CheckSwitchPermission(int32_t userId, const Sw IMSA_HILOGE("not system app!"); return ErrorCode::ERROR_STATUS_SYSTEM_PERMISSION; } - if (!identityChecker_->HasPermission(IPCSkeleton::GetCallingTokenID(), - std::string(PERMISSION_CONNECT_IME_ABILITY))) { + if (!identityChecker_->HasPermission(tokenId, std::string(PERMISSION_CONNECT_IME_ABILITY))) { IMSA_HILOGE("have not PERMISSION_CONNECT_IME_ABILITY!"); return ErrorCode::ERROR_STATUS_PERMISSION_DENIED; } @@ -2202,14 +2236,12 @@ int32_t InputMethodSystemAbility::CheckSwitchPermission(int32_t userId, const Sw } if (trigger == SwitchTrigger::CURRENT_IME) { // PERMISSION_CONNECT_IME_ABILITY check temporarily reserved for application adaptation, will be deleted soon - if (identityChecker_->HasPermission(IPCSkeleton::GetCallingTokenID(), - std::string(PERMISSION_CONNECT_IME_ABILITY))) { + if (identityChecker_->HasPermission(tokenId, std::string(PERMISSION_CONNECT_IME_ABILITY))) { return ErrorCode::NO_ERROR; } IMSA_HILOGE("have not PERMISSION_CONNECT_IME_ABILITY!"); // switchInfo.subName.empty() check temporarily reserved for application adaptation, will be deleted soon - auto currentBundleName = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId)->bundleName; - if (identityChecker_->IsBundleNameValid(IPCSkeleton::GetCallingTokenID(), currentBundleName)) { + if (IsCurrentIme(userId, tokenId)) { return ErrorCode::NO_ERROR; } IMSA_HILOGE("not current ime!"); @@ -2426,17 +2458,17 @@ uint64_t InputMethodSystemAbility::GetCallingDisplayId(sptr abili return identityChecker_->GetDisplayIdByPid(IPCSkeleton::GetCallingPid(), abilityToken); } -bool InputMethodSystemAbility::IsCurrentIme(int32_t userId) +bool InputMethodSystemAbility::IsCurrentIme(int32_t userId, uint32_t tokenId) { auto session = UserSessionManager::GetInstance().GetUserSession(userId); if (session == nullptr) { IMSA_HILOGE("%{public}d session is nullptr!", userId); return false; } - auto bundleName = FullImeInfoManager::GetInstance().Get(userId, IPCSkeleton::GetCallingTokenID()); + auto bundleName = FullImeInfoManager::GetInstance().Get(userId, tokenId); if (bundleName.empty()) { - IMSA_HILOGW("user:%{public}d tokenId:%{public}d not find.", userId, IPCSkeleton::GetCallingTokenID()); - bundleName = identityChecker_->GetBundleNameByToken(IPCSkeleton::GetCallingTokenID()); + IMSA_HILOGW("user:%{public}d tokenId:%{public}d not find.", userId, tokenId); + bundleName = identityChecker_->GetBundleNameByToken(tokenId); } auto imeData = session->GetImeData(ImeType::IME); return imeData != nullptr && bundleName == imeData->ime.first; -- Gitee