1 /* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #define private public 16 #define protected public 17 #include "input_method_controller.h" 18 #undef private 19 #include <gtest/gtest.h> 20 #include <gtest/hwext/gtest-multithread.h> 21 #include <string_ex.h> 22 #include <unistd.h> 23 24 #include "global.h" 25 #include "ime_event_listener.h" 26 #include "ime_setting_listener_test_impl.h" 27 #include "ime_system_channel.h" 28 #include "input_method_engine_listener.h" 29 #include "input_method_utils.h" 30 31 using namespace testing; 32 using namespace testing::ext; 33 using namespace testing::mt; 34 namespace OHOS { 35 namespace MiscServices { 36 constexpr int32_t GET_INDEX = 0; 37 constexpr const char *GET_TEXT = "test"; 38 /** 39 * @brief Only pure virtual functions are implemented. 40 */ 41 class TextListenerImpl : public OnTextChangedListener { 42 public: InsertText(const std::u16string & text)43 void InsertText(const std::u16string &text) override { } DeleteForward(int32_t length)44 void DeleteForward(int32_t length) override { } DeleteBackward(int32_t length)45 void DeleteBackward(int32_t length) override { } SendKeyEventFromInputMethod(const KeyEvent & event)46 void SendKeyEventFromInputMethod(const KeyEvent &event) override { } SendKeyboardStatus(const KeyboardStatus & keyboardStatus)47 void SendKeyboardStatus(const KeyboardStatus &keyboardStatus) override { } SendFunctionKey(const FunctionKey & functionKey)48 void SendFunctionKey(const FunctionKey &functionKey) override { } SetKeyboardStatus(bool status)49 void SetKeyboardStatus(bool status) override { } MoveCursor(const Direction direction)50 void MoveCursor(const Direction direction) override { } HandleSetSelection(int32_t start,int32_t end)51 void HandleSetSelection(int32_t start, int32_t end) override { } HandleExtendAction(int32_t action)52 void HandleExtendAction(int32_t action) override { } HandleSelect(int32_t keyCode,int32_t cursorMoveSkip)53 void HandleSelect(int32_t keyCode, int32_t cursorMoveSkip) override { } GetLeftTextOfCursor(int32_t number)54 std::u16string GetLeftTextOfCursor(int32_t number) override 55 { 56 return Str8ToStr16(GET_TEXT); 57 } GetRightTextOfCursor(int32_t number)58 std::u16string GetRightTextOfCursor(int32_t number) override 59 { 60 return Str8ToStr16(GET_TEXT); 61 } GetTextIndexAtCursor()62 int32_t GetTextIndexAtCursor() override 63 { 64 return GET_INDEX; 65 } 66 }; 67 68 class EventHandlerTextListenerImpl : public TextListenerImpl { 69 public: EventHandlerTextListenerImpl(const std::shared_ptr<AppExecFwk::EventHandler> & handler)70 explicit EventHandlerTextListenerImpl(const std::shared_ptr<AppExecFwk::EventHandler> &handler) 71 { 72 listenerEventHandler_ = handler; 73 } GetEventHandler()74 std::shared_ptr<AppExecFwk::EventHandler> GetEventHandler() 75 { 76 return listenerEventHandler_; 77 } 78 79 private: 80 std::shared_ptr<AppExecFwk::EventHandler> listenerEventHandler_{ nullptr }; 81 }; 82 /** 83 * @brief Only pure virtual functions are implemented. 84 */ 85 class EngineListenerImpl : public InputMethodEngineListener { 86 public: OnKeyboardStatus(bool isShow)87 void OnKeyboardStatus(bool isShow) override { } OnInputStart()88 void OnInputStart() override { } OnInputStop()89 int32_t OnInputStop() override 90 { 91 return ErrorCode::NO_ERROR; 92 } OnSecurityChange(int32_t security)93 void OnSecurityChange(int32_t security) override { } OnSetCallingWindow(uint32_t windowId)94 void OnSetCallingWindow(uint32_t windowId) override { } OnSetSubtype(const SubProperty & property)95 void OnSetSubtype(const SubProperty &property) override { } ReceivePrivateCommand(const std::unordered_map<std::string,PrivateDataValue> & privateCommand)96 void ReceivePrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand) override { } 97 }; 98 /** 99 * @brief Only pure virtual functions are implemented. 100 */ 101 class EventListenerImpl : public ImeEventListener { }; 102 /** 103 * @brief Only pure virtual functions are implemented. 104 */ 105 class SystemCmdChannelImpl : public OnSystemCmdListener { }; 106 107 class SystemCmdChannelListenerImpl : public OnSystemCmdListener { 108 public: ReceivePrivateCommand(const std::unordered_map<std::string,PrivateDataValue> & privateCommand)109 void ReceivePrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand) override 110 { 111 isReceivePrivateCommand_ = true; 112 } NotifyPanelStatus(const SysPanelStatus & sysPanelStatus)113 void NotifyPanelStatus(const SysPanelStatus &sysPanelStatus) override 114 { 115 isNotifyIsShowSysPanel_ = true; 116 } ResetParam()117 static void ResetParam() 118 { 119 isReceivePrivateCommand_ = false; 120 isNotifyIsShowSysPanel_ = false; 121 } 122 static bool isReceivePrivateCommand_; 123 static bool isNotifyIsShowSysPanel_; 124 }; 125 bool SystemCmdChannelListenerImpl::isReceivePrivateCommand_ { false }; 126 bool SystemCmdChannelListenerImpl::isNotifyIsShowSysPanel_ { false }; 127 128 class VirtualListenerTest : public testing::Test { 129 public: 130 static constexpr int32_t EACH_THREAD_CIRCULATION_TIME = 100; SetUpTestCase(void)131 static void SetUpTestCase(void) 132 { 133 IMSA_HILOGI("VirtualListenerTest::SetUpTestCase"); 134 textListener_ = new (std::nothrow) TextListenerImpl(); 135 std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create("eventHandlerTextListener"); 136 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner); 137 eventHandlerTextListener_ = new (std::nothrow) EventHandlerTextListenerImpl(eventHandler_); 138 eventListener_ = std::make_shared<EventListenerImpl>(); 139 engineListener_ = std::make_shared<EngineListenerImpl>(); 140 systemCmdListener_ = new (std::nothrow) SystemCmdChannelImpl(); 141 } TearDownTestCase(void)142 static void TearDownTestCase(void) 143 { 144 IMSA_HILOGI("VirtualListenerTest::TearDownTestCase"); 145 } SetUp()146 void SetUp() 147 { 148 IMSA_HILOGI("VirtualListenerTest::SetUp"); 149 } TearDown()150 void TearDown() 151 { 152 eventHandlerTextListener_ = new (std::nothrow) EventHandlerTextListenerImpl(eventHandler_); 153 IMSA_HILOGI("VirtualListenerTest::TearDown"); 154 } 155 GetEventHandlerTextListener()156 static sptr<OnTextChangedListener> GetEventHandlerTextListener() 157 { 158 std::lock_guard<std::mutex>lock(eventHandlerTextListenerLock_); 159 eventHandlerTextListener_ = new (std::nothrow) EventHandlerTextListenerImpl(eventHandler_); 160 return eventHandlerTextListener_; 161 } 162 ClearEventHandlerTextListener()163 static void ClearEventHandlerTextListener() 164 { 165 std::lock_guard<std::mutex>lock(eventHandlerTextListenerLock_); 166 eventHandlerTextListener_ = nullptr; 167 } 168 TextListenerMultiThreadTest1()169 static void TextListenerMultiThreadTest1() 170 { 171 for (int32_t i = 0; i < EACH_THREAD_CIRCULATION_TIME; i++) { 172 auto listener = GetEventHandlerTextListener(); 173 ASSERT_NE(listener, nullptr); 174 listener->InsertTextV2(u""); 175 int32_t length = 1; 176 listener->DeleteForwardV2(length); 177 listener->DeleteBackwardV2(length); 178 listener->SendKeyboardStatusV2(KeyboardStatus::SHOW); 179 FunctionKey key; 180 listener->SendFunctionKeyV2(key); 181 listener->MoveCursorV2(Direction::DOWN); 182 listener->HandleExtendActionV2(0); 183 listener->GetLeftTextOfCursorV2(length); 184 listener->GetRightTextOfCursorV2(length); 185 listener->GetTextIndexAtCursorV2(); 186 KeyEvent keyEvent; 187 listener->SendKeyEventFromInputMethodV2(keyEvent); 188 listener->SetKeyboardStatusV2(true); 189 ClearEventHandlerTextListener(); 190 } 191 } 192 TextListenerMultiThreadTest2()193 static void TextListenerMultiThreadTest2() 194 { 195 for (int32_t i = 0; i < EACH_THREAD_CIRCULATION_TIME; i++) { 196 auto listener = GetEventHandlerTextListener(); 197 ASSERT_NE(listener, nullptr); 198 int32_t start = 1; 199 int32_t end = 1; 200 listener->HandleSetSelectionV2(start, end); 201 int32_t keyCode = 1; 202 int32_t cursorMoveSkip = 1; 203 listener->HandleSelectV2(keyCode, cursorMoveSkip); 204 listener->OnDetachV2(); 205 PanelStatusInfo statusInfo; 206 Range range; 207 std::unordered_map<std::string, PrivateDataValue> privateCommand; 208 listener->NotifyPanelStatusInfoV2(statusInfo); 209 listener->NotifyKeyboardHeightV2(0); 210 listener->ReceivePrivateCommandV2(privateCommand); 211 listener->FinishTextPreviewV2(); 212 listener->SetPreviewTextV2(Str8ToStr16("test"), range); 213 ClearEventHandlerTextListener(); 214 } 215 } 216 static sptr<OnTextChangedListener> textListener_; 217 static std::shared_ptr<AppExecFwk::EventHandler> eventHandler_; 218 static std::mutex eventHandlerTextListenerLock_; 219 static sptr<OnTextChangedListener> eventHandlerTextListener_; 220 static std::shared_ptr<ImeEventListener> eventListener_; 221 static std::shared_ptr<InputMethodEngineListener> engineListener_; 222 static sptr<OnSystemCmdListener> systemCmdListener_; 223 }; 224 sptr<OnTextChangedListener> VirtualListenerTest::textListener_{ nullptr }; 225 std::shared_ptr<AppExecFwk::EventHandler> VirtualListenerTest::eventHandler_{ nullptr }; 226 std::mutex VirtualListenerTest::eventHandlerTextListenerLock_; 227 sptr<OnTextChangedListener> VirtualListenerTest::eventHandlerTextListener_{ nullptr }; 228 std::shared_ptr<ImeEventListener> VirtualListenerTest::eventListener_{ nullptr }; 229 std::shared_ptr<InputMethodEngineListener> VirtualListenerTest::engineListener_{ nullptr }; 230 sptr<OnSystemCmdListener> VirtualListenerTest::systemCmdListener_{ nullptr }; 231 232 /** 233 * @tc.name: testOnTextChangedListener_001 234 * @tc.desc: Cover non-pure virtual function in class: OnTextChangedListener. 235 * @tc.type: FUNC 236 * @tc.require: 237 */ 238 HWTEST_F(VirtualListenerTest, testOnTextChangedListener_001, TestSize.Level1) 239 { 240 IMSA_HILOGI("VirtualListenerTest testOnTextChangedListener_001 START"); 241 ASSERT_NE(VirtualListenerTest::textListener_, nullptr); 242 KeyEvent keyEvent; 243 VirtualListenerTest::textListener_->SendKeyEventFromInputMethodV2(keyEvent); 244 VirtualListenerTest::textListener_->SetKeyboardStatusV2(true); 245 PanelStatusInfo statusInfo; 246 Range range; 247 std::unordered_map<std::string, PrivateDataValue> privateCommand; 248 VirtualListenerTest::textListener_->NotifyPanelStatusInfo(statusInfo); 249 VirtualListenerTest::textListener_->NotifyKeyboardHeight(0); 250 int32_t ret = VirtualListenerTest::textListener_->ReceivePrivateCommand(privateCommand); 251 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 252 VirtualListenerTest::textListener_->FinishTextPreview(); 253 ret = VirtualListenerTest::textListener_->SetPreviewText(Str8ToStr16("test"), range); 254 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 255 } 256 257 /** 258 * @tc.name: testOnTextChangedListener_002 259 * @tc.desc: has eventHandler. 260 * @tc.type: FUNC 261 * @tc.require: 262 */ 263 HWTEST_F(VirtualListenerTest, testOnTextChangedListener_002, TestSize.Level1) 264 { 265 IMSA_HILOGI("VirtualListenerTest testOnTextChangedListener_002 START"); 266 ASSERT_NE(VirtualListenerTest::eventHandlerTextListener_, nullptr); 267 VirtualListenerTest::eventHandlerTextListener_->InsertTextV2(u""); 268 int32_t length = 1; 269 VirtualListenerTest::eventHandlerTextListener_->DeleteForwardV2(length); 270 VirtualListenerTest::eventHandlerTextListener_->DeleteBackwardV2(length); 271 VirtualListenerTest::eventHandlerTextListener_->SendKeyboardStatusV2(KeyboardStatus::SHOW); 272 FunctionKey key; 273 VirtualListenerTest::eventHandlerTextListener_->SendFunctionKeyV2(key); 274 VirtualListenerTest::eventHandlerTextListener_->MoveCursorV2(Direction::DOWN); 275 VirtualListenerTest::eventHandlerTextListener_->HandleExtendActionV2(0); 276 auto text = VirtualListenerTest::eventHandlerTextListener_->GetLeftTextOfCursorV2(length); 277 EXPECT_EQ(text, Str8ToStr16(GET_TEXT)); 278 auto text1 = VirtualListenerTest::eventHandlerTextListener_->GetRightTextOfCursorV2(length); 279 EXPECT_EQ(text1, Str8ToStr16(GET_TEXT)); 280 auto index = VirtualListenerTest::eventHandlerTextListener_->GetTextIndexAtCursorV2(); 281 EXPECT_EQ(index, GET_INDEX); 282 KeyEvent keyEvent; 283 VirtualListenerTest::eventHandlerTextListener_->SendKeyEventFromInputMethodV2(keyEvent); 284 VirtualListenerTest::eventHandlerTextListener_->SetKeyboardStatusV2(true); 285 int32_t start = 1; 286 int32_t end = 1; 287 VirtualListenerTest::eventHandlerTextListener_->HandleSetSelectionV2(start, end); 288 int32_t keyCode = 1; 289 int32_t cursorMoveSkip = 1; 290 VirtualListenerTest::eventHandlerTextListener_->HandleSelectV2(keyCode, cursorMoveSkip); 291 VirtualListenerTest::eventHandlerTextListener_->OnDetachV2(); 292 PanelStatusInfo statusInfo; 293 Range range; 294 std::unordered_map<std::string, PrivateDataValue> privateCommand; 295 VirtualListenerTest::eventHandlerTextListener_->NotifyPanelStatusInfoV2(statusInfo); 296 VirtualListenerTest::eventHandlerTextListener_->NotifyKeyboardHeightV2(0); 297 int32_t ret = VirtualListenerTest::eventHandlerTextListener_->ReceivePrivateCommandV2(privateCommand); 298 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 299 VirtualListenerTest::eventHandlerTextListener_->FinishTextPreviewV2(); 300 ret = VirtualListenerTest::eventHandlerTextListener_->SetPreviewTextV2(Str8ToStr16("test"), range); 301 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 302 } 303 304 /** 305 * @tc.name: testOnTextChangedListener_003 306 * @tc.desc: multi thread 307 * @tc.type: FUNC 308 * @tc.require: 309 * @tc.author: chenyu 310 */ 311 HWTEST_F(VirtualListenerTest, testOnTextChangedListener_003, TestSize.Level1) 312 { 313 IMSA_HILOGI("VirtualListenerTest testOnTextChangedListener_003 START"); 314 SET_THREAD_NUM(5); 315 GTEST_RUN_TASK(TextListenerMultiThreadTest1); 316 } 317 318 /** 319 * @tc.name: testOnTextChangedListener_004 320 * @tc.desc: multi thread 321 * @tc.type: FUNC 322 * @tc.require: 323 * @tc.author: chenyu 324 */ 325 HWTEST_F(VirtualListenerTest, testOnTextChangedListener_004, TestSize.Level1) 326 { 327 IMSA_HILOGI("VirtualListenerTest testOnTextChangedListener_004 START"); 328 SET_THREAD_NUM(5); 329 GTEST_RUN_TASK(TextListenerMultiThreadTest2); 330 } 331 332 /** 333 * @tc.name: testInputMethodEngineListener_001 334 * @tc.desc: Cover non-pure virtual function in class: InputMethodEngineListener. 335 * @tc.type: FUNC 336 * @tc.require: 337 */ 338 HWTEST_F(VirtualListenerTest, testInputMethodEngineListener_001, TestSize.Level1) 339 { 340 IMSA_HILOGI("VirtualListenerTest testInputMethodEngineListener_001 START"); 341 ASSERT_NE(VirtualListenerTest::engineListener_, nullptr); 342 VirtualListenerTest::engineListener_->OnInputFinish(); 343 bool isEnable = VirtualListenerTest::engineListener_->IsEnable(); 344 EXPECT_FALSE(isEnable); 345 } 346 347 /** 348 * @tc.name: testInputMethodEngineListener_002 349 * @tc.desc: Cover non-pure virtual function in class: InputMethodEngineListener. 350 * @tc.type: FUNC 351 * @tc.require: 352 */ 353 HWTEST_F(VirtualListenerTest, testInputMethodEngineListener_002, TestSize.Level1) 354 { 355 IMSA_HILOGI("VirtualListenerTest testInputMethodEngineListener_002 START"); 356 ASSERT_NE(VirtualListenerTest::engineListener_, nullptr); 357 int32_t security = 1; 358 VirtualListenerTest::engineListener_->OnSecurityChange(security); 359 bool isEnable = VirtualListenerTest::engineListener_->IsEnable(); 360 EXPECT_FALSE(isEnable); 361 } 362 363 /** 364 * @tc.name: testImeEventListener_001 365 * @tc.desc: Cover non-pure virtual function in class: ImeEventListener. 366 * @tc.type: FUNC 367 * @tc.require: 368 */ 369 HWTEST_F(VirtualListenerTest, testImeEventListener_001, TestSize.Level1) 370 { 371 IMSA_HILOGI("VirtualListenerTest testImeEventListener_001 START"); 372 ASSERT_NE(VirtualListenerTest::eventListener_, nullptr); 373 Property property; 374 SubProperty subProperty; 375 ImeWindowInfo imeWindowInfo; 376 auto listener = std::make_shared<ImeSettingListenerTestImpl>(); 377 ImeSettingListenerTestImpl::ResetParam(); 378 VirtualListenerTest::eventListener_->OnImeChange(property, subProperty); 379 VirtualListenerTest::eventListener_->OnImeShow(imeWindowInfo); 380 VirtualListenerTest::eventListener_->OnImeHide(imeWindowInfo); 381 EXPECT_FALSE(ImeSettingListenerTestImpl::WaitImeChange()); 382 EXPECT_FALSE(ImeSettingListenerTestImpl::WaitPanelHide()); 383 EXPECT_FALSE(ImeSettingListenerTestImpl::WaitPanelHide()); 384 } 385 386 /** 387 * @tc.name: testOnSystemCmdListener_001 388 * @tc.desc: Cover non-pure virtual function in class: OnSystemCmdListener. 389 * @tc.type: FUNC 390 * @tc.require: 391 */ 392 HWTEST_F(VirtualListenerTest, testOnSystemCmdListener_001, TestSize.Level1) 393 { 394 IMSA_HILOGI("VirtualListenerTest testOnSystemCmdListener_001 START"); 395 sptr<OnSystemCmdListener> listener = new (std::nothrow) SystemCmdChannelListenerImpl(); 396 ASSERT_NE(listener, nullptr); 397 ASSERT_NE(VirtualListenerTest::systemCmdListener_, nullptr); 398 SystemCmdChannelListenerImpl::ResetParam(); 399 std::unordered_map<std::string, PrivateDataValue> privateCommand; 400 VirtualListenerTest::systemCmdListener_->ReceivePrivateCommand(privateCommand); 401 VirtualListenerTest::systemCmdListener_->NotifyPanelStatus({ InputType::NONE, 0, 0, 0 }); 402 EXPECT_FALSE(SystemCmdChannelListenerImpl::isNotifyIsShowSysPanel_); 403 EXPECT_FALSE(SystemCmdChannelListenerImpl::isReceivePrivateCommand_); 404 SystemCmdChannelListenerImpl::ResetParam(); 405 listener->ReceivePrivateCommand(privateCommand); 406 listener->NotifyPanelStatus({ InputType::NONE, 0, 0, 0 }); 407 EXPECT_TRUE(SystemCmdChannelListenerImpl::isNotifyIsShowSysPanel_); 408 EXPECT_TRUE(SystemCmdChannelListenerImpl::isReceivePrivateCommand_); 409 } 410 } // namespace MiscServices 411 } // namespace OHOS