• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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