• 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 InputMethodAbility &inputMethodAbility_;
48     static sptr<InputMethodSystemAbilityProxy> imsaProxy_;
49     static sptr<InputMethodSystemAbility> imsa_;
50     static constexpr int32_t EACH_THREAD_CIRCULATION_TIME = 100;
51     static constexpr int32_t WAIT_TASK_EMPTY_TIMES = 100;
52     static constexpr int32_t WAIT_TASK_EMPTY_INTERVAL = 20;
53     static bool timeout_;
54     static std::shared_ptr<AppExecFwk::EventHandler> textConfigHandler_;
55 
SetUpTestCase(void)56     static void SetUpTestCase(void)
57     {
58         IMSA_HILOGI("InputMethodAttachTest::SetUpTestCase");
59         IdentityCheckerMock::ResetParam();
60         imsa_ = new (std::nothrow) InputMethodSystemAbility();
61         if (imsa_ == nullptr) {
62             return;
63         }
64         imsa_->OnStart();
65         imsa_->userId_ = TddUtil::GetCurrentUserId();
66         imsa_->identityChecker_ = std::make_shared<IdentityCheckerMock>();
67         sptr<InputMethodSystemAbilityStub> serviceStub = imsa_;
68         imsaProxy_ = new InputMethodSystemAbilityProxy(serviceStub->AsObject());
69         if (imsaProxy_ == nullptr) {
70             return;
71         }
72         IdentityCheckerMock::SetFocused(true);
73 
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         BlockRetry(WAIT_TASK_EMPTY_INTERVAL, WAIT_TASK_EMPTY_TIMES, IsTaskEmpty);
101         TaskManager::GetInstance().Reset();
102         TaskManager::GetInstance().Reset();
103     }
104 
TestImfMultiThreadAttach()105     static void TestImfMultiThreadAttach()
106     {
107         for (int32_t i = 0; i < EACH_THREAD_CIRCULATION_TIME; ++i) {
108             sptr<OnTextChangedListener> textListener = new TextListener();
109             inputMethodController_->Attach(textListener, true);
110         }
111         IMSA_HILOGI("InputMethodAttachTest::end");
112     }
113 
IsTaskEmpty()114     static bool IsTaskEmpty()
115     {
116         return TaskManager::GetInstance().curTask_ == nullptr && TaskManager::GetInstance().amsTasks_.empty() &&
117                TaskManager::GetInstance().imaTasks_.empty() && TaskManager::GetInstance().imsaTasks_.empty() &&
118                TaskManager::GetInstance().innerTasks_.empty();
119     }
120 };
121 sptr<InputMethodController> InputMethodAttachTest::inputMethodController_;
122 InputMethodAbility &InputMethodAttachTest::inputMethodAbility_ = InputMethodAbility::GetInstance();
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     BlockRetry(WAIT_TASK_EMPTY_INTERVAL, WAIT_TASK_EMPTY_TIMES, IsTaskEmpty);
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     BlockRetry(WAIT_TASK_EMPTY_INTERVAL, WAIT_TASK_EMPTY_TIMES, IsTaskEmpty);
164 
165     int32_t keyType = -1;
166     ret = inputMethodAbility_.GetEnterKeyType(keyType);
167     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
168     EXPECT_EQ(keyType, 0);
169     int32_t inputPattern = -1;
170     ret = inputMethodAbility_.GetInputPattern(inputPattern);
171     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
172     auto pattern = InputAttribute::PATTERN_TEXT;
173     EXPECT_EQ(inputPattern, pattern);
174 }
175 
176 /**
177  * @tc.name: testAttach003
178  * @tc.desc: test Attach
179  * @tc.type: FUNC
180  */
181 HWTEST_F(InputMethodAttachTest, testAttach003, TestSize.Level0)
182 {
183     IMSA_HILOGI("test testAttach003 after attach.");
184     sptr<OnTextChangedListener> textListener = new TextListener();
185     InputAttribute attribute;
186     attribute.inputPattern = 2;
187     attribute.enterKeyType = 1;
188     auto ret = inputMethodController_->Attach(textListener, true, attribute);
189     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
190     BlockRetry(WAIT_TASK_EMPTY_INTERVAL, WAIT_TASK_EMPTY_TIMES, IsTaskEmpty);
191 
192     int32_t keyType = -1;
193     ret = inputMethodAbility_.GetEnterKeyType(keyType);
194     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
195     EXPECT_EQ(keyType, attribute.enterKeyType);
196     int32_t inputPattern = -1;
197     ret = inputMethodAbility_.GetInputPattern(inputPattern);
198     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
199     EXPECT_EQ(inputPattern, attribute.inputPattern);
200 }
201 
202 /**
203  * @tc.name: testAttach004
204  * @tc.desc: test Attach
205  * @tc.type: FUNC
206  */
207 HWTEST_F(InputMethodAttachTest, testAttach004, TestSize.Level0)
208 {
209     IMSA_HILOGI("test testAttach004 after attach.");
210     sptr<OnTextChangedListener> textListener = new TextListener();
211     InputAttribute attribute;
212     attribute.inputPattern = 3;
213     attribute.enterKeyType = 2;
214     TextConfig config;
215     config.inputAttribute = attribute;
216     auto ret = inputMethodController_->Attach(textListener, false, config);
217     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
218     BlockRetry(WAIT_TASK_EMPTY_INTERVAL, WAIT_TASK_EMPTY_TIMES, IsTaskEmpty);
219 
220     int32_t keyType = -1;
221     ret = inputMethodAbility_.GetEnterKeyType(keyType);
222     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
223     EXPECT_EQ(keyType, config.inputAttribute.enterKeyType);
224     int32_t inputPattern = -1;
225     ret = inputMethodAbility_.GetInputPattern(inputPattern);
226     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
227     EXPECT_EQ(inputPattern, config.inputAttribute.inputPattern);
228 }
229 
230 /**
231  * @tc.name: testAttach005
232  * @tc.desc: test Attach, test optional param in TextConfig
233  * @tc.type: FUNC
234  */
235 HWTEST_F(InputMethodAttachTest, testAttach005, TestSize.Level0)
236 {
237     IMSA_HILOGI("test testAttach005 after attach.");
238     sptr<OnTextChangedListener> textListener = new TextListener();
239     InputAttribute attribute;
240     attribute.inputPattern = 3;
241     attribute.enterKeyType = 2;
242     TextConfig config;
243     config.inputAttribute = attribute;
244     CursorInfo cursorInfo;
245     cursorInfo.left = 0;
246     cursorInfo.top = 1;
247     cursorInfo.width = 0.5;
248     cursorInfo.height = 1.2;
249     config.cursorInfo = cursorInfo;
250     Range selectionRange;
251     selectionRange.start = 0;
252     selectionRange.end = 2;
253     config.range = selectionRange;
254     config.windowId = 10;
255     inputMethodController_->Close();
256     auto ret = inputMethodController_->Attach(textListener, true, config);
257     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
258     BlockRetry(WAIT_TASK_EMPTY_INTERVAL, WAIT_TASK_EMPTY_TIMES, IsTaskEmpty);
259 
260     int32_t keyType = -1;
261     ret = inputMethodAbility_.GetEnterKeyType(keyType);
262     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
263     EXPECT_EQ(keyType, config.inputAttribute.enterKeyType);
264     int32_t inputPattern = -1;
265     ret = inputMethodAbility_.GetInputPattern(inputPattern);
266     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
267     EXPECT_EQ(inputPattern, config.inputAttribute.inputPattern);
268 
269     TextTotalConfig textConfig;
270     ret = inputMethodAbility_.GetTextConfig(textConfig);
271     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
272     EXPECT_EQ(textConfig.inputAttribute, config.inputAttribute);
273     EXPECT_EQ(textConfig.windowId, config.windowId);
274     EXPECT_EQ(textConfig.cursorInfo, config.cursorInfo);
275     EXPECT_EQ(textConfig.textSelection.newBegin, config.range.start);
276     EXPECT_EQ(textConfig.textSelection.newEnd, config.range.end);
277     EXPECT_EQ(textConfig.textSelection.oldBegin, INVALID_VALUE);
278     EXPECT_EQ(textConfig.textSelection.oldEnd, INVALID_VALUE);
279 }
280 
281 /**
282  * @tc.name: testAttach006
283  * @tc.desc: test Attach
284  * @tc.type: FUNC
285  */
286 HWTEST_F(InputMethodAttachTest, testAttach006, TestSize.Level0)
287 {
288     IMSA_HILOGI("test testAttach006 attach.");
289     InputMethodAttachTest::inputMethodController_->Close();
290     TextListener::ResetParam();
291     sptr<OnTextChangedListener> textListener = new TextListener();
292     auto ret = InputMethodAttachTest::inputMethodController_->Attach(textListener, false);
293     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
294     EXPECT_TRUE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::NONE));
295     BlockRetry(WAIT_TASK_EMPTY_INTERVAL, WAIT_TASK_EMPTY_TIMES, IsTaskEmpty);
296 
297     InputMethodAttachTest::inputMethodController_->Close();
298     TextListener::ResetParam();
299     ret = InputMethodAttachTest::inputMethodController_->Attach(textListener, true);
300     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
301     EXPECT_TRUE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::SHOW));
302 }
303 
304 /**
305  * @tc.name: testOnConfigurationChangeWithoutAttach
306  * @tc.desc: test OnConfigurationChange without attach
307  * @tc.type: FUNC
308  */
309 HWTEST_F(InputMethodAttachTest, testOnConfigurationChangeWithoutAttach, TestSize.Level0)
310 {
311     IMSA_HILOGI("InputMethodAttachTest testOnConfigurationChangeWithoutAttach in.");
312     Configuration config;
313     EnterKeyType keyType = EnterKeyType::NEXT;
314     config.SetEnterKeyType(keyType);
315     TextInputType textInputType = TextInputType::DATETIME;
316     config.SetTextInputType(textInputType);
317     auto ret = inputMethodController_->OnConfigurationChange(config);
318     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_BOUND);
319 }
320 
321 /**
322  * @tc.name: testOnConfigurationChange
323  * @tc.desc: test OnConfigurationChange after attach
324  * @tc.type: FUNC
325  */
326 HWTEST_F(InputMethodAttachTest, testOnConfigurationChange, TestSize.Level0)
327 {
328     IMSA_HILOGI("test OnConfigurationChange after attach.");
329     sptr<OnTextChangedListener> textListener = new TextListener();
330     auto ret = inputMethodController_->Attach(textListener);
331     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
332     BlockRetry(WAIT_TASK_EMPTY_INTERVAL, WAIT_TASK_EMPTY_TIMES, IsTaskEmpty);
333 
334     Configuration config;
335     EnterKeyType keyType = EnterKeyType::NEXT;
336     config.SetEnterKeyType(keyType);
337     TextInputType textInputType = TextInputType::DATETIME;
338     config.SetTextInputType(textInputType);
339     ret = inputMethodController_->OnConfigurationChange(config);
340     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
341     int32_t keyType2;
342     ret = inputMethodAbility_.GetEnterKeyType(keyType2);
343     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
344     EXPECT_EQ(keyType2, (int)keyType);
345     int32_t inputPattern;
346     ret = inputMethodAbility_.GetInputPattern(inputPattern);
347     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
348     EXPECT_EQ(inputPattern, (int)textInputType);
349 }
350 
351 /**
352  * @tc.name: testGetTextConfig
353  * @tc.desc: test GetTextConfig of InputMethodAbility
354  * @tc.type: FUNC
355  */
356 HWTEST_F(InputMethodAttachTest, testGetTextConfig, TestSize.Level0)
357 {
358     IMSA_HILOGI("test OnConfigurationChange001 after attach.");
359     sptr<OnTextChangedListener> textListener = new TextListener();
360     InputAttribute attribute;
361     attribute.inputPattern = 3;
362     attribute.enterKeyType = 2;
363     TextConfig config;
364     config.inputAttribute = attribute;
365     CursorInfo cursorInfo;
366     cursorInfo.left = 0;
367     cursorInfo.top = 1;
368     cursorInfo.width = 0.5;
369     cursorInfo.height = 1.2;
370     config.cursorInfo = cursorInfo;
371     Range selectionRange;
372     selectionRange.start = 0;
373     selectionRange.end = 2;
374     config.range = selectionRange;
375     config.windowId = 10;
376     inputMethodController_->Close();
377     auto ret = inputMethodController_->Attach(textListener, false, config);
378     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
379     BlockRetry(WAIT_TASK_EMPTY_INTERVAL, WAIT_TASK_EMPTY_TIMES, IsTaskEmpty);
380     TextTotalConfig totalConfig;
381     ret = inputMethodAbility_.GetTextConfig(totalConfig);
382     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
383 
384     EXPECT_EQ(totalConfig.inputAttribute, attribute);
385     EXPECT_EQ(totalConfig.cursorInfo, cursorInfo);
386     EXPECT_EQ(totalConfig.textSelection.newBegin, selectionRange.start);
387     EXPECT_EQ(totalConfig.textSelection.newEnd, selectionRange.end);
388     EXPECT_EQ(totalConfig.textSelection.oldBegin, INVALID_VALUE);
389     EXPECT_EQ(totalConfig.textSelection.oldEnd, INVALID_VALUE);
390     EXPECT_EQ(totalConfig.windowId, config.windowId);
391 }
392 
393 /**
394  * @tc.name: testOnCursorUpdateAfterAttach001
395  * @tc.desc: test OnCursorUpdate after attach
396  * @tc.type: FUNC
397  */
398 HWTEST_F(InputMethodAttachTest, testOnCursorUpdateAfterAttach001, TestSize.Level0)
399 {
400     IMSA_HILOGI("test testOnCursorUpdateAfterAttach001.");
401     sptr<OnTextChangedListener> textListener = new TextListener();
402     auto ret = inputMethodController_->Attach(textListener);
403     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
404     CursorInfo cursorInfo = { .top = 5, .left = 5, .height = 5, .width = 0.8 };
405     ret = inputMethodController_->OnCursorUpdate(cursorInfo);
406     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
407     TextTotalConfig totalConfig;
408     ret = inputMethodAbility_.GetTextConfig(totalConfig);
409     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
410     EXPECT_EQ(totalConfig.cursorInfo, cursorInfo);
411 }
412 
413 /**
414  * @tc.name: testOnCursorUpdateAfterAttach002
415  * @tc.desc: test OnCursorUpdate after attach
416  * @tc.type: FUNC
417  */
418 HWTEST_F(InputMethodAttachTest, testOnCursorUpdateAfterAttach002, TestSize.Level0)
419 {
420     IMSA_HILOGI("test testOnCursorUpdateAfterAttach002.");
421     sptr<OnTextChangedListener> textListener = new TextListener();
422     InputAttribute attribute;
423     attribute.inputPattern = 3;
424     attribute.enterKeyType = 2;
425     TextConfig config;
426     config.inputAttribute = attribute;
427     config.cursorInfo = { .top = 1, .left = 1, .height = 1, .width = 0.4 };
428     auto ret = inputMethodController_->Attach(textListener, true, config);
429     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
430     CursorInfo cursorInfo = { .top = 5, .left = 5, .height = 5, .width = 0.8 };
431     ret = inputMethodController_->OnCursorUpdate(cursorInfo);
432     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
433     TextTotalConfig totalConfig;
434     ret = inputMethodAbility_.GetTextConfig(totalConfig);
435     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
436     EXPECT_EQ(totalConfig.cursorInfo, cursorInfo);
437 }
438 
439 /**
440  * @tc.name: testAttachWithInvalidImmersiveMode
441  * @tc.desc: test Attach with invalid immersive mode.
442  * @tc.type: FUNC
443  */
444 HWTEST_F(InputMethodAttachTest, testAttachWithInvalidImmersiveMode, TestSize.Level0)
445 {
446     IMSA_HILOGI("test testAttachWithInvalidImmersiveMode.");
447     sptr<OnTextChangedListener> textListener = new TextListener();
448     InputAttribute attribute;
449     attribute.immersiveMode = static_cast<int32_t>(ImmersiveMode::END);
450     TextConfig config;
451     config.inputAttribute = attribute;
452     auto ret = inputMethodController_->Attach(textListener, true, config);
453     EXPECT_EQ(ErrorCode::ERROR_PARAMETER_CHECK_FAILED, ret);
454 }
455 
456 /**
457  * @tc.name: testOnSelectionChangeAfterAttach002
458  * @tc.desc: test OnSelectionChange after attach
459  * @tc.type: FUNC
460  */
461 HWTEST_F(InputMethodAttachTest, testOnSelectionChangeAfterAttach002, TestSize.Level0)
462 {
463     IMSA_HILOGI("test testOnSelectionChangeAfterAttach002.");
464     sptr<OnTextChangedListener> textListener = new TextListener();
465     InputAttribute attribute;
466     attribute.inputPattern = 3;
467     attribute.enterKeyType = 2;
468     TextConfig config;
469     config.inputAttribute = attribute;
470     config.range = { .start = 1, .end = 2 };
471     inputMethodController_->Close();
472     auto ret = inputMethodController_->Attach(textListener, false, config);
473     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
474     int start = 0;
475     int end = 1;
476     ret = inputMethodController_->OnSelectionChange(Str8ToStr16("aaa"), start, end);
477     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
478 
479     TextTotalConfig totalConfig;
480     ret = inputMethodAbility_.GetTextConfig(totalConfig);
481     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
482     EXPECT_EQ(totalConfig.textSelection.newBegin, start);
483     EXPECT_EQ(totalConfig.textSelection.newEnd, end);
484     EXPECT_EQ(totalConfig.textSelection.oldBegin, config.range.start);
485     EXPECT_EQ(totalConfig.textSelection.oldEnd, config.range.end);
486 }
487 
488 /**
489  * @tc.name: testOnConfigurationChangeAfterAttach001
490  * @tc.desc: test OnConfigurationChange after attach
491  * @tc.type: FUNC
492  */
493 HWTEST_F(InputMethodAttachTest, testOnConfigurationChangeAfterAttach001, TestSize.Level0)
494 {
495     IMSA_HILOGI("test testOnConfigurationChangeAfterAttach001.");
496     sptr<OnTextChangedListener> textListener = new TextListener();
497     auto ret = inputMethodController_->Attach(textListener);
498     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
499 
500     Configuration config;
501     config.SetTextInputType(TextInputType::DATETIME);
502     config.SetEnterKeyType(EnterKeyType::NEXT);
503     ret = inputMethodController_->OnConfigurationChange(config);
504     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
505 
506     TextTotalConfig totalConfig;
507     ret = inputMethodAbility_.GetTextConfig(totalConfig);
508     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
509     EXPECT_EQ(totalConfig.inputAttribute.inputPattern, static_cast<int32_t>(TextInputType::DATETIME));
510     EXPECT_EQ(totalConfig.inputAttribute.enterKeyType, static_cast<int32_t>(EnterKeyType::NEXT));
511 }
512 
513 /**
514  * @tc.name: testOnConfigurationChangeAfterAttach002
515  * @tc.desc: test OnConfigurationChange after attach
516  * @tc.type: FUNC
517  */
518 HWTEST_F(InputMethodAttachTest, testOnConfigurationChangeAfterAttach002, TestSize.Level0)
519 {
520     IMSA_HILOGI("test testOnConfigurationChangeAfterAttach002.");
521     sptr<OnTextChangedListener> textListener = new TextListener();
522     InputAttribute attribute;
523     attribute.inputPattern = 3;
524     attribute.enterKeyType = 2;
525     attribute.immersiveMode = static_cast<int32_t>(ImmersiveMode::DARK_IMMERSIVE);
526     TextConfig config;
527     config.inputAttribute = attribute;
528     auto ret = inputMethodController_->Attach(textListener, false, config);
529     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
530 
531     Configuration configuration;
532     configuration.SetTextInputType(TextInputType::DATETIME);
533     configuration.SetEnterKeyType(EnterKeyType::NEXT);
534     ret = inputMethodController_->OnConfigurationChange(configuration);
535     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
536 
537     TextTotalConfig totalConfig;
538     ret = inputMethodAbility_.GetTextConfig(totalConfig);
539     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
540     EXPECT_EQ(totalConfig.inputAttribute.inputPattern, static_cast<int32_t>(configuration.GetTextInputType()));
541     EXPECT_EQ(totalConfig.inputAttribute.enterKeyType, static_cast<int32_t>(configuration.GetEnterKeyType()));
542     EXPECT_EQ(totalConfig.inputAttribute.immersiveMode, static_cast<int32_t>(ImmersiveMode::DARK_IMMERSIVE));
543 }
544 
545 /**
546  * @tc.name: testSetCallingWindowAfterAttach002
547  * @tc.desc: test SetCallingWindow after attach
548  * @tc.type: FUNC
549  */
550 HWTEST_F(InputMethodAttachTest, testSetCallingWindowAfterAttach002, TestSize.Level0)
551 {
552     IMSA_HILOGI("test testSetCallingWindowAfterAttach002.");
553     sptr<OnTextChangedListener> textListener = new TextListener();
554     InputAttribute attribute;
555     attribute.inputPattern = 3;
556     attribute.enterKeyType = 2;
557     TextConfig config;
558     config.inputAttribute = attribute;
559     config.windowId = 88;
560     auto ret = inputMethodController_->Attach(textListener, false, config);
561     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
562 
563     uint32_t windowId = 99;
564     ret = inputMethodController_->SetCallingWindow(windowId);
565     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
566 
567     TextTotalConfig totalConfig;
568     ret = inputMethodAbility_.GetTextConfig(totalConfig);
569     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
570     EXPECT_EQ(totalConfig.windowId, windowId);
571 }
572 
573 /**
574  * @tc.name: testOnCursorUpdate001
575  * @tc.desc: test OnCursorUpdate after attach
576  * @tc.type: FUNC
577  */
578 HWTEST_F(InputMethodAttachTest, testOnCursorUpdate001, TestSize.Level0)
579 {
580     IMSA_HILOGI("test testOnCursorUpdate001.");
581     sptr<OnTextChangedListener> textListener = new TextListener();
582     auto ret = inputMethodController_->Attach(textListener);
583     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
584     CursorInfo cursorInfo = { .top = 5, .left = 5, .height = 5, .width = 0.8 };
585     ret = inputMethodController_->OnCursorUpdate(cursorInfo);
586     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
587 
588     InputAttribute attribute;
589     attribute.inputPattern = 3;
590     attribute.enterKeyType = 2;
591     TextConfig config;
592     config.inputAttribute = attribute;
593     CursorInfo cursorInfo2 = { .top = 10, .left = 9, .width = 8, .height = 7 };
594     config.cursorInfo = cursorInfo2;
595     ret = inputMethodController_->Attach(textListener, false, config);
596     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
597 
598     TextTotalConfig totalConfig;
599     ret = inputMethodAbility_.GetTextConfig(totalConfig);
600     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
601     EXPECT_EQ(totalConfig.cursorInfo, cursorInfo2);
602 }
603 
604 /**
605  * @tc.name: testOnSelectionChange
606  * @tc.desc: test OnSelectionChange after attach
607  * @tc.type: FUNC
608  */
609 HWTEST_F(InputMethodAttachTest, testOnSelectionChange, TestSize.Level0)
610 {
611     IMSA_HILOGI("test testOnSelectionChange.");
612     sptr<OnTextChangedListener> textListener = new TextListener();
613     auto ret = inputMethodController_->Attach(textListener);
614     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
615     int start = 0;
616     int end = 1;
617     ret = inputMethodController_->OnSelectionChange(Str8ToStr16("bbb"), start, end);
618     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
619 
620     InputAttribute attribute;
621     attribute.inputPattern = 3;
622     attribute.enterKeyType = 2;
623     TextConfig config;
624     config.inputAttribute = attribute;
625     config.range.start = 10;
626     config.range.end = 20;
627     ret = inputMethodController_->Attach(textListener, false, config);
628     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
629 
630     TextTotalConfig totalConfig;
631     ret = inputMethodAbility_.GetTextConfig(totalConfig);
632     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
633     EXPECT_EQ(totalConfig.textSelection.newBegin, config.range.start);
634     EXPECT_EQ(totalConfig.textSelection.newEnd, config.range.end);
635     EXPECT_EQ(totalConfig.textSelection.oldBegin, start);
636     EXPECT_EQ(totalConfig.textSelection.oldEnd, end);
637 }
638 
639 /**
640  * @tc.name: testOnConfigurationChange002
641  * @tc.desc: test OnConfigurationChange after attach
642  * @tc.type: FUNC
643  */
644 HWTEST_F(InputMethodAttachTest, testOnConfigurationChange002, TestSize.Level0)
645 {
646     IMSA_HILOGI("test testOnConfigurationChange002.");
647     sptr<OnTextChangedListener> textListener = new TextListener();
648     auto ret = inputMethodController_->Attach(textListener);
649     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
650 
651     Configuration configuration;
652     configuration.SetTextInputType(TextInputType::DATETIME);
653     configuration.SetEnterKeyType(EnterKeyType::NEXT);
654     ret = inputMethodController_->OnConfigurationChange(configuration);
655     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
656 
657     InputAttribute attribute;
658     attribute.inputPattern = 3;
659     attribute.enterKeyType = 2;
660     TextConfig config;
661     config.inputAttribute = attribute;
662     config.inputAttribute.enterKeyType = 5;
663     config.inputAttribute.inputPattern = 5;
664     config.inputAttribute.immersiveMode = static_cast<int32_t>(ImmersiveMode::LIGHT_IMMERSIVE);
665     ret = inputMethodController_->Attach(textListener, false, config);
666     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
667 
668     TextTotalConfig totalConfig;
669     ret = inputMethodAbility_.GetTextConfig(totalConfig);
670     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
671 
672     EXPECT_EQ(totalConfig.inputAttribute, config.inputAttribute);
673 }
674 
675 /**
676  * @tc.name: testSetCallingWindow
677  * @tc.desc: test SetCallingWindow after attach
678  * @tc.type: FUNC
679  */
680 HWTEST_F(InputMethodAttachTest, testSetCallingWindow, TestSize.Level0)
681 {
682     IMSA_HILOGI("test testSetCallingWindow.");
683     sptr<OnTextChangedListener> textListener = new TextListener();
684     auto ret = inputMethodController_->Attach(textListener);
685     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
686 
687     uint32_t windowId = 88;
688     ret = inputMethodController_->SetCallingWindow(windowId);
689     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
690 
691     InputAttribute attribute;
692     attribute.inputPattern = 3;
693     attribute.enterKeyType = 2;
694     TextConfig config;
695     config.windowId = 77;
696     ret = inputMethodController_->Attach(textListener, false, config);
697     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
698 
699     TextTotalConfig totalConfig;
700     ret = inputMethodAbility_.GetTextConfig(totalConfig);
701     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
702 
703     EXPECT_EQ(totalConfig.windowId, config.windowId);
704 }
705 /**
706  * @tc.name: testImeCallbackInAttach
707  * @tc.desc: test ime can receive callback in Attach
708  * @tc.type: FUNC
709  */
710 HWTEST_F(InputMethodAttachTest, testImeCallbackInAttach, TestSize.Level0)
711 {
712     IMSA_HILOGI("test testImeCallbackInAttach.");
713     inputMethodAbility_.SetImeListener(std::make_shared<InputMethodEngineListenerImpl>());
714     inputMethodAbility_.SetKdListener(std::make_shared<KeyboardListenerTestImpl>());
715     sptr<OnTextChangedListener> textListener = new TextListener();
716     InputMethodEngineListenerImpl::ResetParam();
717     KeyboardListenerTestImpl::ResetParam();
718     InputAttribute attribute;
719     attribute.inputPattern = 3;
720     attribute.enterKeyType = 2;
721     TextConfig config;
722     config.inputAttribute = attribute;
723     CursorInfo cursorInfo;
724     cursorInfo.left = 0;
725     cursorInfo.top = 1;
726     cursorInfo.width = 0.5;
727     cursorInfo.height = 1.2;
728     config.cursorInfo = cursorInfo;
729     Range selectionRange;
730     selectionRange.start = 5;
731     selectionRange.end = 2;
732     config.range = selectionRange;
733     config.windowId = 10;
734     auto ret = inputMethodController_->Attach(textListener, true, config);
735     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
736 
737     EXPECT_TRUE(KeyboardListenerTestImpl::WaitSelectionChange(selectionRange.start));
738     EXPECT_TRUE(KeyboardListenerTestImpl::WaitCursorUpdate());
739     EXPECT_TRUE(KeyboardListenerTestImpl::WaitEditorAttributeChange(attribute));
740     EXPECT_TRUE(InputMethodEngineListenerImpl::WaitSetCallingWindow(config.windowId));
741 }
742 
743 /**
744  * @tc.name: TestImfMultiThreadAttach
745  * @tc.desc: test ime Attach in multi-thread
746  * @tc.type: FUNC
747  * @tc.require:
748  * @tc.author: mashaoyin
749  */
750 HWTEST_F(InputMethodAttachTest, multiThreadAttachTest_001, TestSize.Level0)
751 {
752     IMSA_HILOGI("InputMethodAttachTest multiThreadAttachTest_001 START");
753     SET_THREAD_NUM(5);
754     GTEST_RUN_TASK(InputMethodAttachTest::TestImfMultiThreadAttach);
755 }
756 
757 /**
758  * @tc.name: testAttach007
759  * @tc.desc: test Attach
760  * @tc.type: FUNC
761  */
762 HWTEST_F(InputMethodAttachTest, testAttach007, TestSize.Level0)
763 {
764     IMSA_HILOGI("test testAttach007 after attach.");
765     sptr<OnTextChangedListener> textListener = new TextListener();
766     InputAttribute attribute;
767     attribute.inputPattern = 3;
768     attribute.enterKeyType = 2;
769     TextConfig config;
770     config.inputAttribute = attribute;
771     AttachOptions attachOptions;
772     attachOptions.isShowKeyboard = false;
773     attachOptions.requestKeyboardReason = RequestKeyboardReason::NONE;
774     auto ret = inputMethodController_->Attach(textListener, attachOptions, config);
775     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
776 
777     int32_t keyType = -1;
778     ret = inputMethodAbility_.GetEnterKeyType(keyType);
779     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
780     EXPECT_EQ(keyType, config.inputAttribute.enterKeyType);
781     int32_t inputPattern = -1;
782     ret = inputMethodAbility_.GetInputPattern(inputPattern);
783     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
784     EXPECT_EQ(inputPattern, config.inputAttribute.inputPattern);
785 }
786 
787 /**
788  * @tc.name: testSetCapitalizeMode_001
789  * @tc.desc: test set capitalizeMode after attach
790  * @tc.type: FUNC
791  */
792 HWTEST_F(InputMethodAttachTest, testSetCapitalizeMode_001, TestSize.Level0)
793 {
794     IMSA_HILOGI("test testSetCapitalizeMode_001.");
795     sptr<OnTextChangedListener> textListener = new TextListener();
796     InputAttribute attribute;
797     attribute.inputPattern = 0;
798     attribute.enterKeyType = 0;
799     TextConfig config;
800     config.inputAttribute = attribute;
801     config.inputAttribute.capitalizeMode = CapitalizeMode::WORDS;
802     auto ret = inputMethodController_->Attach(textListener, false, config);
803     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
804     TextTotalConfig totalConfig;
805     ret = inputMethodAbility_.GetTextConfig(totalConfig);
806     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
807     EXPECT_EQ(totalConfig.inputAttribute.capitalizeMode, config.inputAttribute.capitalizeMode);
808 }
809 
810 /**
811  * @tc.name: testAttach008
812  * @tc.desc: test set simple keyboard after attach
813  * @tc.type: FUNC
814  */
815 HWTEST_F(InputMethodAttachTest, testAttach008, TestSize.Level0)
816 {
817     IMSA_HILOGI("test testAttach008 after attach.");
818     sptr<OnTextChangedListener> textListener = new TextListener();
819     InputAttribute attribute;
820     attribute.inputPattern = 3;
821     attribute.enterKeyType = 2;
822     TextConfig config;
823     config.inputAttribute = attribute;
824     AttachOptions attachOptions;
825     attachOptions.isShowKeyboard = false;
826     attachOptions.requestKeyboardReason = RequestKeyboardReason::NONE;
827     inputMethodController_->clientInfo_.config.isSimpleKeyboardEnabled = true;
828     auto ret = inputMethodController_->Attach(textListener, attachOptions, config);
829     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
830     inputMethodController_->clientInfo_.config.isSimpleKeyboardEnabled = false;
831     ret = inputMethodController_->Attach(textListener, attachOptions, config);
832     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
833 }
834 
835 /**
836  * @tc.name: testAttach009
837  * @tc.desc: test set simple keyboard after attach
838  * @tc.type: FUNC
839  */
840 HWTEST_F(InputMethodAttachTest, testAttach009, TestSize.Level0)
841 {
842     IMSA_HILOGI("test testAttach009 after attach.");
843     sptr<OnTextChangedListener> textListener = new TextListener();
844     InputAttribute attribute;
845     attribute.inputPattern = 8;
846     attribute.enterKeyType = 2;
847     TextConfig config;
848     config.inputAttribute = attribute;
849     AttachOptions attachOptions;
850     attachOptions.isShowKeyboard = false;
851     attachOptions.requestKeyboardReason = RequestKeyboardReason::NONE;
852     inputMethodController_->clientInfo_.config.isSimpleKeyboardEnabled = true;
853     auto ret = inputMethodController_->Attach(textListener, attachOptions, config);
854     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
855 }
856 
857 /**
858  * @tc.name: testOninputstop001
859  * @tc.desc: test OnInputStop callback
860  * @tc.type: FUNC
861  */
862 HWTEST_F(InputMethodAttachTest, testOninputstop001, TestSize.Level0)
863 {
864     IMSA_HILOGI("test testOninputstop001 start!");
865     sptr<OnTextChangedListener> textListener = new TextListener();
866     ASSERT_NE(textListener, nullptr);
867     auto ret = inputMethodController_->Attach(textListener);
868     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
869     ret = inputMethodController_->Close();
870     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
871 }
872 } // namespace MiscServices
873 } // namespace OHOS
874