From f75d22bd4056d9a639be66924ba66da6769feb4c Mon Sep 17 00:00:00 2001 From: shiyu-shiyu Date: Tue, 19 Aug 2025 11:29:44 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=89=E6=96=B9=E8=BE=93=E5=85=A5=E6=B3=95?= =?UTF-8?q?=E5=9C=A8=E5=A4=A7=E6=A1=8C=E9=9D=A2=E6=8B=89=E8=B5=B7=E6=8B=8D?= =?UTF-8?q?=E6=91=84=E8=BE=93=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: shiyu-shiyu --- .../include/input_method_ability.h | 2 +- .../src/input_method_ability.cpp | 10 +- .../IInputMethodSystemAbility.idl | 1 + .../src/input_method_controller.cpp | 11 +++ .../include/input_method_controller.h | 11 +++ .../include/input_method_system_ability.h | 1 + services/src/input_method_system_ability.cpp | 5 + .../src/input_method_ability_test.cpp | 96 +++++++++++++++++++ .../src/input_method_controller_test.cpp | 14 +++ .../src/input_method_private_member_test.cpp | 16 ++++ 10 files changed, 161 insertions(+), 6 deletions(-) diff --git a/frameworks/native/inputmethod_ability/include/input_method_ability.h b/frameworks/native/inputmethod_ability/include/input_method_ability.h index e69116c88..4c2860c69 100644 --- a/frameworks/native/inputmethod_ability/include/input_method_ability.h +++ b/frameworks/native/inputmethod_ability/include/input_method_ability.h @@ -233,7 +233,7 @@ private: std::mutex inputTypeLock_; InputType inputType_ = InputType::NONE; - std::atomic isImeTerminating = false; + std::atomic isImeTerminating_ = false; std::atomic_bool isShowAfterCreate_ { false }; std::atomic securityMode_ = -1; std::mutex msgHandlerMutex_; diff --git a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp index 3b364924e..e5fa4e49e 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp @@ -331,7 +331,7 @@ int32_t InputMethodAbility::StartInputInner(const InputClientInfo &clientInfo, b } ReportImeStartInput( static_cast(IInputMethodCoreIpcCode::COMMAND_START_INPUT), ret, needShow, endTime - startTime); - isImeTerminating.store(false); + isImeTerminating_.store(false); }; uint64_t seqId = Task::GetNextSeqId(); if (imeListener_ == nullptr || @@ -525,7 +525,7 @@ int32_t InputMethodAbility::OnStopInputService(bool isTerminateIme) return ErrorCode::ERROR_IME_NOT_STARTED; } if (isTerminateIme) { - isImeTerminating.store(true); + isImeTerminating_.store(true); return imeListener->OnInputStop(); } return ErrorCode::NO_ERROR; @@ -770,7 +770,7 @@ int32_t InputMethodAbility::SendFunctionKey(int32_t funcKey, const AsyncIpcCallB int32_t InputMethodAbility::HideKeyboardSelf() { // Current Ime is exiting, hide softkeyboard will cause the TextFiled to lose focus. - if (isImeTerminating.load()) { + if (isImeTerminating_.load()) { IMSA_HILOGI("Current Ime is terminating, no need to hide keyboard."); return ErrorCode::NO_ERROR; } @@ -1180,7 +1180,7 @@ int32_t InputMethodAbility::HidePanel(const std::shared_ptr &i return ErrorCode::ERROR_BAD_PARAMETERS; } // Current Ime is exiting, hide softkeyboard will cause the TextFiled to lose focus. - if (isImeTerminating.load() && inputMethodPanel->GetPanelType() == PanelType::SOFT_KEYBOARD) { + if (isImeTerminating_.load() && inputMethodPanel->GetPanelType() == PanelType::SOFT_KEYBOARD) { IMSA_HILOGI("Current Ime is terminating, no need to hide keyboard."); return ErrorCode::NO_ERROR; } @@ -1641,7 +1641,7 @@ void InputMethodAbility::NotifyPanelStatusInfo( } auto controlChannel = GetInputControlChannel(); - if (controlChannel != nullptr && info.trigger == Trigger::IME_APP && !info.visible) { + if (controlChannel != nullptr && info.trigger == Trigger::IME_APP && !info.visible && !isImeTerminating_.load()) { controlChannel->HideKeyboardSelf(); } } diff --git a/frameworks/native/inputmethod_controller/IInputMethodSystemAbility.idl b/frameworks/native/inputmethod_controller/IInputMethodSystemAbility.idl index 28f1b43b4..3b314a8d2 100644 --- a/frameworks/native/inputmethod_controller/IInputMethodSystemAbility.idl +++ b/frameworks/native/inputmethod_controller/IInputMethodSystemAbility.idl @@ -52,6 +52,7 @@ interface OHOS.MiscServices.IInputMethodSystemAbility { void IsInputTypeSupported([in] int type, [out] boolean resultValue); void IsCurrentImeByPid([in] int pid, [out] boolean resultValue); void StartInputType([in] int type); + [oneway] void StartInputTypeAsync([in] int type); void ExitCurrentInputType(); void IsPanelShown([in] PanelInfo panelInfo, [out] boolean isShown); void GetSecurityMode([out] int security); diff --git a/frameworks/native/inputmethod_controller/src/input_method_controller.cpp b/frameworks/native/inputmethod_controller/src/input_method_controller.cpp index d8408fcbe..202ef673c 100644 --- a/frameworks/native/inputmethod_controller/src/input_method_controller.cpp +++ b/frameworks/native/inputmethod_controller/src/input_method_controller.cpp @@ -1541,6 +1541,17 @@ int32_t InputMethodController::StartInputType(InputType type) return proxy->StartInputType(static_cast(type)); } +int32_t InputMethodController::StartInputTypeAsync(InputType type) +{ + auto proxy = GetSystemAbilityProxy(); + if (proxy == nullptr) { + IMSA_HILOGE("proxy is nullptr!"); + return ErrorCode::ERROR_NULL_POINTER; + } + IMSA_HILOGI("type: %{public}d.", static_cast(type)); + return proxy->StartInputTypeAsync(static_cast(type)); +} + int32_t InputMethodController::IsPanelShown(const PanelInfo &panelInfo, bool &isShown) { auto proxy = GetSystemAbilityProxy(); diff --git a/interfaces/inner_api/inputmethod_controller/include/input_method_controller.h b/interfaces/inner_api/inputmethod_controller/include/input_method_controller.h index faf71602b..6f25f05b1 100644 --- a/interfaces/inner_api/inputmethod_controller/include/input_method_controller.h +++ b/interfaces/inner_api/inputmethod_controller/include/input_method_controller.h @@ -819,6 +819,17 @@ public: */ IMF_API int32_t StartInputType(InputType type); + /** + * @brief Start the input method which provides the specific input type. + * + * This function is used to start the input method which provides the specific input type. + * + * @param type Indicates the input type being specified. + * @return Returns 0 for success, others for failure. + * @since 21 + */ + IMF_API int32_t StartInputTypeAsync(InputType type); + /** * @brief Query whether the specific type panel is shown. * diff --git a/services/include/input_method_system_ability.h b/services/include/input_method_system_ability.h index 9ffe9e226..2df39bbdd 100644 --- a/services/include/input_method_system_ability.h +++ b/services/include/input_method_system_ability.h @@ -73,6 +73,7 @@ public: ErrCode IsInputTypeSupported(int32_t type, bool& resultValue) override; ErrCode IsCurrentImeByPid(int32_t pid, bool& resultValue) override; ErrCode StartInputType(int32_t type) override; + ErrCode StartInputTypeAsync(int32_t type) override; ErrCode ExitCurrentInputType() override; ErrCode IsPanelShown(const PanelInfo &panelInfo, bool &isShown) override; ErrCode GetSecurityMode(int32_t &security) override; diff --git a/services/src/input_method_system_ability.cpp b/services/src/input_method_system_ability.cpp index 80a7380b0..af92b18f9 100644 --- a/services/src/input_method_system_ability.cpp +++ b/services/src/input_method_system_ability.cpp @@ -1101,6 +1101,11 @@ ErrCode InputMethodSystemAbility::StartInputType(int32_t type) return StartInputType(GetCallingUserId(), static_cast(type)); } +ErrCode InputMethodSystemAbility::StartInputTypeAsync(int32_t type) +{ + return StartInputType(GetCallingUserId(), static_cast(type)); +} + ErrCode InputMethodSystemAbility::ExitCurrentInputType() { auto userId = GetCallingUserId(); diff --git a/test/unittest/cpp_test/src/input_method_ability_test.cpp b/test/unittest/cpp_test/src/input_method_ability_test.cpp index 62c4a6924..6e8086070 100644 --- a/test/unittest/cpp_test/src/input_method_ability_test.cpp +++ b/test/unittest/cpp_test/src/input_method_ability_test.cpp @@ -1316,6 +1316,42 @@ HWTEST_F(InputMethodAbilityTest, testNotifyPanelStatusInfo_005, TestSize.Level0) EXPECT_EQ(ret, ErrorCode::NO_ERROR); } +/** + * @tc.name: testNotifyPanelStatusInfo_006 + * @tc.desc: HideKeyboardSelf + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenyu + */ +HWTEST_F(InputMethodAbilityTest, testNotifyPanelStatusInfo_006, TestSize.Level0) +{ + IMSA_HILOGI("InputMethodAbility testNotifyPanelStatusInfo_006 START"); + imc_->Attach(textListener_); + PanelInfo info; + info.panelType = SOFT_KEYBOARD; + info.panelFlag = FLG_CANDIDATE_COLUMN; + auto panel = std::make_shared(); + AccessScope scope(currentImeTokenId_, currentImeUid_); + auto ret = inputMethodAbility_.CreatePanel(nullptr, info, panel); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + PanelStatusInfo statusInfo; + statusInfo.panelInfo = info; + statusInfo.visible = true; + statusInfo.trigger = Trigger::IME_APP; + // ShowPanel + CheckPanelStatusInfo(panel, statusInfo); + PanelStatusInfo statusInfo1; + statusInfo1.panelInfo = info; + statusInfo1.visible = false; + statusInfo1.trigger = Trigger::IME_APP; + InputMethodAbilityTest::inputMethodAbility_.isImeTerminating_ = false; + // HidePanel + CheckPanelStatusInfo(panel, statusInfo1); + + ret = inputMethodAbility_.DestroyPanel(panel); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); +} + /** * @tc.name: testNotifyKeyboardHeight_001 * @tc.desc: NotifyKeyboardHeight SOFT_KEYBOARD FLG_FIXED @@ -2252,5 +2288,65 @@ HWTEST_F(InputMethodAbilityTest, testSelectByRange, TestSize.Level0) ret = InputMethodAbilityInterface::GetInstance().SelectByRange(start, end); EXPECT_EQ(ret, ErrorCode::ERROR_PARAMETER_CHECK_FAILED); } + +/** + *@tc.name: testOnStopInputService_001 + *@tc.desc: IMA + *@tc.type: FUNC + *@tc.require: + */ +HWTEST_F(InputMethodAbilityTest, testOnStopInputService_001, TestSize.Level0) +{ + IMSA_HILOGI("InputMethodAbilityTest OnStopInputService_001 Test START"); + InputMethodAbilityTest::inputMethodAbility_.isImeTerminating_ = false; + inputMethodAbility_.SetImeListener(std::make_shared()); + auto ret = InputMethodAbilityTest::inputMethodAbility_.OnStopInputService(false); + EXPECT_NE(true, InputMethodAbilityTest::inputMethodAbility_.isImeTerminating_); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + + ret = InputMethodAbilityTest::inputMethodAbility_.OnStopInputService(true); + EXPECT_EQ(true, InputMethodAbilityTest::inputMethodAbility_.isImeTerminating_); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); +} + +/** + * @tc.name: testHideKeyboardSelf_001 + * @tc.desc: InputMethodAbility HideKeyboardSelf + * @tc.type: FUNC + * @tc.require: + * @tc.author: Hollokin + */ +HWTEST_F(InputMethodAbilityTest, testHideKeyboardSelf_001, TestSize.Level0) +{ + IMSA_HILOGI("InputMethodAbility testHideKeyboardSelf_001 START"); + InputMethodAbilityTest::inputMethodAbility_.isImeTerminating_ = true; + auto ret = InputMethodAbilityTest::inputMethodAbility_.HideKeyboardSelf(); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); +} + +/** + * @tc.name: testHidePanel + * @tc.desc: InputMethodAbility HidePanel + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(InputMethodAbilityTest, testHidePanel, TestSize.Level0) +{ + IMSA_HILOGI("InputMethodAbility testHidePanel START"); + imc_->Attach(textListener_); + PanelInfo info1; + info1.panelType = SOFT_KEYBOARD; + info1.panelFlag = FLG_FLOATING; + AccessScope scope(currentImeTokenId_, currentImeUid_); + auto panel = std::make_shared(); + auto ret = inputMethodAbility_.CreatePanel(nullptr, info1, panel); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); + ret = InputMethodAbilityTest::inputMethodAbility_.HidePanel(nullptr); + EXPECT_EQ(ret, ErrorCode::ERROR_BAD_PARAMETERS); + + InputMethodAbilityTest::inputMethodAbility_.isImeTerminating_ = true; + ret = InputMethodAbilityTest::inputMethodAbility_.HidePanel(panel); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); +} } // namespace MiscServices } // namespace OHOS 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 d54d1b50e..baff5de30 100644 --- a/test/unittest/cpp_test/src/input_method_controller_test.cpp +++ b/test/unittest/cpp_test/src/input_method_controller_test.cpp @@ -1383,6 +1383,20 @@ HWTEST_F(InputMethodControllerTest, testStartInputType, TestSize.Level0) EXPECT_NE(ret, ErrorCode::NO_ERROR); } +/** + * @tc.name: testStartInputTypeAsync + * @tc.desc: StartInputTypeAsync + * @tc.type: FUNC + * @tc.require: + * @tc.author: chenyu + */ +HWTEST_F(InputMethodControllerTest, testStartInputTypeAsync, TestSize.Level0) +{ + IMSA_HILOGI("IMC testStartInputTypeAsync Test START"); + auto ret = inputMethodController_->StartInputTypeAsync(InputType::NONE); + EXPECT_EQ(ret, ErrorCode::NO_ERROR); +} + /** * @tc.name: testSendPrivateCommand_001 * @tc.desc: IMC SendPrivateCommand without default ime 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 a78ea4f90..b22bb83fa 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 @@ -1192,6 +1192,22 @@ HWTEST_F(InputMethodPrivateMemberTest, TestStartInputType, TestSize.Level0) EXPECT_NE(ret, ErrorCode::NO_ERROR); } +/** + * @tc.name: TestStartInputTypeAsync + * @tc.desc: Test StartInputTypeAsync + * @tc.type: FUNC + * @tc.require: issuesI794QF + */ +HWTEST_F(InputMethodPrivateMemberTest, TestStartInputTypeAsync, TestSize.Level0) +{ + IMSA_HILOGI("InputMethodPrivateMemberTest TestStartInputTypeAsync TEST START"); + InputType type = InputType::NONE; + auto ret = service_->StartInputTypeAsync(static_cast(type)); + EXPECT_NE(ret, ErrorCode::NO_ERROR); + ret = service_->StartInputTypeAsync(static_cast(InputType::VOICEKB_INPUT)); + EXPECT_NE(ret, ErrorCode::NO_ERROR); +} + /** * @tc.name: TestFullImeInfoManager_Update001 * @tc.desc: Test FullImeInfoManager_Update -- Gitee