1 /* 2 * Copyright (C) 2023 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 16 #define private public 17 #define protected public 18 #include "input_method_ability.h" 19 #include "input_method_controller.h" 20 #include "input_method_system_ability.h" 21 #include "task_manager.h" 22 #undef private 23 24 #include <gtest/gtest.h> 25 #include <gtest/hwext/gtest-multithread.h> 26 #include <string_ex.h> 27 28 #include "global.h" 29 #include "identity_checker_mock.h" 30 #include "input_attribute.h" 31 #include "input_method_engine_listener_impl.h" 32 #include "input_method_system_ability_proxy.h" 33 #include "input_method_system_ability_stub.h" 34 #include "keyboard_listener_test_impl.h" 35 #include "tdd_util.h" 36 #include "text_listener.h" 37 38 using namespace testing::ext; 39 namespace OHOS { 40 namespace MiscServices { 41 using namespace std::chrono; 42 using namespace testing::ext; 43 using namespace testing::mt; 44 class InputMethodAttachTest : public testing::Test { 45 public: 46 static sptr<InputMethodController> inputMethodController_; 47 static sptr<InputMethodAbility> inputMethodAbility_; 48 static sptr<InputMethodSystemAbilityProxy> imsaProxy_; 49 static sptr<InputMethodSystemAbility> imsa_; 50 static constexpr int32_t EACH_THREAD_CIRCULATION_TIME = 1000; 51 static constexpr int32_t MAX_WAIT_TIME = 5000; 52 static bool timeout_; 53 static std::shared_ptr<AppExecFwk::EventHandler> textConfigHandler_; 54 SetUpTestCase(void)55 static void SetUpTestCase(void) 56 { 57 IMSA_HILOGI("InputMethodAttachTest::SetUpTestCase"); 58 IdentityCheckerMock::ResetParam(); 59 imsa_ = new (std::nothrow) InputMethodSystemAbility(); 60 if (imsa_ == nullptr) { 61 return; 62 } 63 imsa_->OnStart(); 64 imsa_->userId_ = TddUtil::GetCurrentUserId(); 65 imsa_->identityChecker_ = std::make_shared<IdentityCheckerMock>(); 66 sptr<InputMethodSystemAbilityStub> serviceStub = imsa_; 67 imsaProxy_ = new InputMethodSystemAbilityProxy(serviceStub->AsObject()); 68 if (imsaProxy_ == nullptr) { 69 return; 70 } 71 IdentityCheckerMock::SetFocused(true); 72 73 inputMethodAbility_ = InputMethodAbility::GetInstance(); 74 inputMethodAbility_->abilityManager_ = imsaProxy_; 75 TddUtil::InitCurrentImePermissionInfo(); 76 IdentityCheckerMock::SetBundleName(TddUtil::currentBundleNameMock_); 77 inputMethodAbility_->SetCoreAndAgent(); 78 std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create("InputMethodAttachTest"); 79 textConfigHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner); 80 inputMethodAbility_->SetImeListener(std::make_shared<InputMethodEngineListenerImpl>(textConfigHandler_)); 81 82 inputMethodController_ = InputMethodController::GetInstance(); 83 inputMethodController_->abilityManager_ = imsaProxy_; 84 } TearDownTestCase(void)85 static void TearDownTestCase(void) 86 { 87 IMSA_HILOGI("InputMethodAttachTest::TearDownTestCase"); 88 IdentityCheckerMock::ResetParam(); 89 imsa_->OnStop(); 90 } SetUp()91 void SetUp() 92 { 93 IMSA_HILOGI("InputMethodAttachTest::SetUp"); 94 TaskManager::GetInstance().SetInited(true); 95 } TearDown()96 void TearDown() 97 { 98 IMSA_HILOGI("InputMethodAttachTest::TearDown"); 99 inputMethodController_->Close(); 100 std::this_thread::sleep_for(std::chrono::seconds(1)); 101 TaskManager::GetInstance().Reset(); 102 } 103 TestImfMultiThreadAttach()104 static void TestImfMultiThreadAttach() 105 { 106 for (int32_t i = 0; i < EACH_THREAD_CIRCULATION_TIME; ++i) { 107 sptr<OnTextChangedListener> textListener = new TextListener(); 108 if (timeout_) { 109 break; 110 } 111 int64_t start = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count(); 112 inputMethodController_->Attach(textListener, true); 113 int64_t end = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count(); 114 auto consume = end - start; 115 if (consume >= MAX_WAIT_TIME) { 116 timeout_ = true; 117 } 118 } 119 } 120 }; 121 sptr<InputMethodController> InputMethodAttachTest::inputMethodController_; 122 sptr<InputMethodAbility> InputMethodAttachTest::inputMethodAbility_; 123 sptr<InputMethodSystemAbilityProxy> InputMethodAttachTest::imsaProxy_; 124 sptr<InputMethodSystemAbility> InputMethodAttachTest::imsa_; 125 bool InputMethodAttachTest::timeout_ { false }; 126 std::shared_ptr<AppExecFwk::EventHandler> InputMethodAttachTest::textConfigHandler_ { nullptr }; 127 128 /** 129 * @tc.name: testAttach001 130 * @tc.desc: test Attach 131 * @tc.type: FUNC 132 */ 133 HWTEST_F(InputMethodAttachTest, testAttach001, TestSize.Level0) 134 { 135 IMSA_HILOGI("test testAttach001 after attach."); 136 sptr<OnTextChangedListener> textListener = new TextListener(); 137 auto ret = inputMethodController_->Attach(textListener); 138 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 139 std::this_thread::sleep_for(std::chrono::seconds(2)); 140 141 int32_t keyType = -1; 142 ret = inputMethodAbility_->GetEnterKeyType(keyType); 143 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 144 EXPECT_EQ(keyType, 0); 145 int32_t inputPattern = -1; 146 ret = inputMethodAbility_->GetInputPattern(inputPattern); 147 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 148 auto pattern = InputAttribute::PATTERN_TEXT; 149 EXPECT_EQ(inputPattern, pattern); 150 } 151 152 /** 153 * @tc.name: testAttach002 154 * @tc.desc: test Attach 155 * @tc.type: FUNC 156 */ 157 HWTEST_F(InputMethodAttachTest, testAttach002, TestSize.Level0) 158 { 159 IMSA_HILOGI("test testAttach002 after attach."); 160 sptr<OnTextChangedListener> textListener = new TextListener(); 161 auto ret = inputMethodController_->Attach(textListener, false); 162 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 163 164 int32_t keyType = -1; 165 ret = inputMethodAbility_->GetEnterKeyType(keyType); 166 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 167 EXPECT_EQ(keyType, 0); 168 int32_t inputPattern = -1; 169 ret = inputMethodAbility_->GetInputPattern(inputPattern); 170 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 171 auto pattern = InputAttribute::PATTERN_TEXT; 172 EXPECT_EQ(inputPattern, pattern); 173 } 174 175 /** 176 * @tc.name: testAttach003 177 * @tc.desc: test Attach 178 * @tc.type: FUNC 179 */ 180 HWTEST_F(InputMethodAttachTest, testAttach003, TestSize.Level0) 181 { 182 IMSA_HILOGI("test testAttach003 after attach."); 183 sptr<OnTextChangedListener> textListener = new TextListener(); 184 InputAttribute attribute; 185 attribute.inputPattern = 2; 186 attribute.enterKeyType = 1; 187 auto ret = inputMethodController_->Attach(textListener, true, attribute); 188 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 189 190 int32_t keyType = -1; 191 ret = inputMethodAbility_->GetEnterKeyType(keyType); 192 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 193 EXPECT_EQ(keyType, attribute.enterKeyType); 194 int32_t inputPattern = -1; 195 ret = inputMethodAbility_->GetInputPattern(inputPattern); 196 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 197 EXPECT_EQ(inputPattern, attribute.inputPattern); 198 } 199 200 /** 201 * @tc.name: testAttach004 202 * @tc.desc: test Attach 203 * @tc.type: FUNC 204 */ 205 HWTEST_F(InputMethodAttachTest, testAttach004, TestSize.Level0) 206 { 207 IMSA_HILOGI("test testAttach004 after attach."); 208 sptr<OnTextChangedListener> textListener = new TextListener(); 209 InputAttribute attribute; 210 attribute.inputPattern = 3; 211 attribute.enterKeyType = 2; 212 TextConfig config; 213 config.inputAttribute = attribute; 214 auto ret = inputMethodController_->Attach(textListener, false, config); 215 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 216 217 int32_t keyType = -1; 218 ret = inputMethodAbility_->GetEnterKeyType(keyType); 219 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 220 EXPECT_EQ(keyType, config.inputAttribute.enterKeyType); 221 int32_t inputPattern = -1; 222 ret = inputMethodAbility_->GetInputPattern(inputPattern); 223 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 224 EXPECT_EQ(inputPattern, config.inputAttribute.inputPattern); 225 } 226 227 /** 228 * @tc.name: testAttach005 229 * @tc.desc: test Attach, test optional param in TextConfig 230 * @tc.type: FUNC 231 */ 232 HWTEST_F(InputMethodAttachTest, testAttach005, TestSize.Level0) 233 { 234 IMSA_HILOGI("test testAttach005 after attach."); 235 sptr<OnTextChangedListener> textListener = new TextListener(); 236 InputAttribute attribute; 237 attribute.inputPattern = 3; 238 attribute.enterKeyType = 2; 239 TextConfig config; 240 config.inputAttribute = attribute; 241 CursorInfo cursorInfo; 242 cursorInfo.left = 0; 243 cursorInfo.top = 1; 244 cursorInfo.width = 0.5; 245 cursorInfo.height = 1.2; 246 config.cursorInfo = cursorInfo; 247 Range selectionRange; 248 selectionRange.start = 0; 249 selectionRange.end = 2; 250 config.range = selectionRange; 251 config.windowId = 10; 252 inputMethodController_->Close(); 253 auto ret = inputMethodController_->Attach(textListener, true, config); 254 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 255 256 int32_t keyType = -1; 257 ret = inputMethodAbility_->GetEnterKeyType(keyType); 258 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 259 EXPECT_EQ(keyType, config.inputAttribute.enterKeyType); 260 int32_t inputPattern = -1; 261 ret = inputMethodAbility_->GetInputPattern(inputPattern); 262 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 263 EXPECT_EQ(inputPattern, config.inputAttribute.inputPattern); 264 265 TextTotalConfig textConfig; 266 ret = inputMethodAbility_->GetTextConfig(textConfig); 267 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 268 EXPECT_EQ(textConfig.inputAttribute, config.inputAttribute); 269 EXPECT_EQ(textConfig.windowId, config.windowId); 270 EXPECT_EQ(textConfig.cursorInfo, config.cursorInfo); 271 EXPECT_EQ(textConfig.textSelection.newBegin, config.range.start); 272 EXPECT_EQ(textConfig.textSelection.newEnd, config.range.end); 273 EXPECT_EQ(textConfig.textSelection.oldBegin, INVALID_VALUE); 274 EXPECT_EQ(textConfig.textSelection.oldEnd, INVALID_VALUE); 275 } 276 277 /** 278 * @tc.name: testAttach006 279 * @tc.desc: test Attach 280 * @tc.type: FUNC 281 */ 282 HWTEST_F(InputMethodAttachTest, testAttach006, TestSize.Level0) 283 { 284 IMSA_HILOGI("test testAttach006 attach."); 285 InputMethodAttachTest::inputMethodController_->Close(); 286 TextListener::ResetParam(); 287 sptr<OnTextChangedListener> textListener = new TextListener(); 288 auto ret = InputMethodAttachTest::inputMethodController_->Attach(textListener, false); 289 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 290 EXPECT_TRUE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::NONE)); 291 std::this_thread::sleep_for(std::chrono::seconds(2)); 292 293 InputMethodAttachTest::inputMethodController_->Close(); 294 TextListener::ResetParam(); 295 ret = InputMethodAttachTest::inputMethodController_->Attach(textListener, true); 296 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 297 EXPECT_TRUE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::SHOW)); 298 } 299 300 /** 301 * @tc.name: testOnConfigurationChangeWithoutAttach 302 * @tc.desc: test OnConfigurationChange without attach 303 * @tc.type: FUNC 304 */ 305 HWTEST_F(InputMethodAttachTest, testOnConfigurationChangeWithoutAttach, TestSize.Level0) 306 { 307 IMSA_HILOGI("InputMethodAttachTest testOnConfigurationChangeWithoutAttach in."); 308 Configuration config; 309 EnterKeyType keyType = EnterKeyType::NEXT; 310 config.SetEnterKeyType(keyType); 311 TextInputType textInputType = TextInputType::DATETIME; 312 config.SetTextInputType(textInputType); 313 auto ret = inputMethodController_->OnConfigurationChange(config); 314 EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_BOUND); 315 } 316 317 /** 318 * @tc.name: testOnConfigurationChange 319 * @tc.desc: test OnConfigurationChange after attach 320 * @tc.type: FUNC 321 */ 322 HWTEST_F(InputMethodAttachTest, testOnConfigurationChange, TestSize.Level0) 323 { 324 IMSA_HILOGI("test OnConfigurationChange after attach."); 325 sptr<OnTextChangedListener> textListener = new TextListener(); 326 auto ret = inputMethodController_->Attach(textListener); 327 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 328 329 Configuration config; 330 EnterKeyType keyType = EnterKeyType::NEXT; 331 config.SetEnterKeyType(keyType); 332 TextInputType textInputType = TextInputType::DATETIME; 333 config.SetTextInputType(textInputType); 334 ret = inputMethodController_->OnConfigurationChange(config); 335 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 336 int32_t keyType2; 337 ret = inputMethodAbility_->GetEnterKeyType(keyType2); 338 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 339 EXPECT_EQ(keyType2, (int)keyType); 340 int32_t inputPattern; 341 ret = inputMethodAbility_->GetInputPattern(inputPattern); 342 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 343 EXPECT_EQ(inputPattern, (int)textInputType); 344 } 345 346 /** 347 * @tc.name: testGetTextConfig 348 * @tc.desc: test GetTextConfig of InputMethodAbility 349 * @tc.type: FUNC 350 */ 351 HWTEST_F(InputMethodAttachTest, testGetTextConfig, TestSize.Level0) 352 { 353 IMSA_HILOGI("test OnConfigurationChange001 after attach."); 354 sptr<OnTextChangedListener> textListener = new TextListener(); 355 InputAttribute attribute; 356 attribute.inputPattern = 3; 357 attribute.enterKeyType = 2; 358 TextConfig config; 359 config.inputAttribute = attribute; 360 CursorInfo cursorInfo; 361 cursorInfo.left = 0; 362 cursorInfo.top = 1; 363 cursorInfo.width = 0.5; 364 cursorInfo.height = 1.2; 365 config.cursorInfo = cursorInfo; 366 Range selectionRange; 367 selectionRange.start = 0; 368 selectionRange.end = 2; 369 config.range = selectionRange; 370 config.windowId = 10; 371 inputMethodController_->Close(); 372 auto ret = inputMethodController_->Attach(textListener, false, config); 373 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 374 TextTotalConfig totalConfig; 375 ret = inputMethodAbility_->GetTextConfig(totalConfig); 376 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 377 378 EXPECT_EQ(totalConfig.inputAttribute, attribute); 379 EXPECT_EQ(totalConfig.cursorInfo, cursorInfo); 380 EXPECT_EQ(totalConfig.textSelection.newBegin, selectionRange.start); 381 EXPECT_EQ(totalConfig.textSelection.newEnd, selectionRange.end); 382 EXPECT_EQ(totalConfig.textSelection.oldBegin, INVALID_VALUE); 383 EXPECT_EQ(totalConfig.textSelection.oldEnd, INVALID_VALUE); 384 EXPECT_EQ(totalConfig.windowId, config.windowId); 385 } 386 387 /** 388 * @tc.name: testOnCursorUpdateAfterAttach001 389 * @tc.desc: test OnCursorUpdate after attach 390 * @tc.type: FUNC 391 */ 392 HWTEST_F(InputMethodAttachTest, testOnCursorUpdateAfterAttach001, TestSize.Level0) 393 { 394 IMSA_HILOGI("test testOnCursorUpdateAfterAttach001."); 395 sptr<OnTextChangedListener> textListener = new TextListener(); 396 auto ret = inputMethodController_->Attach(textListener); 397 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 398 CursorInfo cursorInfo = { .top = 5, .left = 5, .height = 5, .width = 0.8 }; 399 ret = inputMethodController_->OnCursorUpdate(cursorInfo); 400 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 401 TextTotalConfig totalConfig; 402 ret = inputMethodAbility_->GetTextConfig(totalConfig); 403 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 404 EXPECT_EQ(totalConfig.cursorInfo, cursorInfo); 405 } 406 407 /** 408 * @tc.name: testOnCursorUpdateAfterAttach002 409 * @tc.desc: test OnCursorUpdate after attach 410 * @tc.type: FUNC 411 */ 412 HWTEST_F(InputMethodAttachTest, testOnCursorUpdateAfterAttach002, TestSize.Level0) 413 { 414 IMSA_HILOGI("test testOnCursorUpdateAfterAttach002."); 415 sptr<OnTextChangedListener> textListener = new TextListener(); 416 InputAttribute attribute; 417 attribute.inputPattern = 3; 418 attribute.enterKeyType = 2; 419 TextConfig config; 420 config.inputAttribute = attribute; 421 config.cursorInfo = { .top = 1, .left = 1, .height = 1, .width = 0.4 }; 422 auto ret = inputMethodController_->Attach(textListener, true, config); 423 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 424 CursorInfo cursorInfo = { .top = 5, .left = 5, .height = 5, .width = 0.8 }; 425 ret = inputMethodController_->OnCursorUpdate(cursorInfo); 426 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 427 TextTotalConfig totalConfig; 428 ret = inputMethodAbility_->GetTextConfig(totalConfig); 429 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 430 EXPECT_EQ(totalConfig.cursorInfo, cursorInfo); 431 } 432 433 /** 434 * @tc.name: testAttachWithInvalidImmersiveMode 435 * @tc.desc: test Attach with invalid immersive mode. 436 * @tc.type: FUNC 437 */ 438 HWTEST_F(InputMethodAttachTest, testAttachWithInvalidImmersiveMode, TestSize.Level0) 439 { 440 IMSA_HILOGI("test testAttachWithInvalidImmersiveMode."); 441 sptr<OnTextChangedListener> textListener = new TextListener(); 442 InputAttribute attribute; 443 attribute.immersiveMode = static_cast<int32_t>(ImmersiveMode::END); 444 TextConfig config; 445 config.inputAttribute = attribute; 446 auto ret = inputMethodController_->Attach(textListener, true, config); 447 EXPECT_EQ(ErrorCode::ERROR_PARAMETER_CHECK_FAILED, ret); 448 } 449 450 /** 451 * @tc.name: testOnSelectionChangeAfterAttach002 452 * @tc.desc: test OnSelectionChange after attach 453 * @tc.type: FUNC 454 */ 455 HWTEST_F(InputMethodAttachTest, testOnSelectionChangeAfterAttach002, TestSize.Level0) 456 { 457 IMSA_HILOGI("test testOnSelectionChangeAfterAttach002."); 458 sptr<OnTextChangedListener> textListener = new TextListener(); 459 InputAttribute attribute; 460 attribute.inputPattern = 3; 461 attribute.enterKeyType = 2; 462 TextConfig config; 463 config.inputAttribute = attribute; 464 config.range = { .start = 1, .end = 2 }; 465 inputMethodController_->Close(); 466 auto ret = inputMethodController_->Attach(textListener, false, config); 467 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 468 int start = 0; 469 int end = 1; 470 ret = inputMethodController_->OnSelectionChange(Str8ToStr16("aaa"), start, end); 471 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 472 473 TextTotalConfig totalConfig; 474 ret = inputMethodAbility_->GetTextConfig(totalConfig); 475 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 476 EXPECT_EQ(totalConfig.textSelection.newBegin, start); 477 EXPECT_EQ(totalConfig.textSelection.newEnd, end); 478 EXPECT_EQ(totalConfig.textSelection.oldBegin, config.range.start); 479 EXPECT_EQ(totalConfig.textSelection.oldEnd, config.range.end); 480 } 481 482 /** 483 * @tc.name: testOnConfigurationChangeAfterAttach001 484 * @tc.desc: test OnConfigurationChange after attach 485 * @tc.type: FUNC 486 */ 487 HWTEST_F(InputMethodAttachTest, testOnConfigurationChangeAfterAttach001, TestSize.Level0) 488 { 489 IMSA_HILOGI("test testOnConfigurationChangeAfterAttach001."); 490 sptr<OnTextChangedListener> textListener = new TextListener(); 491 auto ret = inputMethodController_->Attach(textListener); 492 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 493 494 Configuration config; 495 config.SetTextInputType(TextInputType::DATETIME); 496 config.SetEnterKeyType(EnterKeyType::NEXT); 497 ret = inputMethodController_->OnConfigurationChange(config); 498 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 499 500 TextTotalConfig totalConfig; 501 ret = inputMethodAbility_->GetTextConfig(totalConfig); 502 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 503 EXPECT_EQ(totalConfig.inputAttribute.inputPattern, static_cast<int32_t>(TextInputType::DATETIME)); 504 EXPECT_EQ(totalConfig.inputAttribute.enterKeyType, static_cast<int32_t>(EnterKeyType::NEXT)); 505 } 506 507 /** 508 * @tc.name: testOnConfigurationChangeAfterAttach002 509 * @tc.desc: test OnConfigurationChange after attach 510 * @tc.type: FUNC 511 */ 512 HWTEST_F(InputMethodAttachTest, testOnConfigurationChangeAfterAttach002, TestSize.Level0) 513 { 514 IMSA_HILOGI("test testOnConfigurationChangeAfterAttach002."); 515 sptr<OnTextChangedListener> textListener = new TextListener(); 516 InputAttribute attribute; 517 attribute.inputPattern = 3; 518 attribute.enterKeyType = 2; 519 attribute.immersiveMode = static_cast<int32_t>(ImmersiveMode::DARK_IMMERSIVE); 520 TextConfig config; 521 config.inputAttribute = attribute; 522 auto ret = inputMethodController_->Attach(textListener, false, config); 523 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 524 525 Configuration configuration; 526 configuration.SetTextInputType(TextInputType::DATETIME); 527 configuration.SetEnterKeyType(EnterKeyType::NEXT); 528 ret = inputMethodController_->OnConfigurationChange(configuration); 529 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 530 531 TextTotalConfig totalConfig; 532 ret = inputMethodAbility_->GetTextConfig(totalConfig); 533 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 534 EXPECT_EQ(totalConfig.inputAttribute.inputPattern, static_cast<int32_t>(configuration.GetTextInputType())); 535 EXPECT_EQ(totalConfig.inputAttribute.enterKeyType, static_cast<int32_t>(configuration.GetEnterKeyType())); 536 EXPECT_EQ(totalConfig.inputAttribute.immersiveMode, static_cast<int32_t>(ImmersiveMode::DARK_IMMERSIVE)); 537 } 538 539 /** 540 * @tc.name: testSetCallingWindowAfterAttach002 541 * @tc.desc: test SetCallingWindow after attach 542 * @tc.type: FUNC 543 */ 544 HWTEST_F(InputMethodAttachTest, testSetCallingWindowAfterAttach002, TestSize.Level0) 545 { 546 IMSA_HILOGI("test testSetCallingWindowAfterAttach002."); 547 sptr<OnTextChangedListener> textListener = new TextListener(); 548 InputAttribute attribute; 549 attribute.inputPattern = 3; 550 attribute.enterKeyType = 2; 551 TextConfig config; 552 config.inputAttribute = attribute; 553 config.windowId = 88; 554 auto ret = inputMethodController_->Attach(textListener, false, config); 555 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 556 557 uint32_t windowId = 99; 558 ret = inputMethodController_->SetCallingWindow(windowId); 559 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 560 561 TextTotalConfig totalConfig; 562 ret = inputMethodAbility_->GetTextConfig(totalConfig); 563 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 564 EXPECT_EQ(totalConfig.windowId, windowId); 565 } 566 567 /** 568 * @tc.name: testOnCursorUpdate001 569 * @tc.desc: test OnCursorUpdate after attach 570 * @tc.type: FUNC 571 */ 572 HWTEST_F(InputMethodAttachTest, testOnCursorUpdate001, TestSize.Level0) 573 { 574 IMSA_HILOGI("test testOnCursorUpdate001."); 575 sptr<OnTextChangedListener> textListener = new TextListener(); 576 auto ret = inputMethodController_->Attach(textListener); 577 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 578 CursorInfo cursorInfo = { .top = 5, .left = 5, .height = 5, .width = 0.8 }; 579 ret = inputMethodController_->OnCursorUpdate(cursorInfo); 580 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 581 582 InputAttribute attribute; 583 attribute.inputPattern = 3; 584 attribute.enterKeyType = 2; 585 TextConfig config; 586 config.inputAttribute = attribute; 587 CursorInfo cursorInfo2 = { .top = 10, .left = 9, .width = 8, .height = 7 }; 588 config.cursorInfo = cursorInfo2; 589 ret = inputMethodController_->Attach(textListener, false, config); 590 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 591 592 TextTotalConfig totalConfig; 593 ret = inputMethodAbility_->GetTextConfig(totalConfig); 594 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 595 EXPECT_EQ(totalConfig.cursorInfo, cursorInfo2); 596 } 597 598 /** 599 * @tc.name: testOnSelectionChange 600 * @tc.desc: test OnSelectionChange after attach 601 * @tc.type: FUNC 602 */ 603 HWTEST_F(InputMethodAttachTest, testOnSelectionChange, TestSize.Level0) 604 { 605 IMSA_HILOGI("test testOnSelectionChange."); 606 sptr<OnTextChangedListener> textListener = new TextListener(); 607 auto ret = inputMethodController_->Attach(textListener); 608 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 609 int start = 0; 610 int end = 1; 611 ret = inputMethodController_->OnSelectionChange(Str8ToStr16("bbb"), start, end); 612 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 613 614 InputAttribute attribute; 615 attribute.inputPattern = 3; 616 attribute.enterKeyType = 2; 617 TextConfig config; 618 config.inputAttribute = attribute; 619 config.range.start = 10; 620 config.range.end = 20; 621 ret = inputMethodController_->Attach(textListener, false, config); 622 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 623 624 TextTotalConfig totalConfig; 625 ret = inputMethodAbility_->GetTextConfig(totalConfig); 626 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 627 EXPECT_EQ(totalConfig.textSelection.newBegin, config.range.start); 628 EXPECT_EQ(totalConfig.textSelection.newEnd, config.range.end); 629 EXPECT_EQ(totalConfig.textSelection.oldBegin, start); 630 EXPECT_EQ(totalConfig.textSelection.oldEnd, end); 631 } 632 633 /** 634 * @tc.name: testOnConfigurationChange002 635 * @tc.desc: test OnConfigurationChange after attach 636 * @tc.type: FUNC 637 */ 638 HWTEST_F(InputMethodAttachTest, testOnConfigurationChange002, TestSize.Level0) 639 { 640 IMSA_HILOGI("test testOnConfigurationChange002."); 641 sptr<OnTextChangedListener> textListener = new TextListener(); 642 auto ret = inputMethodController_->Attach(textListener); 643 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 644 645 Configuration configuration; 646 configuration.SetTextInputType(TextInputType::DATETIME); 647 configuration.SetEnterKeyType(EnterKeyType::NEXT); 648 ret = inputMethodController_->OnConfigurationChange(configuration); 649 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 650 651 InputAttribute attribute; 652 attribute.inputPattern = 3; 653 attribute.enterKeyType = 2; 654 TextConfig config; 655 config.inputAttribute = attribute; 656 config.inputAttribute.enterKeyType = 5; 657 config.inputAttribute.inputPattern = 5; 658 config.inputAttribute.immersiveMode = static_cast<int32_t>(ImmersiveMode::LIGHT_IMMERSIVE); 659 ret = inputMethodController_->Attach(textListener, false, config); 660 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 661 662 TextTotalConfig totalConfig; 663 ret = inputMethodAbility_->GetTextConfig(totalConfig); 664 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 665 666 EXPECT_EQ(totalConfig.inputAttribute, config.inputAttribute); 667 } 668 669 /** 670 * @tc.name: testSetCallingWindow 671 * @tc.desc: test SetCallingWindow after attach 672 * @tc.type: FUNC 673 */ 674 HWTEST_F(InputMethodAttachTest, testSetCallingWindow, TestSize.Level0) 675 { 676 IMSA_HILOGI("test testSetCallingWindow."); 677 sptr<OnTextChangedListener> textListener = new TextListener(); 678 auto ret = inputMethodController_->Attach(textListener); 679 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 680 681 uint32_t windowId = 88; 682 ret = inputMethodController_->SetCallingWindow(windowId); 683 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 684 685 InputAttribute attribute; 686 attribute.inputPattern = 3; 687 attribute.enterKeyType = 2; 688 TextConfig config; 689 config.windowId = 77; 690 ret = inputMethodController_->Attach(textListener, false, config); 691 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 692 693 TextTotalConfig totalConfig; 694 ret = inputMethodAbility_->GetTextConfig(totalConfig); 695 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 696 697 EXPECT_EQ(totalConfig.windowId, config.windowId); 698 } 699 /** 700 * @tc.name: testImeCallbackInAttach 701 * @tc.desc: test ime can receive callback in Attach 702 * @tc.type: FUNC 703 */ 704 HWTEST_F(InputMethodAttachTest, testImeCallbackInAttach, TestSize.Level0) 705 { 706 IMSA_HILOGI("test testImeCallbackInAttach."); 707 inputMethodAbility_->SetImeListener(std::make_shared<InputMethodEngineListenerImpl>()); 708 inputMethodAbility_->SetKdListener(std::make_shared<KeyboardListenerTestImpl>()); 709 sptr<OnTextChangedListener> textListener = new TextListener(); 710 InputMethodEngineListenerImpl::ResetParam(); 711 KeyboardListenerTestImpl::ResetParam(); 712 InputAttribute attribute; 713 attribute.inputPattern = 3; 714 attribute.enterKeyType = 2; 715 TextConfig config; 716 config.inputAttribute = attribute; 717 CursorInfo cursorInfo; 718 cursorInfo.left = 0; 719 cursorInfo.top = 1; 720 cursorInfo.width = 0.5; 721 cursorInfo.height = 1.2; 722 config.cursorInfo = cursorInfo; 723 Range selectionRange; 724 selectionRange.start = 5; 725 selectionRange.end = 2; 726 config.range = selectionRange; 727 config.windowId = 10; 728 auto ret = inputMethodController_->Attach(textListener, true, config); 729 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 730 731 EXPECT_TRUE(KeyboardListenerTestImpl::WaitSelectionChange(selectionRange.start)); 732 EXPECT_TRUE(KeyboardListenerTestImpl::WaitCursorUpdate()); 733 EXPECT_TRUE(KeyboardListenerTestImpl::WaitEditorAttributeChange(attribute)); 734 EXPECT_TRUE(InputMethodEngineListenerImpl::WaitSetCallingWindow(config.windowId)); 735 } 736 737 /** 738 * @tc.name: TestImfMultiThreadAttach 739 * @tc.desc: test ime Attach in multi-thread 740 * @tc.type: FUNC 741 * @tc.require: 742 * @tc.author: mashaoyin 743 */ 744 HWTEST_F(InputMethodAttachTest, multiThreadAttachTest_001, TestSize.Level0) 745 { 746 IMSA_HILOGI("InputMethodAttachTest multiThreadAttachTest_001 START"); 747 SET_THREAD_NUM(5); 748 GTEST_RUN_TASK(InputMethodAttachTest::TestImfMultiThreadAttach); 749 EXPECT_FALSE(timeout_); 750 } 751 752 /** 753 * @tc.name: testAttach007 754 * @tc.desc: test Attach 755 * @tc.type: FUNC 756 */ 757 HWTEST_F(InputMethodAttachTest, testAttach007, TestSize.Level0) 758 { 759 IMSA_HILOGI("test testAttach007 after attach."); 760 sptr<OnTextChangedListener> textListener = new TextListener(); 761 InputAttribute attribute; 762 attribute.inputPattern = 3; 763 attribute.enterKeyType = 2; 764 TextConfig config; 765 config.inputAttribute = attribute; 766 AttachOptions attachOptions; 767 attachOptions.isShowKeyboard = false; 768 attachOptions.requestKeyboardReason = RequestKeyboardReason::NONE; 769 auto ret = inputMethodController_->Attach(textListener, attachOptions, config); 770 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 771 772 int32_t keyType = -1; 773 ret = inputMethodAbility_->GetEnterKeyType(keyType); 774 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 775 EXPECT_EQ(keyType, config.inputAttribute.enterKeyType); 776 int32_t inputPattern = -1; 777 ret = inputMethodAbility_->GetInputPattern(inputPattern); 778 EXPECT_EQ(ret, ErrorCode::NO_ERROR); 779 EXPECT_EQ(inputPattern, config.inputAttribute.inputPattern); 780 } 781 } // namespace MiscServices 782 } // namespace OHOS 783