• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-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 #define private public
16 #define protected public
17 #include "input_method_controller.h"
18 
19 #include "input_method_ability.h"
20 #include "input_method_system_ability.h"
21 #undef private
22 
23 #include <event_handler.h>
24 #include <gtest/gtest.h>
25 #include <string_ex.h>
26 #include <sys/time.h>
27 
28 #include <condition_variable>
29 #include <csignal>
30 #include <cstdint>
31 #include <functional>
32 #include <mutex>
33 #include <string>
34 #include <thread>
35 #include <unordered_map>
36 #include <vector>
37 
38 #include "ability_manager_client.h"
39 #include "block_data.h"
40 #include "global.h"
41 #include "i_input_method_agent.h"
42 #include "i_input_method_system_ability.h"
43 #include "if_system_ability_manager.h"
44 #include "input_client_stub.h"
45 
46 #include "enable_ime_data_parser.h"
47 #include "input_data_channel_stub.h"
48 #include "input_death_recipient.h"
49 #include "input_method_ability.h"
50 #include "input_method_engine_listener_impl.h"
51 #include "input_method_system_ability_proxy.h"
52 #include "input_method_utils.h"
53 #include "ime_info_inquirer.h"
54 #include "iservice_registry.h"
55 #include "key_event_util.h"
56 #include "keyboard_listener.h"
57 #include "message_parcel.h"
58 #include "scope_utils.h"
59 #include "security_mode_parser.h"
60 #include "system_ability.h"
61 #include "system_ability_definition.h"
62 #include "tdd_util.h"
63 #include "text_listener.h"
64 #include "identity_checker_mock.h"
65 using namespace testing;
66 using namespace testing::ext;
67 namespace OHOS {
68 namespace MiscServices {
69 constexpr uint32_t RETRY_TIME = 200 * 1000;
70 constexpr uint32_t RETRY_TIMES = 5;
71 constexpr uint32_t WAIT_INTERVAL = 500;
72 constexpr size_t PRIVATE_COMMAND_SIZE_MAX = 32 * 1024;
73 constexpr uint32_t WAIT_SA_DIE_TIME_OUT = 3;
74 const std::string IME_KEY = "settings.inputmethod.enable_ime";
75 
76 class SelectListenerMock : public ControllerListener {
77 public:
78     SelectListenerMock() = default;
79     ~SelectListenerMock() override = default;
80 
OnSelectByRange(int32_t start,int32_t end)81     void OnSelectByRange(int32_t start, int32_t end) override
82     {
83         start_ = start;
84         end_ = end;
85         selectListenerCv_.notify_all();
86     }
87 
OnSelectByMovement(int32_t direction)88     void OnSelectByMovement(int32_t direction) override
89     {
90         direction_ = direction;
91         selectListenerCv_.notify_all();
92     }
93     static void WaitSelectListenerCallback();
94     static int32_t start_;
95     static int32_t end_;
96     static int32_t direction_;
97     static std::mutex selectListenerMutex_;
98     static std::condition_variable selectListenerCv_;
99 };
100 
101 int32_t SelectListenerMock::start_ = 0;
102 int32_t SelectListenerMock::end_ = 0;
103 int32_t SelectListenerMock::direction_ = 0;
104 std::mutex SelectListenerMock::selectListenerMutex_;
105 std::condition_variable SelectListenerMock::selectListenerCv_;
WaitSelectListenerCallback()106 void SelectListenerMock::WaitSelectListenerCallback()
107 {
108     std::unique_lock<std::mutex> lock(selectListenerMutex_);
109     selectListenerCv_.wait_for(lock, std::chrono::milliseconds(WAIT_INTERVAL));
110 }
111 
112 class InputMethodControllerTest : public testing::Test {
113 public:
114     static void SetUpTestCase(void);
115     static void TearDownTestCase(void);
116     void SetUp();
117     void TearDown();
118     static void SetInputDeathRecipient();
119     static void OnRemoteSaDied(const wptr<IRemoteObject> &remote);
120     static void CheckKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent);
121     static bool WaitRemoteDiedCallback();
122     static void WaitKeyboardStatusCallback(bool keyboardState);
123     static void TriggerConfigurationChangeCallback(Configuration &info);
124     static void TriggerCursorUpdateCallback(CursorInfo &info);
125     static void TriggerSelectionChangeCallback(std::u16string &text, int start, int end);
126     static void CheckProxyObject();
127     static void DispatchKeyEventCallback(std::shared_ptr<MMI::KeyEvent> &keyEvent, bool isConsumed);
128     static bool WaitKeyEventCallback();
129     static void CheckTextConfig(const TextConfig &config);
130     static void ResetKeyboardListenerTextConfig();
131     static sptr<InputMethodController> inputMethodController_;
132     static sptr<InputMethodAbility> inputMethodAbility_;
133     static sptr<InputMethodSystemAbility> imsa_;
134     static sptr<InputMethodSystemAbilityProxy> imsaProxy_;
135     static std::shared_ptr<MMI::KeyEvent> keyEvent_;
136     static std::shared_ptr<InputMethodEngineListenerImpl> imeListener_;
137     static std::shared_ptr<SelectListenerMock> controllerListener_;
138     static sptr<OnTextChangedListener> textListener_;
139     static std::mutex keyboardListenerMutex_;
140     static std::condition_variable keyboardListenerCv_;
141     static BlockData<std::shared_ptr<MMI::KeyEvent>> blockKeyEvent_;
142     static BlockData<std::shared_ptr<MMI::KeyEvent>> blockFullKeyEvent_;
143     static std::mutex onRemoteSaDiedMutex_;
144     static std::condition_variable onRemoteSaDiedCv_;
145     static sptr<InputDeathRecipient> deathRecipient_;
146     static CursorInfo cursorInfo_;
147     static int32_t oldBegin_;
148     static int32_t oldEnd_;
149     static int32_t newBegin_;
150     static int32_t newEnd_;
151     static std::string text_;
152     static bool doesKeyEventConsume_;
153     static bool doesFUllKeyEventConsume_;
154     static std::condition_variable keyEventCv_;
155     static std::mutex keyEventLock_;
156     static bool consumeResult_;
157     static InputAttribute inputAttribute_;
158     static std::shared_ptr<AppExecFwk::EventHandler> textConfigHandler_;
159     static constexpr uint32_t DELAY_TIME = 1;
160     static constexpr uint32_t KEY_EVENT_DELAY_TIME = 100;
161     static constexpr int32_t TASK_DELAY_TIME = 10;
162 
163     class KeyboardListenerImpl : public KeyboardListener {
164     public:
KeyboardListenerImpl()165         KeyboardListenerImpl()
166         {
167             std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create("InputMethodControllerTe"
168                                                                                               "st");
169             textConfigHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
170         };
~KeyboardListenerImpl()171         ~KeyboardListenerImpl(){};
OnKeyEvent(int32_t keyCode,int32_t keyStatus,sptr<KeyEventConsumerProxy> & consumer)172         bool OnKeyEvent(int32_t keyCode, int32_t keyStatus, sptr<KeyEventConsumerProxy> &consumer) override
173         {
174             if (!doesKeyEventConsume_) {
175                 IMSA_HILOGI("KeyboardListenerImpl doesKeyEventConsume_ false");
176                 return false;
177             }
178             IMSA_HILOGI("KeyboardListenerImpl::OnKeyEvent %{public}d %{public}d", keyCode, keyStatus);
179             auto keyEvent = KeyEventUtil::CreateKeyEvent(keyCode, keyStatus);
180             blockKeyEvent_.SetValue(keyEvent);
181             return true;
182         }
OnKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent,sptr<KeyEventConsumerProxy> & consumer)183         bool OnKeyEvent(const std::shared_ptr<MMI::KeyEvent> &keyEvent, sptr<KeyEventConsumerProxy> &consumer) override
184         {
185             if (!doesFUllKeyEventConsume_) {
186                 IMSA_HILOGI("KeyboardListenerImpl doesFUllKeyEventConsume_ false");
187                 return false;
188             }
189             IMSA_HILOGI("KeyboardListenerImpl::OnKeyEvent %{public}d %{public}d", keyEvent->GetKeyCode(),
190                 keyEvent->GetKeyAction());
191             auto fullKey = keyEvent;
192             blockFullKeyEvent_.SetValue(fullKey);
193             return true;
194         }
OnDealKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent,sptr<KeyEventConsumerProxy> & consumer)195         bool OnDealKeyEvent(
196             const std::shared_ptr<MMI::KeyEvent> &keyEvent, sptr<KeyEventConsumerProxy> &consumer) override
197         {
198             IMSA_HILOGI("KeyboardListenerImpl run in");
199             bool isKeyCodeConsume = OnKeyEvent(keyEvent->GetKeyCode(), keyEvent->GetKeyAction(), consumer);
200             bool isKeyEventConsume = OnKeyEvent(keyEvent, consumer);
201             if (consumer != nullptr) {
202                 consumer->OnKeyEventResult(isKeyEventConsume | isKeyCodeConsume);
203             }
204             return true;
205         }
OnCursorUpdate(int32_t positionX,int32_t positionY,int32_t height)206         void OnCursorUpdate(int32_t positionX, int32_t positionY, int32_t height) override
207         {
208             IMSA_HILOGI("KeyboardListenerImpl %{public}d %{public}d %{public}d", positionX, positionY, height);
209             cursorInfo_ = { static_cast<double>(positionX), static_cast<double>(positionY), 0,
210                 static_cast<double>(height) };
211             InputMethodControllerTest::keyboardListenerCv_.notify_one();
212         }
OnSelectionChange(int32_t oldBegin,int32_t oldEnd,int32_t newBegin,int32_t newEnd)213         void OnSelectionChange(int32_t oldBegin, int32_t oldEnd, int32_t newBegin, int32_t newEnd) override
214         {
215             IMSA_HILOGI("KeyboardListenerImpl %{public}d %{public}d %{public}d %{public}d", oldBegin, oldEnd, newBegin,
216                 newEnd);
217             oldBegin_ = oldBegin;
218             oldEnd_ = oldEnd;
219             newBegin_ = newBegin;
220             newEnd_ = newEnd;
221             InputMethodControllerTest::keyboardListenerCv_.notify_one();
222         }
OnTextChange(const std::string & text)223         void OnTextChange(const std::string &text) override
224         {
225             IMSA_HILOGI("KeyboardListenerImpl text: %{public}s", text.c_str());
226             text_ = text;
227             InputMethodControllerTest::keyboardListenerCv_.notify_one();
228         }
OnEditorAttributeChange(const InputAttribute & inputAttribute)229         void OnEditorAttributeChange(const InputAttribute &inputAttribute) override
230         {
231             IMSA_HILOGI("KeyboardListenerImpl inputPattern: %{public}d, enterKeyType: %{public}d, "
232                         "isTextPreviewSupported: %{public}d",
233                 inputAttribute.inputPattern, inputAttribute.enterKeyType, inputAttribute.isTextPreviewSupported);
234             inputAttribute_ = inputAttribute;
235             InputMethodControllerTest::keyboardListenerCv_.notify_one();
236         }
237     };
238 };
239 sptr<InputMethodController> InputMethodControllerTest::inputMethodController_;
240 sptr<InputMethodAbility> InputMethodControllerTest::inputMethodAbility_;
241 sptr<InputMethodSystemAbility> InputMethodControllerTest::imsa_;
242 sptr<InputMethodSystemAbilityProxy> InputMethodControllerTest::imsaProxy_;
243 std::shared_ptr<MMI::KeyEvent> InputMethodControllerTest::keyEvent_;
244 std::shared_ptr<InputMethodEngineListenerImpl> InputMethodControllerTest::imeListener_;
245 std::shared_ptr<SelectListenerMock> InputMethodControllerTest::controllerListener_;
246 sptr<OnTextChangedListener> InputMethodControllerTest::textListener_;
247 CursorInfo InputMethodControllerTest::cursorInfo_ = {};
248 int32_t InputMethodControllerTest::oldBegin_ = 0;
249 int32_t InputMethodControllerTest::oldEnd_ = 0;
250 int32_t InputMethodControllerTest::newBegin_ = 0;
251 int32_t InputMethodControllerTest::newEnd_ = 0;
252 std::string InputMethodControllerTest::text_;
253 InputAttribute InputMethodControllerTest::inputAttribute_;
254 std::mutex InputMethodControllerTest::keyboardListenerMutex_;
255 std::condition_variable InputMethodControllerTest::keyboardListenerCv_;
256 sptr<InputDeathRecipient> InputMethodControllerTest::deathRecipient_;
257 std::mutex InputMethodControllerTest::onRemoteSaDiedMutex_;
258 std::condition_variable InputMethodControllerTest::onRemoteSaDiedCv_;
259 BlockData<std::shared_ptr<MMI::KeyEvent>> InputMethodControllerTest::blockKeyEvent_{
260     InputMethodControllerTest::KEY_EVENT_DELAY_TIME, nullptr
261 };
262 BlockData<std::shared_ptr<MMI::KeyEvent>> InputMethodControllerTest::blockFullKeyEvent_{
263     InputMethodControllerTest::KEY_EVENT_DELAY_TIME, nullptr
264 };
265 bool InputMethodControllerTest::doesKeyEventConsume_{ false };
266 bool InputMethodControllerTest::doesFUllKeyEventConsume_{ false };
267 std::condition_variable InputMethodControllerTest::keyEventCv_;
268 std::mutex InputMethodControllerTest::keyEventLock_;
269 bool InputMethodControllerTest::consumeResult_{ false };
270 std::shared_ptr<AppExecFwk::EventHandler> InputMethodControllerTest::textConfigHandler_{ nullptr };
271 
SetUpTestCase(void)272 void InputMethodControllerTest::SetUpTestCase(void)
273 {
274     IMSA_HILOGI("InputMethodControllerTest::SetUpTestCase");
275     IdentityCheckerMock::ResetParam();
276     imsa_ = new (std::nothrow) InputMethodSystemAbility();
277     if (imsa_ == nullptr) {
278         return;
279     }
280     imsa_->OnStart();
281     imsa_->userId_ = TddUtil::GetCurrentUserId();
282     imsa_->identityChecker_ = std::make_shared<IdentityCheckerMock>();
283     sptr<InputMethodSystemAbilityStub> serviceStub = imsa_;
284     imsaProxy_ = new (std::nothrow) InputMethodSystemAbilityProxy(serviceStub->AsObject());
285     if (imsaProxy_ == nullptr) {
286         return;
287     }
288     IdentityCheckerMock::SetFocused(true);
289 
290     inputMethodAbility_ = InputMethodAbility::GetInstance();
291     inputMethodAbility_->abilityManager_ = imsaProxy_;
292     TddUtil::InitCurrentImePermissionInfo();
293     IdentityCheckerMock::SetBundleName(TddUtil::currentBundleNameMock_);
294     inputMethodAbility_->SetCoreAndAgent();
295     imeListener_ = std::make_shared<InputMethodEngineListenerImpl>();
296     controllerListener_ = std::make_shared<SelectListenerMock>();
297     textListener_ = new TextListener();
298     inputMethodAbility_->SetKdListener(std::make_shared<KeyboardListenerImpl>());
299     inputMethodAbility_->SetImeListener(imeListener_);
300 
301     inputMethodController_ = InputMethodController::GetInstance();
302     inputMethodController_->abilityManager_ = imsaProxy_;
303 
304     keyEvent_ = KeyEventUtil::CreateKeyEvent(MMI::KeyEvent::KEYCODE_A, MMI::KeyEvent::KEY_ACTION_DOWN);
305     keyEvent_->SetFunctionKey(MMI::KeyEvent::NUM_LOCK_FUNCTION_KEY, 0);
306     keyEvent_->SetFunctionKey(MMI::KeyEvent::CAPS_LOCK_FUNCTION_KEY, 1);
307     keyEvent_->SetFunctionKey(MMI::KeyEvent::SCROLL_LOCK_FUNCTION_KEY, 1);
308 
309     SetInputDeathRecipient();
310     TextListener::ResetParam();
311 }
312 
TearDownTestCase(void)313 void InputMethodControllerTest::TearDownTestCase(void)
314 {
315     IMSA_HILOGI("InputMethodControllerTest::TearDownTestCase");
316     TextListener::ResetParam();
317     inputMethodController_->SetControllerListener(nullptr);
318     IdentityCheckerMock::ResetParam();
319     imsa_->OnStop();
320 }
321 
SetUp(void)322 void InputMethodControllerTest::SetUp(void)
323 {
324     IMSA_HILOGI("InputMethodControllerTest::SetUp");
325 }
326 
TearDown(void)327 void InputMethodControllerTest::TearDown(void)
328 {
329     IMSA_HILOGI("InputMethodControllerTest::TearDown");
330 }
331 
SetInputDeathRecipient()332 void InputMethodControllerTest::SetInputDeathRecipient()
333 {
334     IMSA_HILOGI("InputMethodControllerTest::SetInputDeathRecipient");
335     sptr<ISystemAbilityManager> systemAbilityManager =
336         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
337     if (systemAbilityManager == nullptr) {
338         IMSA_HILOGI("InputMethodControllerTest, system ability manager is nullptr");
339         return;
340     }
341     auto systemAbility = systemAbilityManager->GetSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID, "");
342     if (systemAbility == nullptr) {
343         IMSA_HILOGI("InputMethodControllerTest, system ability is nullptr");
344         return;
345     }
346     deathRecipient_ = new (std::nothrow) InputDeathRecipient();
347     if (deathRecipient_ == nullptr) {
348         IMSA_HILOGE("InputMethodControllerTest, new death recipient failed");
349         return;
350     }
351     deathRecipient_->SetDeathRecipient([](const wptr<IRemoteObject> &remote) { OnRemoteSaDied(remote); });
352     if ((systemAbility->IsProxyObject()) && (!systemAbility->AddDeathRecipient(deathRecipient_))) {
353         IMSA_HILOGE("InputMethodControllerTest, failed to add death recipient.");
354         return;
355     }
356 }
357 
OnRemoteSaDied(const wptr<IRemoteObject> & remote)358 void InputMethodControllerTest::OnRemoteSaDied(const wptr<IRemoteObject> &remote)
359 {
360     IMSA_HILOGI("InputMethodControllerTest::OnRemoteSaDied");
361     onRemoteSaDiedCv_.notify_one();
362 }
363 
WaitRemoteDiedCallback()364 bool InputMethodControllerTest::WaitRemoteDiedCallback()
365 {
366     IMSA_HILOGI("InputMethodControllerTest::WaitRemoteDiedCallback");
367     std::unique_lock<std::mutex> lock(onRemoteSaDiedMutex_);
368     return onRemoteSaDiedCv_.wait_for(lock, std::chrono::seconds(WAIT_SA_DIE_TIME_OUT)) != std::cv_status::timeout;
369 }
370 
CheckProxyObject()371 void InputMethodControllerTest::CheckProxyObject()
372 {
373     for (uint32_t retryTimes = 0; retryTimes < RETRY_TIMES; ++retryTimes) {
374         IMSA_HILOGI("times = %{public}d", retryTimes);
375         sptr<ISystemAbilityManager> systemAbilityManager =
376             SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
377         if (systemAbilityManager == nullptr) {
378             IMSA_HILOGI("system ability manager is nullptr");
379             continue;
380         }
381         auto systemAbility = systemAbilityManager->CheckSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID);
382         if (systemAbility != nullptr) {
383             IMSA_HILOGI("CheckProxyObject success!");
384             break;
385         }
386         usleep(RETRY_TIME);
387     }
388 }
389 
CheckKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)390 void InputMethodControllerTest::CheckKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)
391 {
392     ASSERT_NE(keyEvent, nullptr);
393     bool ret = keyEvent->GetKeyCode() == keyEvent_->GetKeyCode();
394     EXPECT_TRUE(ret);
395     ret = keyEvent->GetKeyAction() == keyEvent_->GetKeyAction();
396     EXPECT_TRUE(ret);
397     ret = keyEvent->GetKeyIntention() == keyEvent_->GetKeyIntention();
398     EXPECT_TRUE(ret);
399     // check function key state
400     ret = keyEvent->GetFunctionKey(MMI::KeyEvent::NUM_LOCK_FUNCTION_KEY)
401           == keyEvent_->GetFunctionKey(MMI::KeyEvent::NUM_LOCK_FUNCTION_KEY);
402     EXPECT_TRUE(ret);
403     ret = keyEvent->GetFunctionKey(MMI::KeyEvent::CAPS_LOCK_FUNCTION_KEY)
404           == keyEvent_->GetFunctionKey(MMI::KeyEvent::CAPS_LOCK_FUNCTION_KEY);
405     EXPECT_TRUE(ret);
406     ret = keyEvent->GetFunctionKey(MMI::KeyEvent::SCROLL_LOCK_FUNCTION_KEY)
407           == keyEvent_->GetFunctionKey(MMI::KeyEvent::SCROLL_LOCK_FUNCTION_KEY);
408     EXPECT_TRUE(ret);
409     // check KeyItem
410     ret = keyEvent->GetKeyItems().size() == keyEvent_->GetKeyItems().size();
411     EXPECT_TRUE(ret);
412     ret = keyEvent->GetKeyItem()->GetKeyCode() == keyEvent_->GetKeyItem()->GetKeyCode();
413     EXPECT_TRUE(ret);
414     ret = keyEvent->GetKeyItem()->GetDownTime() == keyEvent_->GetKeyItem()->GetDownTime();
415     EXPECT_TRUE(ret);
416     ret = keyEvent->GetKeyItem()->GetDeviceId() == keyEvent_->GetKeyItem()->GetDeviceId();
417     EXPECT_TRUE(ret);
418     ret = keyEvent->GetKeyItem()->IsPressed() == keyEvent_->GetKeyItem()->IsPressed();
419     EXPECT_TRUE(ret);
420     ret = keyEvent->GetKeyItem()->GetUnicode() == keyEvent_->GetKeyItem()->GetUnicode();
421     EXPECT_TRUE(ret);
422 }
423 
WaitKeyboardStatusCallback(bool keyboardState)424 void InputMethodControllerTest::WaitKeyboardStatusCallback(bool keyboardState)
425 {
426     std::unique_lock<std::mutex> lock(InputMethodEngineListenerImpl::imeListenerMutex_);
427     InputMethodEngineListenerImpl::imeListenerCv_.wait_for(lock,
428         std::chrono::seconds(InputMethodControllerTest::DELAY_TIME),
429         [keyboardState] { return InputMethodEngineListenerImpl::keyboardState_ == keyboardState; });
430 }
431 
TriggerConfigurationChangeCallback(Configuration & info)432 void InputMethodControllerTest::TriggerConfigurationChangeCallback(Configuration &info)
433 {
434     textConfigHandler_->PostTask(
435         [info]() { inputMethodController_->OnConfigurationChange(info); }, InputMethodControllerTest::TASK_DELAY_TIME);
436     {
437         std::unique_lock<std::mutex> lock(InputMethodControllerTest::keyboardListenerMutex_);
438         InputMethodControllerTest::keyboardListenerCv_.wait_for(
439             lock, std::chrono::seconds(InputMethodControllerTest::DELAY_TIME), [&info] {
440                 return (static_cast<OHOS::MiscServices::TextInputType>(
441                             InputMethodControllerTest::inputAttribute_.inputPattern)
442                            == info.GetTextInputType())
443                        && (static_cast<OHOS::MiscServices::EnterKeyType>(
444                                InputMethodControllerTest::inputAttribute_.enterKeyType)
445                            == info.GetEnterKeyType());
446             });
447     }
448 }
449 
TriggerCursorUpdateCallback(CursorInfo & info)450 void InputMethodControllerTest::TriggerCursorUpdateCallback(CursorInfo &info)
451 {
452     textConfigHandler_->PostTask(
453         [info]() { inputMethodController_->OnCursorUpdate(info); }, InputMethodControllerTest::TASK_DELAY_TIME);
454     {
455         std::unique_lock<std::mutex> lock(InputMethodControllerTest::keyboardListenerMutex_);
456         InputMethodControllerTest::keyboardListenerCv_.wait_for(lock,
457             std::chrono::seconds(InputMethodControllerTest::DELAY_TIME),
458             [&info] { return InputMethodControllerTest::cursorInfo_ == info; });
459     }
460 }
461 
TriggerSelectionChangeCallback(std::u16string & text,int start,int end)462 void InputMethodControllerTest::TriggerSelectionChangeCallback(std::u16string &text, int start, int end)
463 {
464     IMSA_HILOGI("InputMethodControllerTest run in");
465     textConfigHandler_->PostTask([text, start, end]() { inputMethodController_->OnSelectionChange(text, start, end); },
466         InputMethodControllerTest::TASK_DELAY_TIME);
467     {
468         std::unique_lock<std::mutex> lock(InputMethodControllerTest::keyboardListenerMutex_);
469         InputMethodControllerTest::keyboardListenerCv_.wait_for(
470             lock, std::chrono::seconds(InputMethodControllerTest::DELAY_TIME), [&text, start, end] {
471                 return InputMethodControllerTest::text_ == Str16ToStr8(text)
472                        && InputMethodControllerTest::newBegin_ == start && InputMethodControllerTest::newEnd_ == end;
473             });
474     }
475     IMSA_HILOGI("InputMethodControllerTest end");
476 }
477 
CheckTextConfig(const TextConfig & config)478 void InputMethodControllerTest::CheckTextConfig(const TextConfig &config)
479 {
480     EXPECT_EQ(imeListener_->windowId_, config.windowId);
481     EXPECT_EQ(cursorInfo_.left, config.cursorInfo.left);
482     EXPECT_EQ(cursorInfo_.top, config.cursorInfo.top);
483     EXPECT_EQ(cursorInfo_.height, config.cursorInfo.height);
484     EXPECT_EQ(newBegin_, config.range.start);
485     EXPECT_EQ(newEnd_, config.range.end);
486     EXPECT_EQ(inputAttribute_.inputPattern, config.inputAttribute.inputPattern);
487     EXPECT_EQ(inputAttribute_.enterKeyType, config.inputAttribute.enterKeyType);
488 }
489 
DispatchKeyEventCallback(std::shared_ptr<MMI::KeyEvent> & keyEvent,bool isConsumed)490 void InputMethodControllerTest::DispatchKeyEventCallback(std::shared_ptr<MMI::KeyEvent> &keyEvent, bool isConsumed)
491 {
492     IMSA_HILOGI("InputMethodControllerTest isConsumed: %{public}d", isConsumed);
493     consumeResult_ = isConsumed;
494     keyEventCv_.notify_one();
495 }
496 
WaitKeyEventCallback()497 bool InputMethodControllerTest::WaitKeyEventCallback()
498 {
499     std::unique_lock<std::mutex> lock(keyEventLock_);
500     keyEventCv_.wait_for(lock, std::chrono::seconds(DELAY_TIME), [] { return consumeResult_; });
501     return consumeResult_;
502 }
503 
ResetKeyboardListenerTextConfig()504 void InputMethodControllerTest::ResetKeyboardListenerTextConfig()
505 {
506     cursorInfo_ = {};
507     oldBegin_ = INVALID_VALUE;
508     oldEnd_ = INVALID_VALUE;
509     newBegin_ = INVALID_VALUE;
510     newEnd_ = INVALID_VALUE;
511     text_ = "";
512     inputAttribute_ = {};
513 }
514 
515 /**
516  * @tc.name: testIMCAttach001
517  * @tc.desc: IMC Attach.
518  * @tc.type: FUNC
519  * @tc.require:
520  */
521 HWTEST_F(InputMethodControllerTest, testIMCAttach001, TestSize.Level0)
522 {
523     IMSA_HILOGI("IMC testIMCAttach001 Test START");
524     imeListener_->isInputStart_ = false;
525     TextListener::ResetParam();
526     inputMethodController_->Attach(textListener_, false);
527     inputMethodController_->Attach(textListener_);
528     inputMethodController_->Attach(textListener_, true);
529     EXPECT_TRUE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::SHOW));
530     EXPECT_TRUE(imeListener_->isInputStart_ && imeListener_->keyboardState_);
531 }
532 
533 /**
534  * @tc.name: testIMCAttach002
535  * @tc.desc: IMC Attach.
536  * @tc.type: FUNC
537  * @tc.require:
538  */
539 HWTEST_F(InputMethodControllerTest, testIMCAttach002, TestSize.Level0)
540 {
541     IMSA_HILOGI("IMC testIMCAttach002 Test START");
542     TextListener::ResetParam();
543     CursorInfo cursorInfo = { 1, 1, 1, 1 };
544     Range selectionRange = { 1, 2 };
545     InputAttribute attribute = { 1, 1 };
546     uint32_t windowId = 10;
547     TextConfig textConfig = {
548         .inputAttribute = attribute, .cursorInfo = cursorInfo, .range = selectionRange, .windowId = windowId
549     };
550 
551     inputMethodController_->Attach(textListener_, true, textConfig);
552     InputMethodControllerTest::CheckTextConfig(textConfig);
553 
554     TextListener::ResetParam();
555     cursorInfo = { 2, 2, 2, 2 };
556     selectionRange = { 3, 4 };
557     attribute = { 2, 2 };
558     windowId = 11;
559     textConfig = {
560         .inputAttribute = attribute, .cursorInfo = cursorInfo, .range = selectionRange, .windowId = windowId
561     };
562     inputMethodController_->Attach(textListener_, true, textConfig);
563     InputMethodControllerTest::CheckTextConfig(textConfig);
564 }
565 
566 /**
567  * @tc.name: testIMCSetCallingWindow
568  * @tc.desc: IMC SetCallingWindow.
569  * @tc.type: FUNC
570  * @tc.require:
571  */
572 HWTEST_F(InputMethodControllerTest, testIMCSetCallingWindow, TestSize.Level0)
573 {
574     IMSA_HILOGI("IMC SetCallingWindow Test START");
575     auto ret = inputMethodController_->Attach(textListener_);
576     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
577     uint32_t windowId = 3;
578     ret = inputMethodController_->SetCallingWindow(windowId);
579     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
580     EXPECT_EQ(windowId, imeListener_->windowId_);
581 }
582 
583 /**
584  * @tc.name: testGetIMSAProxy
585  * @tc.desc: Get Imsa Proxy.
586  * @tc.type: FUNC
587  */
588 HWTEST_F(InputMethodControllerTest, testGetIMSAProxy, TestSize.Level0)
589 {
590     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
591     ASSERT_NE(systemAbilityManager, nullptr);
592     auto systemAbility = systemAbilityManager->GetSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID, "");
593     EXPECT_TRUE(systemAbility != nullptr);
594 }
595 
596 /**
597  * @tc.name: testWriteReadIInputDataChannel
598  * @tc.desc: Checkout IInputDataChannel.
599  * @tc.type: FUNC
600  */
601 HWTEST_F(InputMethodControllerTest, testWriteReadIInputDataChannel, TestSize.Level0)
602 {
603     sptr<InputDataChannelStub> mInputDataChannel = new InputDataChannelStub();
604     MessageParcel data;
605     auto ret = data.WriteRemoteObject(mInputDataChannel->AsObject());
606     EXPECT_TRUE(ret);
607     auto remoteObject = data.ReadRemoteObject();
608     sptr<IInputDataChannel> iface = iface_cast<IInputDataChannel>(remoteObject);
609     EXPECT_TRUE(iface != nullptr);
610 }
611 
612 /**
613  * @tc.name: testIMCBindToIMSA
614  * @tc.desc: Bind IMSA.
615  * @tc.type: FUNC
616  */
617 HWTEST_F(InputMethodControllerTest, testIMCBindToIMSA, TestSize.Level0)
618 {
619     sptr<InputClientStub> mClient = new InputClientStub();
620     MessageParcel data;
621     auto ret = data.WriteRemoteObject(mClient->AsObject());
622     EXPECT_TRUE(ret);
623     auto remoteObject = data.ReadRemoteObject();
624     sptr<IInputClient> iface = iface_cast<IInputClient>(remoteObject);
625     EXPECT_TRUE(iface != nullptr);
626 }
627 
628 /**
629  * @tc.name: testIMCDispatchKeyEvent001
630  * @tc.desc: test IMC DispatchKeyEvent with 'keyDown/KeyUP'.
631  * @tc.type: FUNC
632  * @tc.require:
633  */
634 HWTEST_F(InputMethodControllerTest, testIMCDispatchKeyEvent001, TestSize.Level0)
635 {
636     IMSA_HILOGI("IMC testIMCDispatchKeyEvent001 Test START");
637     doesKeyEventConsume_ = true;
638     doesFUllKeyEventConsume_ = false;
639     blockKeyEvent_.Clear(nullptr);
640     auto res = inputMethodController_->Attach(textListener_);
641     EXPECT_EQ(res, ErrorCode::NO_ERROR);
642 
643     bool ret = inputMethodController_->DispatchKeyEvent(keyEvent_, DispatchKeyEventCallback);
644     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
645 
646     EXPECT_TRUE(WaitKeyEventCallback());
647 
648     auto keyEvent = blockKeyEvent_.GetValue();
649     ASSERT_NE(keyEvent, nullptr);
650     EXPECT_EQ(keyEvent->GetKeyCode(), keyEvent_->GetKeyCode());
651     EXPECT_EQ(keyEvent->GetKeyAction(), keyEvent_->GetKeyAction());
652 
653     doesKeyEventConsume_ = false;
654     ret = inputMethodController_->DispatchKeyEvent(keyEvent_, DispatchKeyEventCallback);
655     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
656 
657     EXPECT_TRUE(!WaitKeyEventCallback());
658 }
659 
660 /**
661  * @tc.name: testIMCDispatchKeyEvent002
662  * @tc.desc: test IMC DispatchKeyEvent with 'keyEvent'.
663  * @tc.type: FUNC
664  * @tc.require:
665  */
666 HWTEST_F(InputMethodControllerTest, testIMCDispatchKeyEvent002, TestSize.Level0)
667 {
668     IMSA_HILOGI("IMC testIMCDispatchKeyEvent002 Test START");
669     doesKeyEventConsume_ = false;
670     doesFUllKeyEventConsume_ = true;
671     blockFullKeyEvent_.Clear(nullptr);
672     int32_t ret = inputMethodController_->DispatchKeyEvent(
__anon3dad76a90a02(std::shared_ptr<MMI::KeyEvent> &keyEvent, bool isConsumed) 673         keyEvent_, [](std::shared_ptr<MMI::KeyEvent> &keyEvent, bool isConsumed) {});
674     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
675     auto keyEvent = blockFullKeyEvent_.GetValue();
676     ASSERT_NE(keyEvent, nullptr);
677     CheckKeyEvent(keyEvent);
678 }
679 
680 /**
681  * @tc.name: testIMCDispatchKeyEvent003
682  * @tc.desc: test IMC DispatchKeyEvent with 'keyDown/KeyUP' and 'keyEvent'.
683  * @tc.type: FUNC
684  * @tc.require:
685  */
686 HWTEST_F(InputMethodControllerTest, testIMCDispatchKeyEvent003, TestSize.Level0)
687 {
688     IMSA_HILOGI("IMC testIMCDispatchKeyEvent003 Test START");
689     doesKeyEventConsume_ = true;
690     doesFUllKeyEventConsume_ = true;
691     blockKeyEvent_.Clear(nullptr);
692     blockFullKeyEvent_.Clear(nullptr);
693     int32_t ret = inputMethodController_->DispatchKeyEvent(
__anon3dad76a90b02(std::shared_ptr<MMI::KeyEvent> &keyEvent, bool isConsumed) 694         keyEvent_, [](std::shared_ptr<MMI::KeyEvent> &keyEvent, bool isConsumed) {});
695     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
696     auto keyEvent = blockKeyEvent_.GetValue();
697     auto keyFullEvent = blockFullKeyEvent_.GetValue();
698     ASSERT_NE(keyEvent, nullptr);
699     EXPECT_EQ(keyEvent->GetKeyCode(), keyEvent_->GetKeyCode());
700     EXPECT_EQ(keyEvent->GetKeyAction(), keyEvent_->GetKeyAction());
701     ASSERT_NE(keyFullEvent, nullptr);
702     CheckKeyEvent(keyFullEvent);
703 }
704 
705 /**
706  * @tc.name: testIMCOnCursorUpdate01
707  * @tc.desc: Test update cursorInfo, call 'OnCursorUpdate' twice, if cursorInfo is the same,
708  *           the second time will not get callback.
709  * @tc.type: FUNC
710  * @tc.require:
711  * @tc.author: Zhaolinglan
712  */
713 HWTEST_F(InputMethodControllerTest, testIMCOnCursorUpdate01, TestSize.Level0)
714 {
715     IMSA_HILOGI("IMC testIMCOnCursorUpdate01 Test START");
716     auto ret = inputMethodController_->Attach(textListener_, false);
717     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
718     CursorInfo info = { 1, 3, 0, 5 };
719     InputMethodControllerTest::TriggerCursorUpdateCallback(info);
720     EXPECT_EQ(InputMethodControllerTest::cursorInfo_, info);
721 
722     InputMethodControllerTest::cursorInfo_ = {};
723     InputMethodControllerTest::TriggerCursorUpdateCallback(info);
724     EXPECT_FALSE(InputMethodControllerTest::cursorInfo_ == info);
725 }
726 
727 /**
728  * @tc.name: testIMCOnCursorUpdate02
729  * @tc.desc: Test update cursorInfo, 'Attach'->'OnCursorUpdate'->'Close'->'Attach'->'OnCursorUpdate',
730  *           it will get callback two time.
731  * @tc.type: FUNC
732  * @tc.require:
733  * @tc.author: Zhaolinglan
734  */
735 HWTEST_F(InputMethodControllerTest, testIMCOnCursorUpdate02, TestSize.Level0)
736 {
737     IMSA_HILOGI("IMC testIMCOnCursorUpdate02 Test START");
738     auto ret = inputMethodController_->Attach(textListener_, false);
739     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
740     CursorInfo info = { 2, 4, 0, 6 };
741     InputMethodControllerTest::TriggerCursorUpdateCallback(info);
742     EXPECT_EQ(InputMethodControllerTest::cursorInfo_, info);
743 
744     InputMethodControllerTest::cursorInfo_ = {};
745     ret = InputMethodControllerTest::inputMethodController_->Close();
746     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
747     ret = inputMethodController_->Attach(textListener_, false);
748     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
749     InputMethodControllerTest::TriggerCursorUpdateCallback(info);
750     EXPECT_EQ(InputMethodControllerTest::cursorInfo_, info);
751 }
752 
753 /**
754  * @tc.name: testIMCOnSelectionChange01
755  * @tc.desc: Test change selection, call 'OnSelectionChange' twice, if selection is the same,
756  *           the second time will not get callback.
757  * @tc.type: FUNC
758  * @tc.require:
759  * @tc.author: Zhaolinglan
760  */
761 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange01, TestSize.Level0)
762 {
763     IMSA_HILOGI("IMC testIMCOnSelectionChange01 Test START");
764     auto ret = inputMethodController_->Attach(textListener_, false);
765     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
766     std::u16string text = Str8ToStr16("testSelect");
767     int start = 1;
768     int end = 2;
769     InputMethodControllerTest::TriggerSelectionChangeCallback(text, start, end);
770     EXPECT_EQ(InputMethodControllerTest::text_, Str16ToStr8(text));
771 
772     InputMethodControllerTest::text_ = "";
773     InputMethodControllerTest::TriggerSelectionChangeCallback(text, start, end);
774     EXPECT_NE(InputMethodControllerTest::text_, Str16ToStr8(text));
775 }
776 
777 /**
778  * @tc.name: testIMCOnSelectionChange02
779  * @tc.desc: Test change selection, 'Attach'->'OnSelectionChange'->'Close'->'Attach'->'OnSelectionChange',
780  *           it will get callback two time.
781  * @tc.type: FUNC
782  * @tc.require:
783  * @tc.author: Zhaolinglan
784  */
785 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange02, TestSize.Level0)
786 {
787     IMSA_HILOGI("IMC testIMCOnSelectionChange02 Test START");
788     auto ret = inputMethodController_->Attach(textListener_, false);
789     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
790     std::u16string text = Str8ToStr16("testSelect2");
791     int start = 1;
792     int end = 2;
793     InputMethodControllerTest::TriggerSelectionChangeCallback(text, start, end);
794     EXPECT_EQ(InputMethodControllerTest::text_, Str16ToStr8(text));
795 
796     InputMethodControllerTest::text_ = "";
797     InputMethodControllerTest::inputMethodController_->Close();
798     inputMethodController_->Attach(textListener_, false);
799     InputMethodControllerTest::TriggerSelectionChangeCallback(text, start, end);
800     EXPECT_EQ(InputMethodControllerTest::text_, Str16ToStr8(text));
801 }
802 
803 /**
804  * @tc.name: testIMCOnSelectionChange03
805  * @tc.desc: Test change selection, 'Attach without config'->'OnSelectionChange(0, 0)', it will get callback.
806  * @tc.type: FUNC
807  * @tc.require:
808  * @tc.author: Zhaolinglan
809  */
810 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange03, TestSize.Level0)
811 {
812     IMSA_HILOGI("IMC testIMCOnSelectionChange03 Test START");
813     InputMethodControllerTest::ResetKeyboardListenerTextConfig();
814     InputMethodControllerTest::inputMethodController_->Close();
815     auto ret = inputMethodController_->Attach(textListener_, false);
816     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
817     std::u16string text = Str8ToStr16("");
818     int start = 0;
819     int end = 0;
820     InputMethodControllerTest::TriggerSelectionChangeCallback(text, start, end);
821     EXPECT_EQ(InputMethodControllerTest::text_, Str16ToStr8(text));
822     EXPECT_EQ(InputMethodControllerTest::oldBegin_, INVALID_VALUE);
823     EXPECT_EQ(InputMethodControllerTest::oldEnd_, INVALID_VALUE);
824     EXPECT_EQ(InputMethodControllerTest::newBegin_, start);
825     EXPECT_EQ(InputMethodControllerTest::newEnd_, end);
826 }
827 
828 /**
829  * @tc.name: testIMCOnSelectionChange04
830  * @tc.desc: Test change selection, 'Attach with range(1, 1)'->'Attach witch range(2, 2)', it will get (1, 1, 2, 2).
831  * @tc.type: FUNC
832  * @tc.require:
833  * @tc.author: Zhaolinglan
834  */
835 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange04, TestSize.Level0)
836 {
837     IMSA_HILOGI("IMC testIMCOnSelectionChange04 Test START");
838     InputMethodControllerTest::ResetKeyboardListenerTextConfig();
839     InputMethodControllerTest::inputMethodController_->Close();
840     TextConfig textConfig;
841     textConfig.range = { 1, 1 };
842     auto ret = inputMethodController_->Attach(textListener_, false, textConfig);
843     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
844     textConfig.range = { 2, 2 };
845     ret = inputMethodController_->Attach(textListener_, false, textConfig);
846     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
847     EXPECT_EQ(InputMethodControllerTest::oldBegin_, 1);
848     EXPECT_EQ(InputMethodControllerTest::oldEnd_, 1);
849     EXPECT_EQ(InputMethodControllerTest::newBegin_, 2);
850     EXPECT_EQ(InputMethodControllerTest::newEnd_, 2);
851 }
852 
853 /**
854  * @tc.name: testIMCOnSelectionChange05
855  * @tc.desc: 'Attach without range'-> it will get no selectionChange callback.
856  * @tc.type: FUNC
857  * @tc.require:
858  * @tc.author: Zhaolinglan
859  */
860 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange05, TestSize.Level0)
861 {
862     IMSA_HILOGI("IMC testIMCOnSelectionChange05 Test START");
863     InputMethodControllerTest::ResetKeyboardListenerTextConfig();
864     InputMethodControllerTest::inputMethodController_->Close();
865     inputMethodController_->Attach(textListener_, false);
866     EXPECT_EQ(InputMethodControllerTest::oldBegin_, INVALID_VALUE);
867     EXPECT_EQ(InputMethodControllerTest::oldEnd_, INVALID_VALUE);
868     EXPECT_EQ(InputMethodControllerTest::newBegin_, INVALID_VALUE);
869     EXPECT_EQ(InputMethodControllerTest::newEnd_, INVALID_VALUE);
870 }
871 
872 /**
873  * @tc.name: testIMCOnSelectionChange06
874  * @tc.desc: 'Update(1, 2)'->'Attach without range', it will get no selectionChange callback.
875  * @tc.type: FUNC
876  * @tc.require:
877  * @tc.author: Zhaolinglan
878  */
879 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange06, TestSize.Level0)
880 {
881     IMSA_HILOGI("IMC testIMCOnSelectionChange06 Test START");
882     InputMethodControllerTest::inputMethodController_->Close();
883     inputMethodController_->Attach(textListener_, false);
884     std::u16string text = Str8ToStr16("");
885     InputMethodControllerTest::TriggerSelectionChangeCallback(text, 1, 2);
886     InputMethodControllerTest::ResetKeyboardListenerTextConfig();
887     inputMethodController_->Attach(textListener_, false);
888     EXPECT_EQ(InputMethodControllerTest::oldBegin_, INVALID_VALUE);
889     EXPECT_EQ(InputMethodControllerTest::oldEnd_, INVALID_VALUE);
890     EXPECT_EQ(InputMethodControllerTest::newBegin_, INVALID_VALUE);
891     EXPECT_EQ(InputMethodControllerTest::newEnd_, INVALID_VALUE);
892 }
893 
894 /**
895  * @tc.name: testIMCOnSelectionChange07
896  * @tc.desc: 'Attach with range -> Attach without range', it will get no selectionChange callback.
897  * @tc.type: FUNC
898  * @tc.require:
899  * @tc.author: Zhaolinglan
900  */
901 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange07, TestSize.Level0)
902 {
903     IMSA_HILOGI("IMC testIMCOnSelectionChange07 Test START");
904     InputMethodControllerTest::inputMethodController_->Close();
905     TextConfig textConfig;
906     textConfig.range = { 1, 1 };
907     inputMethodController_->Attach(textListener_, false, textConfig);
908     InputMethodControllerTest::ResetKeyboardListenerTextConfig();
909     inputMethodController_->Attach(textListener_, false);
910     EXPECT_EQ(InputMethodControllerTest::oldBegin_, INVALID_VALUE);
911     EXPECT_EQ(InputMethodControllerTest::oldEnd_, INVALID_VALUE);
912     EXPECT_EQ(InputMethodControllerTest::newBegin_, INVALID_VALUE);
913     EXPECT_EQ(InputMethodControllerTest::newEnd_, INVALID_VALUE);
914 }
915 
916 /**
917  * @tc.name: testIMCOnSelectionChange08
918  * @tc.desc: 'OnSelectionChange(1, 2) -> Attach without range -> OnSelectionChange(3, 4)', it will get (1,2,3,4)
919  * @tc.type: FUNC
920  * @tc.require:
921  * @tc.author: Zhaolinglan
922  */
923 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange08, TestSize.Level0)
924 {
925     IMSA_HILOGI("IMC testIMCOnSelectionChange08 Test START");
926     InputMethodControllerTest::inputMethodController_->Close();
927     inputMethodController_->Attach(textListener_, false);
928     std::u16string text = Str8ToStr16("");
929     InputMethodControllerTest::TriggerSelectionChangeCallback(text, 1, 2);
930     InputMethodControllerTest::ResetKeyboardListenerTextConfig();
931     inputMethodController_->Attach(textListener_, false);
932     InputMethodControllerTest::TriggerSelectionChangeCallback(text, 3, 4);
933     EXPECT_EQ(InputMethodControllerTest::oldBegin_, 1);
934     EXPECT_EQ(InputMethodControllerTest::oldEnd_, 2);
935     EXPECT_EQ(InputMethodControllerTest::newBegin_, 3);
936     EXPECT_EQ(InputMethodControllerTest::newEnd_, 4);
937 }
938 
939 /**
940  * @tc.name: testIMCOnSelectionChange09
941  * @tc.desc: Attach with range(0, 0) -> OnSelectionChange("", 0, 0) -> Get 'textChange' and 'selectionChange' Callback
942  * @tc.type: FUNC
943  * @tc.require:
944  * @tc.author: Zhaolinglan
945  */
946 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange09, TestSize.Level0)
947 {
948     IMSA_HILOGI("IMC testIMCOnSelectionChange09 Test START");
949     InputMethodControllerTest::inputMethodController_->Close();
950     TextConfig textConfig;
951     textConfig.range = { 0, 0 };
952     auto ret = inputMethodController_->Attach(textListener_, false, textConfig);
953     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
954     InputMethodControllerTest::ResetKeyboardListenerTextConfig();
955     InputMethodControllerTest::text_ = "test";
956     std::u16string text = Str8ToStr16("test1");
957     InputMethodControllerTest::TriggerSelectionChangeCallback(text, 1, 6);
958     EXPECT_EQ(InputMethodControllerTest::text_, "test1");
959     EXPECT_EQ(InputMethodControllerTest::newBegin_, 1);
960     EXPECT_EQ(InputMethodControllerTest::newEnd_, 6);
961 }
962 
963 /**
964  * @tc.name: testShowTextInput
965  * @tc.desc: IMC ShowTextInput
966  * @tc.type: FUNC
967  */
968 HWTEST_F(InputMethodControllerTest, testShowTextInput, TestSize.Level0)
969 {
970     IMSA_HILOGI("IMC ShowTextInput Test START");
971     TextListener::ResetParam();
972     inputMethodController_->ShowTextInput();
973     EXPECT_TRUE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::SHOW));
974 }
975 
976 /**
977  * @tc.name: testShowSoftKeyboard
978  * @tc.desc: IMC ShowSoftKeyboard
979  * @tc.type: FUNC
980  */
981 HWTEST_F(InputMethodControllerTest, testShowSoftKeyboard, TestSize.Level0)
982 {
983     IMSA_HILOGI("IMC ShowSoftKeyboard Test START");
984     IdentityCheckerMock::SetPermission(true);
985     imeListener_->keyboardState_ = false;
986     TextListener::ResetParam();
987     int32_t ret = inputMethodController_->ShowSoftKeyboard();
988     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
989     EXPECT_TRUE(imeListener_->keyboardState_ && TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::SHOW));
990     IdentityCheckerMock::SetPermission(false);
991 }
992 
993 /**
994  * @tc.name: testShowCurrentInput
995  * @tc.desc: IMC ShowCurrentInput
996  * @tc.type: FUNC
997  */
998 HWTEST_F(InputMethodControllerTest, testShowCurrentInput, TestSize.Level0)
999 {
1000     IMSA_HILOGI("IMC ShowCurrentInput Test START");
1001     imeListener_->keyboardState_ = false;
1002     TextListener::ResetParam();
1003     int32_t ret = inputMethodController_->ShowCurrentInput();
1004     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1005     EXPECT_TRUE(imeListener_->keyboardState_ && TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::SHOW));
1006 }
1007 
1008 /**
1009  * @tc.name: testIMCGetEnterKeyType
1010  * @tc.desc: IMC testGetEnterKeyType.
1011  * @tc.type: FUNC
1012  * @tc.require:
1013  */
1014 HWTEST_F(InputMethodControllerTest, testIMCGetEnterKeyType, TestSize.Level0)
1015 {
1016     IMSA_HILOGI("IMC GetEnterKeyType Test START");
1017     int32_t keyType;
1018     inputMethodController_->GetEnterKeyType(keyType);
1019     EXPECT_TRUE(keyType >= static_cast<int32_t>(EnterKeyType::UNSPECIFIED)
1020                 && keyType <= static_cast<int32_t>(EnterKeyType::PREVIOUS));
1021 }
1022 
1023 /**
1024  * @tc.name: testIMCGetInputPattern
1025  * @tc.desc: IMC testGetInputPattern.
1026  * @tc.type: FUNC
1027  * @tc.require:
1028  */
1029 HWTEST_F(InputMethodControllerTest, testIMCGetInputPattern, TestSize.Level0)
1030 {
1031     IMSA_HILOGI("IMC GetInputPattern Test START");
1032     int32_t inputPattern;
1033     inputMethodController_->GetInputPattern(inputPattern);
1034     EXPECT_TRUE(inputPattern >= static_cast<int32_t>(TextInputType::NONE)
1035                 && inputPattern <= static_cast<int32_t>(TextInputType::VISIBLE_PASSWORD));
1036 }
1037 
1038 /**
1039  * @tc.name: testOnEditorAttributeChanged01
1040  * @tc.desc: IMC testOnEditorAttributeChanged01.
1041  * @tc.type: FUNC
1042  * @tc.require:
1043  */
1044 HWTEST_F(InputMethodControllerTest, testOnEditorAttributeChanged01, TestSize.Level0)
1045 {
1046     IMSA_HILOGI("IMC testOnEditorAttributeChanged01 Test START");
1047     auto ret = inputMethodController_->Attach(textListener_, false);
1048     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1049     Configuration info;
1050     info.SetEnterKeyType(EnterKeyType::GO);
1051     info.SetTextInputType(TextInputType::NUMBER);
1052     InputMethodControllerTest::TriggerConfigurationChangeCallback(info);
1053     EXPECT_EQ(InputMethodControllerTest::inputAttribute_.inputPattern, static_cast<int32_t>(info.GetTextInputType()));
1054     EXPECT_EQ(InputMethodControllerTest::inputAttribute_.enterKeyType, static_cast<int32_t>(info.GetEnterKeyType()));
1055 }
1056 
1057 /**
1058  * @tc.name: testOnEditorAttributeChanged02
1059  * @tc.desc: Attach(isPreviewSupport) -> OnConfigurationChange -> editorChange callback (isPreviewSupport).
1060  * @tc.type: FUNC
1061  * @tc.require:
1062  */
1063 HWTEST_F(InputMethodControllerTest, testOnEditorAttributeChanged02, TestSize.Level0)
1064 {
1065     IMSA_HILOGI("IMC testOnEditorAttributeChanged02 Test START");
1066     InputAttribute attribute = { .inputPattern = static_cast<int32_t>(TextInputType::DATETIME),
1067         .enterKeyType = static_cast<int32_t>(EnterKeyType::GO),
1068         .isTextPreviewSupported = true };
1069     auto ret = inputMethodController_->Attach(textListener_, false, attribute);
1070     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1071     Configuration info;
1072     info.SetEnterKeyType(EnterKeyType::NEW_LINE);
1073     info.SetTextInputType(TextInputType::NUMBER);
1074     InputMethodControllerTest::ResetKeyboardListenerTextConfig();
1075     InputMethodControllerTest::TriggerConfigurationChangeCallback(info);
1076     EXPECT_EQ(InputMethodControllerTest::inputAttribute_.inputPattern, static_cast<int32_t>(info.GetTextInputType()));
1077     EXPECT_EQ(InputMethodControllerTest::inputAttribute_.enterKeyType, static_cast<int32_t>(info.GetEnterKeyType()));
1078     EXPECT_EQ(InputMethodControllerTest::inputAttribute_.isTextPreviewSupported, attribute.isTextPreviewSupported);
1079 }
1080 
1081 /**
1082  * @tc.name: testHideSoftKeyboard
1083  * @tc.desc: IMC HideSoftKeyboard
1084  * @tc.type: FUNC
1085  */
1086 HWTEST_F(InputMethodControllerTest, testHideSoftKeyboard, TestSize.Level0)
1087 {
1088     IMSA_HILOGI("IMC HideSoftKeyboard Test START");
1089     IdentityCheckerMock::SetPermission(true);
1090     imeListener_->keyboardState_ = true;
1091     TextListener::ResetParam();
1092     int32_t ret = inputMethodController_->HideSoftKeyboard();
1093     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1094     EXPECT_TRUE(!imeListener_->keyboardState_ && TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::HIDE));
1095     IdentityCheckerMock::SetPermission(false);
1096 }
1097 
1098 /**
1099  * @tc.name: testIMCHideCurrentInput
1100  * @tc.desc: IMC HideCurrentInput.
1101  * @tc.type: FUNC
1102  * @tc.require:
1103  */
1104 HWTEST_F(InputMethodControllerTest, testIMCHideCurrentInput, TestSize.Level0)
1105 {
1106     IMSA_HILOGI("IMC HideCurrentInput Test START");
1107     imeListener_->keyboardState_ = true;
1108     TextListener::ResetParam();
1109     int32_t ret = inputMethodController_->HideCurrentInput();
1110     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1111     EXPECT_TRUE(!imeListener_->keyboardState_ && TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::HIDE));
1112 }
1113 
1114 /**
1115  * @tc.name: testIMCInputStopSession
1116  * @tc.desc: IMC testInputStopSession.
1117  * @tc.type: FUNC
1118  * @tc.require: issueI5U8FZ
1119  * @tc.author: Hollokin
1120  */
1121 HWTEST_F(InputMethodControllerTest, testIMCInputStopSession, TestSize.Level0)
1122 {
1123     IMSA_HILOGI("IMC StopInputSession Test START");
1124     imeListener_->keyboardState_ = true;
1125     int32_t ret = inputMethodController_->StopInputSession();
1126     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1127     WaitKeyboardStatusCallback(false);
1128     EXPECT_TRUE(!imeListener_->keyboardState_);
1129 }
1130 
1131 /**
1132  * @tc.name: testIMCHideTextInput.
1133  * @tc.desc: IMC testHideTextInput.
1134  * @tc.type: FUNC
1135  */
1136 HWTEST_F(InputMethodControllerTest, testIMCHideTextInput, TestSize.Level0)
1137 {
1138     IMSA_HILOGI("IMC HideTextInput Test START");
1139     imeListener_->keyboardState_ = true;
1140     inputMethodController_->HideTextInput();
1141     WaitKeyboardStatusCallback(false);
1142     EXPECT_TRUE(!imeListener_->keyboardState_);
1143 }
1144 
1145 /**
1146  * @tc.name: testIMCRequestShowInput.
1147  * @tc.desc: IMC testIMCRequestShowInput.
1148  * @tc.type: FUNC
1149  */
1150 HWTEST_F(InputMethodControllerTest, testIMCRequestShowInput, TestSize.Level0)
1151 {
1152     IMSA_HILOGI("IMC testIMCRequestShowInput Test START");
1153     imeListener_->keyboardState_ = false;
1154     int32_t ret = InputMethodControllerTest::inputMethodController_->RequestShowInput();
1155     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1156     EXPECT_TRUE(imeListener_->keyboardState_);
1157 }
1158 
1159 /**
1160  * @tc.name: testIMCRequestHideInput.
1161  * @tc.desc: IMC testIMCRequestHideInput.
1162  * @tc.type: FUNC
1163  */
1164 HWTEST_F(InputMethodControllerTest, testIMCRequestHideInput, TestSize.Level0)
1165 {
1166     IMSA_HILOGI("IMC testIMCRequestHideInput Test START");
1167     imeListener_->keyboardState_ = true;
1168     int32_t ret = InputMethodControllerTest::inputMethodController_->RequestHideInput();
1169     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1170     EXPECT_FALSE(imeListener_->keyboardState_);
1171 }
1172 
1173 /**
1174  * @tc.name: testSetControllerListener
1175  * @tc.desc: IMC SetControllerListener
1176  * @tc.type: FUNC
1177  */
1178 HWTEST_F(InputMethodControllerTest, testSetControllerListener, TestSize.Level0)
1179 {
1180     IMSA_HILOGI("IMC SetControllerListener Test START");
1181     inputMethodController_->SetControllerListener(controllerListener_);
1182 
1183     int32_t ret = inputMethodController_->Attach(textListener_, false);
1184     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1185     SelectListenerMock::start_ = 0;
1186     SelectListenerMock::end_ = 0;
1187     inputMethodAbility_->SelectByRange(1, 2);
1188     SelectListenerMock::WaitSelectListenerCallback();
1189     EXPECT_EQ(SelectListenerMock::start_, 1);
1190     EXPECT_EQ(SelectListenerMock::end_, 2);
1191 
1192     SelectListenerMock::direction_ = 0;
1193     inputMethodAbility_->SelectByMovement(static_cast<int32_t>(Direction::UP));
1194     SelectListenerMock::WaitSelectListenerCallback();
1195     EXPECT_EQ(SelectListenerMock::direction_, static_cast<int32_t>(Direction::UP));
1196 
1197     SelectListenerMock::direction_ = 0;
1198     inputMethodAbility_->SelectByMovement(static_cast<int32_t>(Direction::DOWN));
1199     SelectListenerMock::WaitSelectListenerCallback();
1200     EXPECT_EQ(SelectListenerMock::direction_, static_cast<int32_t>(Direction::DOWN));
1201 
1202     SelectListenerMock::direction_ = 0;
1203     inputMethodAbility_->SelectByMovement(static_cast<int32_t>(Direction::LEFT));
1204     SelectListenerMock::WaitSelectListenerCallback();
1205     EXPECT_EQ(SelectListenerMock::direction_, static_cast<int32_t>(Direction::LEFT));
1206 
1207     SelectListenerMock::direction_ = 0;
1208     inputMethodAbility_->SelectByMovement(static_cast<int32_t>(Direction::RIGHT));
1209     SelectListenerMock::WaitSelectListenerCallback();
1210     EXPECT_EQ(SelectListenerMock::direction_, static_cast<int32_t>(Direction::RIGHT));
1211 }
1212 
1213 /**
1214  * @tc.name: testWasAttached
1215  * @tc.desc: IMC WasAttached
1216  * @tc.type: FUNC
1217  */
1218 HWTEST_F(InputMethodControllerTest, testWasAttached, TestSize.Level0)
1219 {
1220     IMSA_HILOGI("IMC WasAttached Test START");
1221     inputMethodController_->Close();
1222     bool result = inputMethodController_->WasAttached();
1223     EXPECT_FALSE(result);
1224     int32_t ret = inputMethodController_->Attach(textListener_, false);
1225     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1226     result = inputMethodController_->WasAttached();
1227     EXPECT_TRUE(result);
1228     inputMethodController_->Close();
1229 }
1230 
1231 /**
1232  * @tc.name: testGetDefaultInputMethod
1233  * @tc.desc: IMC GetDefaultInputMethod
1234  * @tc.type: FUNC
1235  */
1236 HWTEST_F(InputMethodControllerTest, testGetDefaultInputMethod, TestSize.Level0)
1237 {
1238     IMSA_HILOGI("IMC testGetDefaultInputMethod Test START");
1239     std::shared_ptr<Property> property = nullptr;
1240     int32_t ret = inputMethodController_->GetDefaultInputMethod(property);
1241     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1242     ASSERT_NE(property, nullptr);
1243     EXPECT_FALSE(property->name.empty());
1244 }
1245 
1246 /**
1247  * @tc.name: testGetSystemInputMethodConfig
1248  * @tc.desc: IMC GetSystemInputMethodConfig
1249  * @tc.type: FUNC
1250  */
1251 HWTEST_F(InputMethodControllerTest, GetSystemInputMethodConfig, TestSize.Level0)
1252 {
1253     IMSA_HILOGI("IMC GetSystemInputMethodConfig Test START");
1254     OHOS::AppExecFwk::ElementName inputMethodConfig;
1255     int32_t ret = inputMethodController_->GetInputMethodConfig(inputMethodConfig);
1256     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1257     EXPECT_GE(inputMethodConfig.GetBundleName().length(), 0);
1258     EXPECT_GE(inputMethodConfig.GetAbilityName().length(), 0);
1259 }
1260 
1261 /**
1262  * @tc.name: testWithoutEditableState
1263  * @tc.desc: IMC testWithoutEditableState
1264  * @tc.type: FUNC
1265  * @tc.require:
1266  */
1267 HWTEST_F(InputMethodControllerTest, testWithoutEditableState, TestSize.Level0)
1268 {
1269     IMSA_HILOGI("IMC WithouteEditableState Test START");
1270     auto ret = inputMethodController_->Attach(textListener_, false);
1271     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1272     ret = inputMethodController_->HideTextInput();
1273     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1274 
1275     int32_t deleteForwardLength = 1;
1276     ret = inputMethodAbility_->DeleteForward(deleteForwardLength);
1277     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
1278     EXPECT_NE(TextListener::deleteForwardLength_, deleteForwardLength);
1279 
1280     int32_t deleteBackwardLength = 2;
1281     ret = inputMethodAbility_->DeleteBackward(deleteBackwardLength);
1282     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
1283     EXPECT_NE(TextListener::deleteBackwardLength_, deleteBackwardLength);
1284 
1285     std::string insertText = "t";
1286     ret = inputMethodAbility_->InsertText(insertText);
1287     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
1288     EXPECT_NE(TextListener::insertText_, Str8ToStr16(insertText));
1289 
1290     constexpr int32_t funcKey = 1;
1291     ret = inputMethodAbility_->SendFunctionKey(funcKey);
1292     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
1293     EXPECT_NE(TextListener::key_, funcKey);
1294 
1295     constexpr int32_t keyCode = 4;
1296     ret = inputMethodAbility_->MoveCursor(keyCode);
1297     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
1298     EXPECT_NE(TextListener::direction_, keyCode);
1299 }
1300 
1301 /**
1302  * @tc.name: testIsInputTypeSupported
1303  * @tc.desc: IsInputTypeSupported
1304  * @tc.type: FUNC
1305  * @tc.require:
1306  * @tc.author: chenyu
1307  */
1308 HWTEST_F(InputMethodControllerTest, testIsInputTypeSupported, TestSize.Level0)
1309 {
1310     IMSA_HILOGI("IMC testIsInputTypeSupported Test START");
1311     auto ret = inputMethodController_->IsInputTypeSupported(InputType::NONE);
1312     EXPECT_FALSE(ret);
1313 }
1314 
1315 /**
1316  * @tc.name: testStartInputType
1317  * @tc.desc: StartInputType
1318  * @tc.type: FUNC
1319  * @tc.require:
1320  * @tc.author: chenyu
1321  */
1322 HWTEST_F(InputMethodControllerTest, testStartInputType, TestSize.Level0)
1323 {
1324     IMSA_HILOGI("IMC testStartInputType Test START");
1325     auto ret = inputMethodController_->StartInputType(InputType::NONE);
1326     EXPECT_NE(ret, ErrorCode::NO_ERROR);
1327 }
1328 
1329 /**
1330  * @tc.name: testSendPrivateCommand_001
1331  * @tc.desc: IMC SendPrivateCommand without default ime
1332  * @tc.type: FUNC
1333  * @tc.require:
1334  * @tc.author: mashaoyin
1335  */
1336 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_001, TestSize.Level0)
1337 {
1338     IMSA_HILOGI("IMC testSendPrivateCommand_001 Test START");
1339     InputMethodEngineListenerImpl::ResetParam();
1340     auto ret = inputMethodController_->Attach(textListener_, false);
1341     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1342     std::unordered_map<std::string, PrivateDataValue> privateCommand;
1343     PrivateDataValue privateDataValue1 = std::string("stringValue");
1344     privateCommand.emplace("value1", privateDataValue1);
1345     IdentityCheckerMock::SetBundleNameValid(false);
1346     ret = inputMethodController_->SendPrivateCommand(privateCommand);
1347     EXPECT_EQ(ret, ErrorCode::ERROR_NOT_DEFAULT_IME);
1348     inputMethodController_->Close();
1349     IdentityCheckerMock::SetBundleNameValid(true);
1350 }
1351 
1352 /**
1353  * @tc.name: testSendPrivateCommand_002
1354  * @tc.desc: SendPrivateCommand not bound, and empty privateCommand.
1355  * @tc.type: FUNC
1356  * @tc.require:
1357  * @tc.author: mashaoyin
1358  */
1359 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_002, TestSize.Level0)
1360 {
1361     IMSA_HILOGI("IMC testSendPrivateCommand_002 Test START");
1362     InputMethodEngineListenerImpl::ResetParam();
1363     IdentityCheckerMock::SetBundleNameValid(true);
1364     inputMethodController_->Close();
1365     std::unordered_map<std::string, PrivateDataValue> privateCommand;
1366     auto ret = inputMethodController_->SendPrivateCommand(privateCommand);
1367     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_BOUND);
1368 
1369     ret = inputMethodController_->Attach(textListener_, false);
1370     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1371     ret = inputMethodController_->SendPrivateCommand(privateCommand);
1372     EXPECT_EQ(ret, ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE);
1373     inputMethodController_->Close();
1374     IdentityCheckerMock::SetBundleNameValid(false);
1375 }
1376 
1377 /**
1378  * @tc.name: testSendPrivateCommand_003
1379  * @tc.desc: IMC SendPrivateCommand with normal private command.
1380  * @tc.type: FUNC
1381  * @tc.require:
1382  * @tc.author: mashaoyin
1383  */
1384 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_003, TestSize.Level0)
1385 {
1386     IMSA_HILOGI("IMC testSendPrivateCommand_003 Test START");
1387     IdentityCheckerMock::SetBundleNameValid(true);
1388     InputMethodEngineListenerImpl::ResetParam();
1389     auto ret = inputMethodController_->Attach(textListener_, false);
1390     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1391     std::unordered_map<std::string, PrivateDataValue> privateCommand;
1392     PrivateDataValue privateDataValue1 = std::string("stringValue");
1393     privateCommand.emplace("value1", privateDataValue1);
1394     ret = inputMethodController_->SendPrivateCommand(privateCommand);
1395     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1396     inputMethodController_->Close();
1397     IdentityCheckerMock::SetBundleNameValid(false);
1398 }
1399 
1400 /**
1401  * @tc.name: testSendPrivateCommand_004
1402  * @tc.desc: IMC SendPrivateCommand with correct data format and all data type.
1403  * @tc.type: FUNC
1404  * @tc.require:
1405  * @tc.author: mashaoyin
1406  */
1407 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_004, TestSize.Level0)
1408 {
1409     IMSA_HILOGI("IMC testSendPrivateCommand_004 Test START");
1410     IdentityCheckerMock::SetBundleNameValid(true);
1411     InputMethodEngineListenerImpl::ResetParam();
1412     auto ret = inputMethodController_->Attach(textListener_, false);
1413     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1414     std::unordered_map<std::string, PrivateDataValue> privateCommand;
1415     PrivateDataValue privateDataValue1 = std::string("stringValue");
1416     PrivateDataValue privateDataValue2 = true;
1417     PrivateDataValue privateDataValue3 = 100;
1418     privateCommand.emplace("value1", privateDataValue1);
1419     privateCommand.emplace("value2", privateDataValue2);
1420     privateCommand.emplace("value3", privateDataValue3);
1421     ret = inputMethodController_->SendPrivateCommand(privateCommand);
1422     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1423     EXPECT_TRUE(InputMethodEngineListenerImpl::WaitSendPrivateCommand(privateCommand));
1424     inputMethodController_->Close();
1425     IdentityCheckerMock::SetBundleNameValid(false);
1426 }
1427 
1428 /**
1429  * @tc.name: testSendPrivateCommand_005
1430  * @tc.desc: IMC SendPrivateCommand with more than 5 private command.
1431  * @tc.type: FUNC
1432  * @tc.require:
1433  * @tc.author: mashaoyin
1434  */
1435 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_005, TestSize.Level0)
1436 {
1437     IMSA_HILOGI("IMC testSendPrivateCommand_005 Test START");
1438     IdentityCheckerMock::SetBundleNameValid(true);
1439     InputMethodEngineListenerImpl::ResetParam();
1440     auto ret = inputMethodController_->Attach(textListener_, false);
1441     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1442     std::unordered_map<std::string, PrivateDataValue> privateCommand;
1443     PrivateDataValue privateDataValue1 = std::string("stringValue");
1444     privateCommand.emplace("value1", privateDataValue1);
1445     privateCommand.emplace("value2", privateDataValue1);
1446     privateCommand.emplace("value3", privateDataValue1);
1447     privateCommand.emplace("value4", privateDataValue1);
1448     privateCommand.emplace("value5", privateDataValue1);
1449     privateCommand.emplace("value6", privateDataValue1);
1450     ret = inputMethodController_->SendPrivateCommand(privateCommand);
1451     EXPECT_EQ(ret, ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE);
1452     inputMethodController_->Close();
1453     IdentityCheckerMock::SetBundleNameValid(false);
1454 }
1455 
1456 /**
1457  * @tc.name: testSendPrivateCommand_006
1458  * @tc.desc: IMC SendPrivateCommand size is more than 32KB.
1459  * @tc.type: FUNC
1460  * @tc.require:
1461  * @tc.author: mashaoyin
1462  */
1463 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_006, TestSize.Level0)
1464 {
1465     IMSA_HILOGI("IMC testSendPrivateCommand_006 Test START");
1466     IdentityCheckerMock::SetBundleNameValid(true);
1467     InputMethodEngineListenerImpl::ResetParam();
1468     std::unordered_map<std::string, PrivateDataValue> privateCommand;
1469     PrivateDataValue privateDataValue1 = std::string("stringValue");
1470     PrivateDataValue privateDataValue2 = true;
1471     PrivateDataValue privateDataValue3 = 100;
1472     privateCommand.emplace("value1", privateDataValue1);
1473     privateCommand.emplace("value2", privateDataValue2);
1474     privateCommand.emplace("value3", privateDataValue3);
1475     TextConfig textConfig;
1476     textConfig.privateCommand = privateCommand;
1477     textConfig.windowId = 1;
1478     auto ret = inputMethodController_->Attach(textListener_, false, textConfig);
1479     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1480     EXPECT_TRUE(InputMethodEngineListenerImpl::WaitSendPrivateCommand(privateCommand));
1481     inputMethodController_->Close();
1482     IdentityCheckerMock::SetBundleNameValid(false);
1483 }
1484 
1485 /**
1486  * @tc.name: testSendPrivateCommand_007
1487  * @tc.desc: IMC SendPrivateCommand with Attach.
1488  * @tc.type: FUNC
1489  * @tc.require:
1490  * @tc.author: mashaoyin
1491  */
1492 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_007, TestSize.Level0)
1493 {
1494     IMSA_HILOGI("IMC testSendPrivateCommand_007 Test START");
1495     IdentityCheckerMock::SetBundleNameValid(true);
1496     TextListener::ResetParam();
1497     auto ret = inputMethodController_->Attach(textListener_, false);
1498     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1499     string str(32768, 'a');
1500     std::unordered_map<std::string, PrivateDataValue> privateCommand;
1501     PrivateDataValue privateDataValue1 = str;
1502     privateCommand.emplace("value1", privateDataValue1);
1503     ret = inputMethodController_->SendPrivateCommand(privateCommand);
1504     EXPECT_EQ(ret, ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE);
1505     inputMethodController_->Close();
1506     IdentityCheckerMock::SetBundleNameValid(false);
1507 }
1508 
1509 /**
1510  * @tc.name: testSendPrivateCommand_008
1511  * @tc.desc: IMA SendPrivateCommand total size is 32KB, 32KB - 1, 32KB + 1.
1512  * @tc.type: IMC
1513  * @tc.require:
1514  * @tc.author: mashaoyin
1515  */
1516 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_008, TestSize.Level0)
1517 {
1518     IMSA_HILOGI("IMC testSendPrivateCommand_008 Test START");
1519     IdentityCheckerMock::SetBundleNameValid(true);
1520     auto ret = inputMethodController_->Attach(textListener_, false);
1521     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1522     TextListener::ResetParam();
1523     std::unordered_map<std::string, PrivateDataValue> privateCommand1{ { "v",
1524         string(PRIVATE_COMMAND_SIZE_MAX - 2, 'a') } };
1525     std::unordered_map<std::string, PrivateDataValue> privateCommand2{ { "v",
1526         string(PRIVATE_COMMAND_SIZE_MAX - 1, 'a') } };
1527     std::unordered_map<std::string, PrivateDataValue> privateCommand3{ { "v",
1528         string(PRIVATE_COMMAND_SIZE_MAX, 'a') } };
1529     ret = inputMethodController_->SendPrivateCommand(privateCommand1);
1530     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1531     ret = inputMethodController_->SendPrivateCommand(privateCommand2);
1532     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1533     ret = inputMethodController_->SendPrivateCommand(privateCommand3);
1534     EXPECT_EQ(ret, ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE);
1535     inputMethodController_->Close();
1536     IdentityCheckerMock::SetBundleNameValid(false);
1537 }
1538 
1539 /**
1540  * @tc.name: testFinishTextPreviewAfterDetach_001
1541  * @tc.desc: IMC testFinishTextPreviewAfterDetach.
1542  * @tc.type: IMC
1543  * @tc.require:
1544  * @tc.author: zhaolinglan
1545  */
1546 HWTEST_F(InputMethodControllerTest, testFinishTextPreviewAfterDetach_001, TestSize.Level0)
1547 {
1548     IMSA_HILOGI("IMC testFinishTextPreviewAfterDetach_001 Test START");
1549     InputAttribute inputAttribute = { .isTextPreviewSupported = true };
1550     inputMethodController_->Attach(textListener_, false, inputAttribute);
1551     TextListener::ResetParam();
1552     inputMethodController_->Close();
1553     EXPECT_TRUE(TextListener::isFinishTextPreviewCalled_);
1554 }
1555 
1556 /**
1557  * @tc.name: testFinishTextPreviewAfterDetach_002
1558  * @tc.desc: IMC testFinishTextPreviewAfterDetach_002.
1559  * @tc.type: IMC
1560  * @tc.require:
1561  * @tc.author: zhaolinglan
1562  */
1563 HWTEST_F(InputMethodControllerTest, testFinishTextPreviewAfterDetach_002, TestSize.Level0)
1564 {
1565     IMSA_HILOGI("IMC testFinishTextPreviewAfterDetach_002 Test START");
1566     InputAttribute inputAttribute = { .isTextPreviewSupported = true };
1567     inputMethodController_->Attach(textListener_, false, inputAttribute);
1568     TextListener::ResetParam();
1569     inputMethodController_->DeactivateClient();
1570     EXPECT_FALSE(TextListener::isFinishTextPreviewCalled_);
1571 }
1572 
1573 /**
1574  * @tc.name: testGetInputMethodState_001
1575  * @tc.desc: IMA
1576  * @tc.type: FUNC
1577  * @tc.require:
1578  */
1579 HWTEST_F(InputMethodControllerTest, testGetInputMethodState_001, TestSize.Level0)
1580 {
1581     IMSA_HILOGI("InputMethodControllerTest GetInputMethodState_001 Test START");
1582     EnabledStatus status = EnabledStatus::DISABLED;
1583     SecurityModeParser::GetInstance()->fullModeList_.push_back(TddUtil::currentBundleNameMock_);
1584     EnableImeDataParser::GetInstance()->enableList_[IME_KEY].push_back(TddUtil::currentBundleNameMock_);
1585     auto ret = inputMethodController_->GetInputMethodState(status);
1586     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1587     EXPECT_TRUE(status == EnabledStatus::FULL_EXPERIENCE_MODE);
1588     SecurityModeParser::GetInstance()->fullModeList_.clear();
1589     EnableImeDataParser::GetInstance()->enableList_.clear();
1590 }
1591 
1592 /**
1593  * @tc.name: testGetInputMethodState_002
1594  * @tc.desc: IMA
1595  * @tc.type: FUNC
1596  * @tc.require:
1597  */
1598 HWTEST_F(InputMethodControllerTest, testGetInputMethodState_002, TestSize.Level0)
1599 {
1600     IMSA_HILOGI("InputMethodControllerTest GetInputMethodState_002 Test START");
1601     EnabledStatus status = EnabledStatus::DISABLED;
1602     ImeInfoInquirer::GetInstance().systemConfig_.enableFullExperienceFeature = true;
1603     ImeInfoInquirer::GetInstance().systemConfig_.enableInputMethodFeature = true;
1604     EnableImeDataParser::GetInstance()->enableList_.clear();
1605     SecurityModeParser::GetInstance()->fullModeList_.clear();
1606     auto ret = inputMethodController_->GetInputMethodState(status);
1607     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1608     EXPECT_TRUE(status != EnabledStatus::FULL_EXPERIENCE_MODE);
1609     ImeInfoInquirer::GetInstance().systemConfig_.enableFullExperienceFeature = false;
1610     ImeInfoInquirer::GetInstance().systemConfig_.enableInputMethodFeature = false;
1611 }
1612 
1613 /**
1614  * @tc.name: testGetInputMethodState_003
1615  * @tc.desc: IMA
1616  * @tc.type: FUNC
1617  * @tc.require:
1618  */
1619 HWTEST_F(InputMethodControllerTest, testGetInputMethodState_003, TestSize.Level0)
1620 {
1621     IMSA_HILOGI("InputMethodControllerTest GetInputMethodState_003 Test START");
1622     EnabledStatus status = EnabledStatus::DISABLED;
1623     ImeInfoInquirer::GetInstance().systemConfig_.enableFullExperienceFeature = true;
1624     ImeInfoInquirer::GetInstance().systemConfig_.enableInputMethodFeature = true;
1625     EnableImeDataParser::GetInstance()->enableList_[IME_KEY].push_back(TddUtil::currentBundleNameMock_);
1626     auto ret = inputMethodController_->GetInputMethodState(status);
1627     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1628     EXPECT_TRUE(status == EnabledStatus::BASIC_MODE);
1629     ImeInfoInquirer::GetInstance().systemConfig_.enableFullExperienceFeature = false;
1630     ImeInfoInquirer::GetInstance().systemConfig_.enableInputMethodFeature = false;
1631     EnableImeDataParser::GetInstance()->enableList_.clear();
1632 }
1633 
1634 /**
1635  * @tc.name: testGetInputMethodState_004
1636  * @tc.desc: IMA
1637  * @tc.type: FUNC
1638  * @tc.require:
1639  */
1640 HWTEST_F(InputMethodControllerTest, testGetInputMethodState_004, TestSize.Level0)
1641 {
1642     IMSA_HILOGI("InputMethodControllerTest GetInputMethodState_004 Test START");
1643     EnabledStatus status = EnabledStatus::DISABLED;
1644     ImeInfoInquirer::GetInstance().systemConfig_.enableFullExperienceFeature = true;
1645     ImeInfoInquirer::GetInstance().systemConfig_.enableInputMethodFeature = false;
1646     auto ret = inputMethodController_->GetInputMethodState(status);
1647     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1648     EXPECT_TRUE(status == EnabledStatus::BASIC_MODE);
1649     ImeInfoInquirer::GetInstance().systemConfig_.enableFullExperienceFeature = false;
1650 }
1651 
1652 /**
1653  * @tc.name: testGetInputMethodState_005
1654  * @tc.desc: IMA
1655  * @tc.type: FUNC
1656  * @tc.require:
1657  */
1658 HWTEST_F(InputMethodControllerTest, testGetInputMethodState_005, TestSize.Level0)
1659 {
1660     IMSA_HILOGI("InputMethodControllerTest GetInputMethodState_005 Test START");
1661     EnabledStatus status = EnabledStatus::DISABLED;
1662     ImeInfoInquirer::GetInstance().systemConfig_.enableFullExperienceFeature = false;
1663     ImeInfoInquirer::GetInstance().systemConfig_.enableInputMethodFeature = false;
1664     auto ret = inputMethodController_->GetInputMethodState(status);
1665     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1666     EXPECT_TRUE(status == EnabledStatus::FULL_EXPERIENCE_MODE);
1667 }
1668 
1669 /**
1670  * @tc.name: testOnInputReady
1671  * @tc.desc: IMC testOnInputReady
1672  * @tc.type: IMC
1673  * @tc.require:
1674  */
1675 HWTEST_F(InputMethodControllerTest, testOnInputReady, TestSize.Level0)
1676 {
1677     IMSA_HILOGI("IMC OnInputReady Test START");
1678     InputAttribute inputAttribute = { .isTextPreviewSupported = true };
1679     inputMethodController_->Attach(textListener_, false, inputAttribute);
1680     sptr<IRemoteObject> agentObject = nullptr;
1681     inputMethodController_->OnInputReady(agentObject);
1682     TextListener::ResetParam();
1683     inputMethodController_->DeactivateClient();
1684     EXPECT_FALSE(TextListener::isFinishTextPreviewCalled_);
1685 }
1686 } // namespace MiscServices
1687 } // namespace OHOS