diff --git a/frameworks/native/inputmethod_controller/src/input_method_controller.cpp b/frameworks/native/inputmethod_controller/src/input_method_controller.cpp index 6af5f94bd4273b4da279cf269fd4e7c9baec6fd0..474af1d0ceff1fba1ce92303dc6af09d009d7fd3 100644 --- a/frameworks/native/inputmethod_controller/src/input_method_controller.cpp +++ b/frameworks/native/inputmethod_controller/src/input_method_controller.cpp @@ -647,10 +647,13 @@ void InputMethodController::RestoreClientInfoInSaDied() { std::lock_guard lock(textConfigLock_); tempConfig = textConfig_; - tempConfig.cursorInfo = cursorInfo_; tempConfig.range.start = selectNewBegin_; tempConfig.range.end = selectNewEnd_; } + { + std::lock_guard lk(cursorInfoMutex_); + tempConfig.cursorInfo = cursorInfo_; + } auto listener = GetTextListener(); bool isShowKeyboard = false; { @@ -723,15 +726,18 @@ int32_t InputMethodController::OnSelectionChange(std::u16string text, int start, std::lock_guard lock(textConfigLock_); textConfig_.range = { start, end }; } - if (textString_ == text && selectNewBegin_ == start && selectNewEnd_ == end) { - IMSA_HILOGD("same to last update."); - return ErrorCode::NO_ERROR; + { + std::lock_guard lock(editorContentLock_); + if (textString_ == text && selectNewBegin_ == start && selectNewEnd_ == end) { + IMSA_HILOGD("same to last update."); + return ErrorCode::NO_ERROR; + } + textString_ = text; + selectOldBegin_ = selectNewBegin_; + selectOldEnd_ = selectNewEnd_; + selectNewBegin_ = start; + selectNewEnd_ = end; } - textString_ = text; - selectOldBegin_ = selectNewBegin_; - selectOldEnd_ = selectNewEnd_; - selectNewBegin_ = start; - selectNewEnd_ = end; auto agent = GetAgent(); if (agent == nullptr) { IMSA_HILOGE("agent is nullptr!"); @@ -739,7 +745,7 @@ int32_t InputMethodController::OnSelectionChange(std::u16string text, int start, } IMSA_HILOGI("IMC size: %{public}zu, range: %{public}d/%{public}d/%{public}d/%{public}d.", text.size(), selectOldBegin_, selectOldEnd_, start, end); - agent->OnSelectionChange(textString_, selectOldBegin_, selectOldEnd_, selectNewBegin_, selectNewEnd_); + agent->OnSelectionChange(text, selectOldBegin_, selectOldEnd_, selectNewBegin_, selectNewEnd_); return ErrorCode::NO_ERROR; } 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 7588678617083fbd13aabcd600064674ebb4720f..3cef500ba77fdde675daa34ff6a4ad5c59027219 100644 --- a/test/unittest/cpp_test/src/input_method_controller_test.cpp +++ b/test/unittest/cpp_test/src/input_method_controller_test.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -64,6 +65,7 @@ #include "identity_checker_mock.h" using namespace testing; using namespace testing::ext; +using namespace testing::mt; namespace OHOS { namespace MiscServices { constexpr uint32_t RETRY_TIME = 200 * 1000; @@ -128,6 +130,7 @@ public: static bool WaitKeyEventCallback(); static void CheckTextConfig(const TextConfig &config); static void ResetKeyboardListenerTextConfig(); + static void EditorContentMultiTest(); static sptr inputMethodController_; static sptr inputMethodAbility_; static sptr imsa_; @@ -159,6 +162,9 @@ public: static constexpr uint32_t DELAY_TIME = 1; static constexpr uint32_t KEY_EVENT_DELAY_TIME = 100; static constexpr int32_t TASK_DELAY_TIME = 10; + static constexpr int32_t EACH_THREAD_CIRCULATION_TIME = 100; + static constexpr int32_t THREAD_NUM = 5; + static int32_t multiThreadExecTotalNum_; class KeyboardListenerImpl : public KeyboardListener { public: @@ -256,6 +262,7 @@ std::condition_variable InputMethodControllerTest::keyboardListenerCv_; sptr InputMethodControllerTest::deathRecipient_; std::mutex InputMethodControllerTest::onRemoteSaDiedMutex_; std::condition_variable InputMethodControllerTest::onRemoteSaDiedCv_; +int32_t InputMethodControllerTest::multiThreadExecTotalNum_{ 0 }; BlockData> InputMethodControllerTest::blockKeyEvent_{ InputMethodControllerTest::KEY_EVENT_DELAY_TIME, nullptr }; @@ -512,6 +519,20 @@ void InputMethodControllerTest::ResetKeyboardListenerTextConfig() inputAttribute_ = {}; } +void InputMethodControllerTest::EditorContentMultiTest() +{ + for (int32_t i = 0; i < EACH_THREAD_CIRCULATION_TIME; i++) { + InputAttribute inputAttribute = { .isTextPreviewSupported = true }; + inputMethodController_->Attach(textListener_, false, inputAttribute); + std::u16string text = Str8ToStr16("testSelect"); + int start = 1; + int end = 2; + inputMethodController_->OnSelectionChange(text, start, end); + inputMethodController_->OnInputStop(); + multiThreadExecTotalNum_++; + } +} + /** * @tc.name: testIMCAttach001 * @tc.desc: IMC Attach. @@ -1683,5 +1704,19 @@ HWTEST_F(InputMethodControllerTest, testOnInputReady, TestSize.Level0) inputMethodController_->DeactivateClient(); EXPECT_FALSE(TextListener::isFinishTextPreviewCalled_); } + +/** + * @tc.name: TestEditorContentLock + * @tc.desc: Test editorContentLock_ + * @tc.type: FUNC + */ +HWTEST_F(InputMethodControllerTest, TestEditorContentLock, TestSize.Level0) +{ + IMSA_HILOGI("InputMethodControllerTest::TestEditorContentLock START"); + multiThreadExecTotalNum_ = 0; + SET_THREAD_NUM(InputMethodControllerTest::THREAD_NUM); + GTEST_RUN_TASK(InputMethodControllerTest::EditorContentMultiTest); + EXPECT_EQ(multiThreadExecTotalNum_, THREAD_NUM * EACH_THREAD_CIRCULATION_TIME); +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file