diff --git a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp index f6e9f566f77c9512f12ee7a18a21337b54abbaea..0cae789e32e1362c34b3109dc74b9a41588ba680 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp @@ -183,7 +183,7 @@ int32_t InputMethodAbility::RegisterProxyIme(uint64_t displayId) return ret; } isBound_.store(true); - isProxyIme_.store(true); + isProxyIme_.store(displayId != DEFAULT_DISPLAY_ID); IMSA_HILOGD("set successfully, displayId: %{public}" PRIu64 "", displayId); return ErrorCode::NO_ERROR; } diff --git a/services/include/client_group.h b/services/include/client_group.h index afdb6b8ddd0ef1dfb38623e3ab594aa3a99155ee..62acba9581b50f666addb09e187bbbec891bcedc 100644 --- a/services/include/client_group.h +++ b/services/include/client_group.h @@ -37,6 +37,7 @@ public: { } + uint64_t GetDisplayGroupId(); int32_t AddClientInfo( const sptr &inputClient, const InputClientInfo &clientInfo, ClientAddEvent event); void RemoveClientInfo(const sptr &client, bool isClientDied = false); diff --git a/services/include/peruser_session.h b/services/include/peruser_session.h index 6056727e6c5a9d7578208c4f5357730ba47c0266..ef99b9083e4d340657d3c82942cd072d56637bdb 100644 --- a/services/include/peruser_session.h +++ b/services/include/peruser_session.h @@ -124,7 +124,7 @@ public: bool IsProxyImeEnable(); bool IsBoundToClient(uint64_t displayId); bool IsCurrentImeByPid(int32_t pid); - int32_t RestoreCurrentImeSubType(); + int32_t RestoreCurrentImeSubType(uint64_t callingDisplayId); int32_t IsPanelShown(const PanelInfo &panelInfo, bool &isShown); bool CheckSecurityMode(); int32_t OnConnectSystemCmd(const sptr &channel, sptr &agent); @@ -134,7 +134,7 @@ public: BlockQueue& GetSwitchQueue(); bool IsWmsReady(); bool CheckPwdInputPatternConv(InputClientInfo &clientInfo, uint64_t displayId); - int32_t RestoreCurrentIme(); + int32_t RestoreCurrentIme(uint64_t callingDisplayId); int32_t SetInputType(); std::shared_ptr GetImeNativeCfg(int32_t userId, const std::string &bundleName, const std::string &subName); @@ -148,6 +148,8 @@ public: bool SpecialScenarioCheck(); int32_t SpecialSendPrivateData(const std::unordered_map &privateCommand); uint64_t GetDisplayGroupId(uint64_t displayId); + bool IsDefaultDisplayGroup(uint64_t displayId); + private: struct ResetManager { uint32_t num{ 0 }; diff --git a/services/src/client_group.cpp b/services/src/client_group.cpp index 4db6ddaf6f925ed437bf10b44bb859cbbf84e20f..d5705f6fab1c003181c312146161382e06193ee7 100644 --- a/services/src/client_group.cpp +++ b/services/src/client_group.cpp @@ -23,6 +23,11 @@ namespace OHOS { namespace MiscServices { +uint64_t ClientGroup::GetDisplayGroupId() +{ + return displayGroupId_; +} + int32_t ClientGroup::AddClientInfo( const sptr &inputClient, const InputClientInfo &clientInfo, ClientAddEvent event) { diff --git a/services/src/input_method_system_ability.cpp b/services/src/input_method_system_ability.cpp index 10f15c0d17b987a521d37f34d38ecc6bf16d1230..c07e5297800040ec04b02aed67e781be36ede004 100644 --- a/services/src/input_method_system_ability.cpp +++ b/services/src/input_method_system_ability.cpp @@ -13,10 +13,13 @@ * limitations under the License. */ +#include "input_method_system_ability.h" + +#include + #include "securec.h" #include "unordered_map" #include "variant" -#include "input_method_system_ability.h" #include "ability_manager_client.h" #include "combination_key.h" #include "full_ime_info_manager.h" @@ -638,12 +641,11 @@ int32_t InputMethodSystemAbility::StartInputInner( // notify inputStart when caller pid different from both current client and inactive client inputClientInfo.isNotifyInputStart = true; } - auto displayGroupId = session->GetDisplayGroupId(displayId); if (session->CheckPwdInputPatternConv(inputClientInfo, displayId)) { inputClientInfo.needHide = true; inputClientInfo.isNotifyInputStart = true; } - if (displayGroupId == DEFAULT_DISPLAY_ID && !session->IsProxyImeEnable()) { + if (session->IsDefaultDisplayGroup(displayId) && !session->IsProxyImeEnable()) { auto ret = CheckInputTypeOption(userId, inputClientInfo); if (ret != ErrorCode::NO_ERROR) { IMSA_HILOGE("%{public}d failed to CheckInputTypeOption!", userId); @@ -696,7 +698,7 @@ int32_t InputMethodSystemAbility::CheckInputTypeOption(int32_t userId, InputClie } if (InputTypeManager::GetInstance().IsStarted()) { IMSA_HILOGD("NormalFlag, diff textField, input type started, restore."); - session->RestoreCurrentImeSubType(); + session->RestoreCurrentImeSubType(DEFAULT_DISPLAY_ID); } ChangeToDefaultImeForHiCar(userId, inputClientInfo); #ifdef IMF_SCREENLOCK_MGR_ENABLE @@ -709,7 +711,7 @@ int32_t InputMethodSystemAbility::CheckInputTypeOption(int32_t userId, InputClie ImeCfgManager::GetInstance().ModifyTempScreenLockImeCfg(userId_, ime); } #endif - return session->RestoreCurrentIme(); + return session->RestoreCurrentIme(DEFAULT_DISPLAY_ID); } void InputMethodSystemAbility::ChangeToDefaultImeForHiCar(int32_t userId, InputClientInfo &inputClientInfo) @@ -1054,9 +1056,9 @@ ErrCode InputMethodSystemAbility::ExitCurrentInputType() auto typeIme = InputTypeManager::GetInstance().GetCurrentIme(); auto cfgIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_); if (cfgIme->bundleName == typeIme.bundleName) { - return session->RestoreCurrentImeSubType(); + return session->RestoreCurrentImeSubType(DEFAULT_DISPLAY_ID); } - return session->RestoreCurrentIme(); + return session->RestoreCurrentIme(DEFAULT_DISPLAY_ID); } ErrCode InputMethodSystemAbility::IsDefaultIme() @@ -2028,7 +2030,7 @@ ErrCode InputMethodSystemAbility::UnRegisteredProxyIme(int32_t type, const sptr< if (session->CheckSecurityMode()) { ret = StartInputType(userId, InputType::SECURITY_INPUT); } else { - ret = session->RestoreCurrentIme(); + ret = session->RestoreCurrentIme(DEFAULT_DISPLAY_ID); } if (ret != ErrorCode::NO_ERROR) { return ret; @@ -2310,13 +2312,17 @@ int32_t InputMethodSystemAbility::StartInputType(int32_t userId, InputType type) IMSA_HILOGE("%{public}d session is nullptr!", userId); return ErrorCode::ERROR_IMSA_USER_SESSION_NOT_FOUND; } + if (!session->IsDefaultDisplayGroup(GetCallingDisplayId())) { + IMSA_HILOGI("only need input type in default display"); + return ErrorCode::NO_ERROR; + } ImeIdentification ime; int32_t ret = InputTypeManager::GetInstance().GetImeByInputType(type, ime); if (ret != ErrorCode::NO_ERROR) { IMSA_HILOGW("not find input type: %{public}d.", type); // add for not adapter for SECURITY_INPUT if (type == InputType::SECURITY_INPUT) { - return session->RestoreCurrentIme(); + return session->RestoreCurrentIme(DEFAULT_DISPLAY_ID); } return ret; } diff --git a/services/src/peruser_session.cpp b/services/src/peruser_session.cpp index 5eaa877ec0f95db3c459cbd534485cb4e10c6867..80de18840339c0b5124cd52e75442e268ceed28a 100644 --- a/services/src/peruser_session.cpp +++ b/services/src/peruser_session.cpp @@ -120,7 +120,7 @@ int32_t PerUserSession::HideKeyboard( } bool isShowKeyboard = false; clientGroup->UpdateClientInfo(currentClient->AsObject(), { { UpdateFlag::ISSHOWKEYBOARD, isShowKeyboard } }); - RestoreCurrentImeSubType(); + RestoreCurrentImeSubType(clientGroup->GetDisplayGroupId()); return ErrorCode::NO_ERROR; } @@ -177,14 +177,14 @@ void PerUserSession::OnClientDied(sptr remote) StopImeInput(clientInfo->bindImeType, clientInfo->channel, 0); } clientGroup->SetCurrentClient(nullptr); - RestoreCurrentImeSubType(); + RestoreCurrentImeSubType(clientGroup->GetDisplayGroupId()); } if (IsSameClient(remote, clientGroup->GetInactiveClient())) { if (clientInfo != nullptr) { StopImeInput(clientInfo->bindImeType, clientInfo->channel, 0); } clientGroup->SetInactiveClient(nullptr); - RestoreCurrentImeSubType(); + RestoreCurrentImeSubType(clientGroup->GetDisplayGroupId()); } clientGroup->RemoveClientInfo(remote->AsObject(), true); } @@ -339,7 +339,7 @@ void PerUserSession::OnHideSoftKeyBoardSelf() return; } clientGroup->UpdateClientInfo(client->AsObject(), { { UpdateFlag::ISSHOWKEYBOARD, false } }); - RestoreCurrentImeSubType(); + RestoreCurrentImeSubType(DEFAULT_DISPLAY_ID); } int32_t PerUserSession::OnRequestShowInput(uint64_t displayId) @@ -387,7 +387,7 @@ int32_t PerUserSession::OnRequestHideInput(int32_t callingPid, uint64_t displayI auto clientGroup = GetClientGroup(displayId); if (clientGroup == nullptr) { - RestoreCurrentImeSubType(); + RestoreCurrentImeSubType(displayId); return ErrorCode::NO_ERROR; } auto currentClient = clientGroup->GetCurrentClient(); @@ -400,7 +400,7 @@ int32_t PerUserSession::OnRequestHideInput(int32_t callingPid, uint64_t displayI DetachOptions options = { .sessionId = 0, .isUnbindFromClient = false, .isInactiveClient = true }; RemoveClient(inactiveClient, clientGroup, options); } - RestoreCurrentImeSubType(); + RestoreCurrentImeSubType(displayId); clientGroup->NotifyInputStopToClients(); return ErrorCode::NO_ERROR; } @@ -455,7 +455,7 @@ int32_t PerUserSession::RemoveClient( if (IsSameClient(client, clientGroup->GetCurrentClient())) { UnBindClientWithIme(clientInfo, options); clientGroup->SetCurrentClient(nullptr); - RestoreCurrentImeSubType(); + RestoreCurrentImeSubType(clientGroup->GetDisplayGroupId()); StopClientInput(clientInfo, false, options.isNotifyClientAsync); } if (IsSameClient(client, clientGroup->GetInactiveClient())) { @@ -660,7 +660,7 @@ void PerUserSession::StopImeInput(ImeType currentType, const sptr Memory::MemMgrClient::GetInstance().SetCritical(getpid(), false, INPUT_METHOD_SYSTEM_ABILITY_ID); } if (currentType == ImeType::IME) { - RestoreCurrentImeSubType(); + RestoreCurrentImeSubType(DEFAULT_DISPLAY_ID); } } @@ -1369,8 +1369,12 @@ bool PerUserSession::IsBoundToClient(uint64_t displayId) return true; } -int32_t PerUserSession::RestoreCurrentImeSubType() +int32_t PerUserSession::RestoreCurrentImeSubType(uint64_t callingDisplayId) { + if (!IsDefaultDisplayGroup(callingDisplayId)) { + IMSA_HILOGI("only need restore in default display, calling display: %{public}" PRIu64 "", callingDisplayId); + return ErrorCode::NO_ERROR; + } if (!InputTypeManager::GetInstance().IsStarted()) { IMSA_HILOGD("already exit."); return ErrorCode::NO_ERROR; @@ -1843,8 +1847,12 @@ int32_t PerUserSession::HandleFirstStart(const std::shared_ptr &im return ErrorCode::ERROR_IMSA_REBOOT_OLD_IME_NOT_STOP; } -int32_t PerUserSession::RestoreCurrentIme() +int32_t PerUserSession::RestoreCurrentIme(uint64_t callingDisplayId) { + if (!IsDefaultDisplayGroup(callingDisplayId)) { + IMSA_HILOGI("only need restore in default display, calling display: %{public}" PRIu64 "", callingDisplayId); + return ErrorCode::NO_ERROR; + } InputTypeManager::GetInstance().Set(false); auto cfgIme = ImeCfgManager::GetInstance().GetCurrentImeCfg(userId_); auto imeData = GetReadyImeData(ImeType::IME); @@ -2195,5 +2203,10 @@ int32_t PerUserSession::SendPrivateData(const std::unordered_map + +#include "ability_manager_client.h" +#include "global.h" +#include "ime_event_monitor_manager_impl.h" +#include "ime_setting_listener_test_impl.h" +#include "input_method_ability_interface.h" +#include "input_method_controller.h" +#include "input_method_engine_listener_impl.h" +#include "input_method_types.h" +#include "keyboard_listener_test_impl.h" +#include "scope_utils.h" +#include "sys_cfg_parser.h" +#include "tdd_util.h" +#include "text_listener.h" +using namespace testing::ext; +namespace OHOS { +namespace MiscServices { +constexpr uint64_t AGENT_IME_DISPLAY_ID = 666; +constexpr int32_t INVALID_UID = -1; +class ImeProxyAgentImeTest : public testing::Test { +public: + static sptr imc_; + static bool isAgentFeatureEnabled_; + static int32_t agentUid_; + static void SetUpTestCase(void) + { + IMSA_HILOGI("ImeProxyAgentImeTest::SetUpTestCase"); + TddUtil::StorageSelfTokenID(); + TddUtil::InitWindow(false); + imc_ = InputMethodController::GetInstance(); + RegisterImeSettingListener(); + // native sa permission + TddUtil::GrantNativePermission(); + SystemConfig systemConfig; + SysCfgParser::ParseSystemConfig(systemConfig); + isAgentFeatureEnabled_ = systemConfig.enableAppAgentFeature; + if (isAgentFeatureEnabled_) { + if (systemConfig.proxyImeUidList.empty()) { + isAgentFeatureEnabled_ = false; + } + for (auto id : systemConfig.proxyImeUidList) { + agentUid_ = id; + } + } + } + static void TearDownTestCase(void) + { + IMSA_HILOGI("ImeProxyAgentImeTest::TearDownTestCase"); + TddUtil::DestroyWindow(); + TddUtil::RestoreSelfTokenID(); + TddUtil::KillImsaProcess(); + } + void SetUp() + { + IMSA_HILOGI("ImeProxyAgentImeTest::SetUp"); + InputMethodAbilityInterface::GetInstance().SetImeListener(std::make_shared()); + InputMethodAbilityInterface::GetInstance().SetKdListener(std::make_shared()); + TaskManager::GetInstance().SetInited(true); + } + void TearDown() + { + IMSA_HILOGI("InputMethodAbilityTest::TearDown"); + std::this_thread::sleep_for(std::chrono::seconds(1)); + TaskManager::GetInstance().Reset(); + } + + static int32_t Attach() + { + TextConfig config; + config.cursorInfo = { .left = 0, .top = 1, .width = 0.5, .height = 1.2 }; + sptr testListener = new TextListener(); + auto ret = imc_->Attach(testListener, true, config); + return ret; + } + + static void Close() + { + imc_->Close(); + } + +private: + static void RegisterImeSettingListener() + { + TddUtil::StorageSelfTokenID(); + TddUtil::SetTestTokenID(TddUtil::AllocTestTokenID(true, "ImeProxyAgentImeTest")); + auto listener = std::make_shared(); + ImeEventMonitorManagerImpl::GetInstance().RegisterImeEventListener( + EVENT_IME_HIDE_MASK | EVENT_IME_SHOW_MASK | EVENT_IME_CHANGE_MASK, listener); + TddUtil::RestoreSelfTokenID(); + } +}; +sptr ImeProxyAgentImeTest::imc_; +bool ImeProxyAgentImeTest::isAgentFeatureEnabled_{ false }; +int32_t ImeProxyAgentImeTest::agentUid_{ INVALID_UID }; + +/** + * @tc.name: testRegisterProxyIme_001 + * @tc.desc: agent feature enalbed, invalid uid + * @tc.type: FUNC + */ +HWTEST_F(ImeProxyAgentImeTest, testRegisterProxyIme_001, TestSize.Level1) +{ + IMSA_HILOGI("ImeProxyAgentImeTest::testRegisterProxyIme_001 start"); + if (!ImeProxyAgentImeTest::isAgentFeatureEnabled_) { + EXPECT_EQ(ImeProxyAgentImeTest::agentUid_, INVALID_UID); + } else { + auto ret = InputMethodAbilityInterface::GetInstance().RegisterProxyIme(AGENT_IME_DISPLAY_ID); + EXPECT_EQ(ret, ErrorCode::ERROR_NOT_AI_APP_IME); + InputMethodAbilityInterface::GetInstance().UnregisterProxyIme(AGENT_IME_DISPLAY_ID); + EXPECT_EQ(ret, ErrorCode::ERROR_NOT_AI_APP_IME); + } +} + +/** + * @tc.name: testRegisterProxyIme_002 + * @tc.desc: agent feature enabled, valid uid + * @tc.type: FUNC + */ +HWTEST_F(ImeProxyAgentImeTest, testRegisterProxyIme_002, TestSize.Level1) +{ + IMSA_HILOGI("ImeProxyAgentImeTest::testRegisterProxyIme_002 start"); + if (!ImeProxyAgentImeTest::isAgentFeatureEnabled_) { + EXPECT_EQ(ImeProxyAgentImeTest::agentUid_, INVALID_UID); + } else { + UidScope scope(ImeProxyAgentImeTest::agentUid_); + auto ret = InputMethodAbilityInterface::GetInstance().RegisterProxyIme(AGENT_IME_DISPLAY_ID); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + ret = InputMethodAbilityInterface::GetInstance().UnregisterProxyIme(AGENT_IME_DISPLAY_ID); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + } +} +} // namespace MiscServices +} // namespace OHOS