• 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 #undef private
19 
20 #include <event_handler.h>
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23 #include <string_ex.h>
24 #include <sys/time.h>
25 
26 #include <condition_variable>
27 #include <csignal>
28 #include <cstdint>
29 #include <functional>
30 #include <mutex>
31 #include <string>
32 #include <thread>
33 #include <vector>
34 
35 #include "ability_manager_client.h"
36 #include "block_data.h"
37 #include "global.h"
38 #include "i_input_method_agent.h"
39 #include "i_input_method_system_ability.h"
40 #include "if_system_ability_manager.h"
41 #include "input_client_stub.h"
42 #include "input_data_channel_stub.h"
43 #include "input_death_recipient.h"
44 #include "input_method_ability.h"
45 #include "input_method_engine_listener_impl.h"
46 #include "input_method_system_ability_proxy.h"
47 #include "input_method_utils.h"
48 #include "iservice_registry.h"
49 #include "key_event_util.h"
50 #include "keyboard_listener.h"
51 #include "message_parcel.h"
52 #include "system_ability.h"
53 #include "system_ability_definition.h"
54 #include "tdd_util.h"
55 #include "text_listener.h"
56 
57 using namespace testing;
58 using namespace testing::ext;
59 namespace OHOS {
60 namespace MiscServices {
61 constexpr uint32_t RETRY_TIME = 200 * 1000;
62 constexpr uint32_t RETRY_TIMES = 5;
63 using WindowMgr = TddUtil::WindowManager;
64 
65 class SelectListenerMock : public ControllerListener {
66 public:
67     SelectListenerMock() = default;
68     ~SelectListenerMock() override = default;
69 
70     MOCK_METHOD2(OnSelectByRange, void(int32_t start, int32_t end));
71     MOCK_METHOD1(OnSelectByMovement, void(int32_t direction));
72 };
73 
74 class InputMethodControllerTest : public testing::Test {
75 public:
76     static void SetUpTestCase(void);
77     static void TearDownTestCase(void);
78     void SetUp();
79     void TearDown();
80     static void SetInputDeathRecipient();
81     static void OnRemoteSaDied(const wptr<IRemoteObject> &remote);
82     static bool CheckKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent);
83     static bool WaitRemoteDiedCallback();
84     static void WaitKeyboardStatusCallback(bool keyboardState);
85     static void TriggerConfigurationChangeCallback(Configuration &info);
86     static void TriggerCursorUpdateCallback(CursorInfo &info);
87     static void TriggerSelectionChangeCallback(std::u16string &text, int start, int end);
88     static void CheckProxyObject();
89     static sptr<InputMethodController> inputMethodController_;
90     static sptr<InputMethodAbility> inputMethodAbility_;
91     static std::shared_ptr<MMI::KeyEvent> keyEvent_;
92     static std::shared_ptr<InputMethodEngineListenerImpl> imeListener_;
93     static std::shared_ptr<SelectListenerMock> controllerListener_;
94     static sptr<OnTextChangedListener> textListener_;
95     static std::mutex keyboardListenerMutex_;
96     static std::condition_variable keyboardListenerCv_;
97     static BlockData<std::shared_ptr<MMI::KeyEvent>> blockKeyEvent_;
98     static BlockData<std::shared_ptr<MMI::KeyEvent>> blockFullKeyEvent_;
99     static std::mutex onRemoteSaDiedMutex_;
100     static std::condition_variable onRemoteSaDiedCv_;
101     static sptr<InputDeathRecipient> deathRecipient_;
102     static CursorInfo cursorInfo_;
103     static int32_t oldBegin_;
104     static int32_t oldEnd_;
105     static int32_t newBegin_;
106     static int32_t newEnd_;
107     static std::string text_;
108     static bool doesKeyEventConsume_;
109     static bool doesFUllKeyEventConsume_;
110     static InputAttribute inputAttribute_;
111     static std::shared_ptr<AppExecFwk::EventHandler> textConfigHandler_;
112     static constexpr uint32_t DELAY_TIME = 1;
113     static constexpr uint32_t KEY_EVENT_DELAY_TIME = 100;
114     static constexpr int32_t TASK_DELAY_TIME = 10;
115 
116     class KeyboardListenerImpl : public KeyboardListener {
117     public:
KeyboardListenerImpl()118         KeyboardListenerImpl()
119         {
120             std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create("InputMethodControllerTe"
121                                                                                               "st");
122             textConfigHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
123         };
~KeyboardListenerImpl()124         ~KeyboardListenerImpl(){};
OnKeyEvent(int32_t keyCode,int32_t keyStatus)125         bool OnKeyEvent(int32_t keyCode, int32_t keyStatus) override
126         {
127             if (!doesKeyEventConsume_) {
128                 return false;
129             }
130             IMSA_HILOGI("KeyboardListenerImpl::OnKeyEvent %{public}d %{public}d", keyCode, keyStatus);
131             auto keyEvent = KeyEventUtil::CreateKeyEvent(keyCode, keyStatus);
132             blockKeyEvent_.SetValue(keyEvent);
133             return true;
134         }
OnKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)135         bool OnKeyEvent(const std::shared_ptr<MMI::KeyEvent> &keyEvent) override
136         {
137             if (!doesFUllKeyEventConsume_) {
138                 return false;
139             }
140             IMSA_HILOGI("KeyboardListenerImpl::OnKeyEvent %{public}d %{public}d", keyEvent->GetKeyCode(),
141                 keyEvent->GetKeyAction());
142             auto fullKey = keyEvent;
143             blockFullKeyEvent_.SetValue(fullKey);
144             return true;
145         }
OnCursorUpdate(int32_t positionX,int32_t positionY,int32_t height)146         void OnCursorUpdate(int32_t positionX, int32_t positionY, int32_t height) override
147         {
148             IMSA_HILOGD(
149                 "KeyboardListenerImpl::OnCursorUpdate %{public}d %{public}d %{public}d", positionX, positionY, height);
150             cursorInfo_ = { static_cast<double>(positionX), static_cast<double>(positionY), 0,
151                 static_cast<double>(height) };
152             InputMethodControllerTest::keyboardListenerCv_.notify_one();
153         }
OnSelectionChange(int32_t oldBegin,int32_t oldEnd,int32_t newBegin,int32_t newEnd)154         void OnSelectionChange(int32_t oldBegin, int32_t oldEnd, int32_t newBegin, int32_t newEnd) override
155         {
156             IMSA_HILOGD("KeyboardListenerImpl::OnSelectionChange %{public}d %{public}d %{public}d %{public}d",
157                 oldBegin, oldEnd, newBegin, newBegin);
158             oldBegin_ = oldBegin;
159             oldEnd_ = oldEnd;
160             newBegin_ = newBegin;
161             newEnd_ = newEnd;
162             InputMethodControllerTest::keyboardListenerCv_.notify_one();
163         }
OnTextChange(const std::string & text)164         void OnTextChange(const std::string &text) override
165         {
166             IMSA_HILOGD("KeyboardListenerImpl::OnTextChange text: %{public}s", text.c_str());
167             text_ = text;
168             InputMethodControllerTest::keyboardListenerCv_.notify_one();
169         }
OnEditorAttributeChange(const InputAttribute & inputAttribute)170         void OnEditorAttributeChange(const InputAttribute &inputAttribute) override
171         {
172             IMSA_HILOGD("KeyboardListenerImpl in.");
173             inputAttribute_ = inputAttribute;
174             InputMethodControllerTest::keyboardListenerCv_.notify_one();
175         }
176     };
177 };
178 sptr<InputMethodController> InputMethodControllerTest::inputMethodController_;
179 sptr<InputMethodAbility> InputMethodControllerTest::inputMethodAbility_;
180 std::shared_ptr<MMI::KeyEvent> InputMethodControllerTest::keyEvent_;
181 std::shared_ptr<InputMethodEngineListenerImpl> InputMethodControllerTest::imeListener_;
182 std::shared_ptr<SelectListenerMock> InputMethodControllerTest::controllerListener_;
183 sptr<OnTextChangedListener> InputMethodControllerTest::textListener_;
184 CursorInfo InputMethodControllerTest::cursorInfo_ = {};
185 int32_t InputMethodControllerTest::oldBegin_ = 0;
186 int32_t InputMethodControllerTest::oldEnd_ = 0;
187 int32_t InputMethodControllerTest::newBegin_ = 0;
188 int32_t InputMethodControllerTest::newEnd_ = 0;
189 std::string InputMethodControllerTest::text_;
190 InputAttribute InputMethodControllerTest::inputAttribute_;
191 std::mutex InputMethodControllerTest::keyboardListenerMutex_;
192 std::condition_variable InputMethodControllerTest::keyboardListenerCv_;
193 sptr<InputDeathRecipient> InputMethodControllerTest::deathRecipient_;
194 std::mutex InputMethodControllerTest::onRemoteSaDiedMutex_;
195 std::condition_variable InputMethodControllerTest::onRemoteSaDiedCv_;
196 BlockData<std::shared_ptr<MMI::KeyEvent>> InputMethodControllerTest::blockKeyEvent_{
197     InputMethodControllerTest::KEY_EVENT_DELAY_TIME, nullptr
198 };
199 BlockData<std::shared_ptr<MMI::KeyEvent>> InputMethodControllerTest::blockFullKeyEvent_{
200     InputMethodControllerTest::KEY_EVENT_DELAY_TIME, nullptr
201 };
202 bool InputMethodControllerTest::doesKeyEventConsume_{ false };
203 bool InputMethodControllerTest::doesFUllKeyEventConsume_{ false };
204 std::shared_ptr<AppExecFwk::EventHandler> InputMethodControllerTest::textConfigHandler_{ nullptr };
205 
SetUpTestCase(void)206 void InputMethodControllerTest::SetUpTestCase(void)
207 {
208     IMSA_HILOGI("InputMethodControllerTest::SetUpTestCase");
209     TddUtil::StorageSelfTokenID();
210     // Set the tokenID to the tokenID of the current ime
211     std::shared_ptr<Property> property = InputMethodController::GetInstance()->GetCurrentInputMethod();
212     std::string bundleName = property != nullptr ? property->name : "default.inputmethod.unittest";
213     TddUtil::SetTestTokenID(TddUtil::GetTestTokenID(bundleName));
214     inputMethodAbility_ = InputMethodAbility::GetInstance();
215     inputMethodAbility_->SetCoreAndAgent();
216     inputMethodAbility_->OnImeReady();
217     imeListener_ = std::make_shared<InputMethodEngineListenerImpl>();
218     controllerListener_ = std::make_shared<SelectListenerMock>();
219     textListener_ = new TextListener();
220     inputMethodAbility_->SetKdListener(std::make_shared<KeyboardListenerImpl>());
221     inputMethodAbility_->SetImeListener(imeListener_);
222     inputMethodController_ = InputMethodController::GetInstance();
223 
224     keyEvent_ = KeyEventUtil::CreateKeyEvent(MMI::KeyEvent::KEYCODE_A, MMI::KeyEvent::KEY_ACTION_DOWN);
225     keyEvent_->SetFunctionKey(MMI::KeyEvent::NUM_LOCK_FUNCTION_KEY, 0);
226     keyEvent_->SetFunctionKey(MMI::KeyEvent::CAPS_LOCK_FUNCTION_KEY, 1);
227     keyEvent_->SetFunctionKey(MMI::KeyEvent::SCROLL_LOCK_FUNCTION_KEY, 1);
228     TddUtil::SetTestTokenID(TddUtil::AllocTestTokenID(true, true, "undefine"));
229 
230     TddUtil::WindowManager::RegisterFocusChangeListener();
231     WindowMgr::CreateWindow();
232     WindowMgr::ShowWindow();
233     bool isFocused = FocusChangedListenerTestImpl::isFocused_->GetValue();
234     IMSA_HILOGI("getFocus end, isFocused = %{public}d", isFocused);
235     SetInputDeathRecipient();
236     TextListener::ResetParam();
237 }
238 
TearDownTestCase(void)239 void InputMethodControllerTest::TearDownTestCase(void)
240 {
241     IMSA_HILOGI("InputMethodControllerTest::TearDownTestCase");
242     TddUtil::RestoreSelfTokenID();
243     TextListener::ResetParam();
244     WindowMgr::HideWindow();
245     WindowMgr::DestroyWindow();
246     inputMethodController_->SetControllerListener(nullptr);
247 }
248 
SetUp(void)249 void InputMethodControllerTest::SetUp(void)
250 {
251     IMSA_HILOGI("InputMethodControllerTest::SetUp");
252 }
253 
TearDown(void)254 void InputMethodControllerTest::TearDown(void)
255 {
256     IMSA_HILOGI("InputMethodControllerTest::TearDown");
257 }
258 
SetInputDeathRecipient()259 void InputMethodControllerTest::SetInputDeathRecipient()
260 {
261     IMSA_HILOGI("InputMethodControllerTest::SetInputDeathRecipient");
262     sptr<ISystemAbilityManager> systemAbilityManager =
263         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
264     if (systemAbilityManager == nullptr) {
265         IMSA_HILOGI("InputMethodControllerTest, system ability manager is nullptr");
266         return;
267     }
268     auto systemAbility = systemAbilityManager->GetSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID, "");
269     if (systemAbility == nullptr) {
270         IMSA_HILOGI("InputMethodControllerTest, system ability is nullptr");
271         return;
272     }
273     deathRecipient_ = new (std::nothrow) InputDeathRecipient();
274     if (deathRecipient_ == nullptr) {
275         IMSA_HILOGE("InputMethodControllerTest, new death recipient failed");
276         return;
277     }
278     deathRecipient_->SetDeathRecipient([](const wptr<IRemoteObject> &remote) { OnRemoteSaDied(remote); });
279     if ((systemAbility->IsProxyObject()) && (!systemAbility->AddDeathRecipient(deathRecipient_))) {
280         IMSA_HILOGE("InputMethodControllerTest, failed to add death recipient.");
281         return;
282     }
283 }
284 
OnRemoteSaDied(const wptr<IRemoteObject> & remote)285 void InputMethodControllerTest::OnRemoteSaDied(const wptr<IRemoteObject> &remote)
286 {
287     IMSA_HILOGI("InputMethodControllerTest::OnRemoteSaDied");
288     onRemoteSaDiedCv_.notify_one();
289 }
290 
WaitRemoteDiedCallback()291 bool InputMethodControllerTest::WaitRemoteDiedCallback()
292 {
293     IMSA_HILOGI("InputMethodControllerTest::WaitRemoteDiedCallback");
294     std::unique_lock<std::mutex> lock(onRemoteSaDiedMutex_);
295     // 2 means wait 2 seconds.
296     return onRemoteSaDiedCv_.wait_for(lock, std::chrono::seconds(2)) != std::cv_status::timeout;
297 }
298 
CheckProxyObject()299 void InputMethodControllerTest::CheckProxyObject()
300 {
301     for (uint32_t retryTimes = 0; retryTimes < RETRY_TIMES; ++retryTimes) {
302         IMSA_HILOGI("times = %{public}d", retryTimes);
303         sptr<ISystemAbilityManager> systemAbilityManager =
304             SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
305         if (systemAbilityManager == nullptr) {
306             IMSA_HILOGI("system ability manager is nullptr");
307             continue;
308         }
309         auto systemAbility = systemAbilityManager->CheckSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID);
310         if (systemAbility != nullptr) {
311             IMSA_HILOGI("CheckProxyObject success!");
312             break;
313         }
314         usleep(RETRY_TIME);
315     }
316 }
317 
CheckKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)318 bool InputMethodControllerTest::CheckKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)
319 {
320     bool ret = keyEvent->GetKeyCode() == keyEvent_->GetKeyCode();
321     EXPECT_TRUE(ret);
322     ret = keyEvent->GetKeyAction() == keyEvent_->GetKeyAction();
323     EXPECT_TRUE(ret);
324     ret = keyEvent->GetKeyIntention() == keyEvent_->GetKeyIntention();
325     EXPECT_TRUE(ret);
326     // check function key state
327     ret = keyEvent->GetFunctionKey(MMI::KeyEvent::NUM_LOCK_FUNCTION_KEY)
328           == keyEvent_->GetFunctionKey(MMI::KeyEvent::NUM_LOCK_FUNCTION_KEY);
329     EXPECT_TRUE(ret);
330     ret = keyEvent->GetFunctionKey(MMI::KeyEvent::CAPS_LOCK_FUNCTION_KEY)
331           == keyEvent_->GetFunctionKey(MMI::KeyEvent::CAPS_LOCK_FUNCTION_KEY);
332     EXPECT_TRUE(ret);
333     ret = keyEvent->GetFunctionKey(MMI::KeyEvent::SCROLL_LOCK_FUNCTION_KEY)
334           == keyEvent_->GetFunctionKey(MMI::KeyEvent::SCROLL_LOCK_FUNCTION_KEY);
335     EXPECT_TRUE(ret);
336     // check KeyItem
337     ret = keyEvent->GetKeyItems().size() == keyEvent_->GetKeyItems().size();
338     EXPECT_TRUE(ret);
339     ret = keyEvent->GetKeyItem()->GetKeyCode() == keyEvent_->GetKeyItem()->GetKeyCode();
340     EXPECT_TRUE(ret);
341     ret = keyEvent->GetKeyItem()->GetDownTime() == keyEvent_->GetKeyItem()->GetDownTime();
342     EXPECT_TRUE(ret);
343     ret = keyEvent->GetKeyItem()->GetDeviceId() == keyEvent_->GetKeyItem()->GetDeviceId();
344     EXPECT_TRUE(ret);
345     ret = keyEvent->GetKeyItem()->IsPressed() == keyEvent_->GetKeyItem()->IsPressed();
346     EXPECT_TRUE(ret);
347     ret = keyEvent->GetKeyItem()->GetUnicode() == keyEvent_->GetKeyItem()->GetUnicode();
348     EXPECT_TRUE(ret);
349     return ret;
350 }
351 
WaitKeyboardStatusCallback(bool keyboardState)352 void InputMethodControllerTest::WaitKeyboardStatusCallback(bool keyboardState)
353 {
354     std::unique_lock<std::mutex> lock(InputMethodEngineListenerImpl::imeListenerMutex_);
355     InputMethodEngineListenerImpl::imeListenerCv_.wait_for(lock,
356         std::chrono::seconds(InputMethodControllerTest::DELAY_TIME),
357         [keyboardState] { return InputMethodEngineListenerImpl::keyboardState_ == keyboardState; });
358 }
359 
TriggerConfigurationChangeCallback(Configuration & info)360 void InputMethodControllerTest::TriggerConfigurationChangeCallback(Configuration &info)
361 {
362     textConfigHandler_->PostTask(
363         [info]() { inputMethodController_->OnConfigurationChange(info); }, InputMethodControllerTest::TASK_DELAY_TIME);
364     {
365         std::unique_lock<std::mutex> lock(InputMethodControllerTest::keyboardListenerMutex_);
366         InputMethodControllerTest::keyboardListenerCv_.wait_for(
367             lock, std::chrono::seconds(InputMethodControllerTest::DELAY_TIME), [&info] {
368                 return (static_cast<OHOS::MiscServices::TextInputType>(
369                             InputMethodControllerTest::inputAttribute_.inputPattern)
370                            == info.GetTextInputType())
371                        && (static_cast<OHOS::MiscServices::EnterKeyType>(
372                                InputMethodControllerTest::inputAttribute_.enterKeyType)
373                            == info.GetEnterKeyType());
374             });
375     }
376 }
377 
TriggerCursorUpdateCallback(CursorInfo & info)378 void InputMethodControllerTest::TriggerCursorUpdateCallback(CursorInfo &info)
379 {
380     textConfigHandler_->PostTask(
381         [info]() { inputMethodController_->OnCursorUpdate(info); }, InputMethodControllerTest::TASK_DELAY_TIME);
382     {
383         std::unique_lock<std::mutex> lock(InputMethodControllerTest::keyboardListenerMutex_);
384         InputMethodControllerTest::keyboardListenerCv_.wait_for(lock,
385             std::chrono::seconds(InputMethodControllerTest::DELAY_TIME),
386             [&info] { return InputMethodControllerTest::cursorInfo_ == info; });
387     }
388 }
389 
TriggerSelectionChangeCallback(std::u16string & text,int start,int end)390 void InputMethodControllerTest::TriggerSelectionChangeCallback(std::u16string &text, int start, int end)
391 {
392     textConfigHandler_->PostTask([text, start, end]() { inputMethodController_->OnSelectionChange(text, start, end); },
393         InputMethodControllerTest::TASK_DELAY_TIME);
394     {
395         std::unique_lock<std::mutex> lock(InputMethodControllerTest::keyboardListenerMutex_);
396         InputMethodControllerTest::keyboardListenerCv_.wait_for(lock,
397             std::chrono::seconds(InputMethodControllerTest::DELAY_TIME),
398             [&text] { return InputMethodControllerTest::text_ == Str16ToStr8(text); });
399     }
400 }
401 
402 /**
403  * @tc.name: testIMCAttach
404  * @tc.desc: IMC Attach.
405  * @tc.type: FUNC
406  * @tc.require:
407  */
408 HWTEST_F(InputMethodControllerTest, testIMCAttach, TestSize.Level0)
409 {
410     IMSA_HILOGD("IMC Attach Test START");
411     imeListener_->isInputStart_ = false;
412     inputMethodController_->Attach(textListener_, false);
413     inputMethodController_->Attach(textListener_);
414     inputMethodController_->Attach(textListener_, true);
415     EXPECT_TRUE(TextListener::WaitIMACallback());
416     EXPECT_TRUE(imeListener_->isInputStart_ && imeListener_->keyboardState_);
417 }
418 
419 /**
420  * @tc.name: testIMCSetCallingWindow
421  * @tc.desc: IMC SetCallingWindow.
422  * @tc.type: FUNC
423  * @tc.require:
424  */
425 HWTEST_F(InputMethodControllerTest, testIMCSetCallingWindow, TestSize.Level0)
426 {
427     IMSA_HILOGD("IMC SetCallingWindow Test START");
428     auto ret = inputMethodController_->Attach(textListener_);
429     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
430     uint32_t windowId = 3;
431     ret = inputMethodController_->SetCallingWindow(windowId);
432     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
433     EXPECT_EQ(windowId, imeListener_->windowId_);
434 }
435 
436 /**
437  * @tc.name: testGetIMSAProxy
438  * @tc.desc: Get Imsa Proxy.
439  * @tc.type: FUNC
440  */
441 HWTEST_F(InputMethodControllerTest, testGetIMSAProxy, TestSize.Level0)
442 {
443     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
444     EXPECT_TRUE(systemAbilityManager != nullptr);
445     auto systemAbility = systemAbilityManager->GetSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID, "");
446     EXPECT_TRUE(systemAbility != nullptr);
447 }
448 
449 /**
450  * @tc.name: testWriteReadIInputDataChannel
451  * @tc.desc: Checkout IInputDataChannel.
452  * @tc.type: FUNC
453  */
454 HWTEST_F(InputMethodControllerTest, testWriteReadIInputDataChannel, TestSize.Level0)
455 {
456     sptr<InputDataChannelStub> mInputDataChannel = new InputDataChannelStub();
457     MessageParcel data;
458     auto ret = data.WriteRemoteObject(mInputDataChannel->AsObject());
459     EXPECT_TRUE(ret);
460     auto remoteObject = data.ReadRemoteObject();
461     sptr<IInputDataChannel> iface = iface_cast<IInputDataChannel>(remoteObject);
462     EXPECT_TRUE(iface != nullptr);
463 }
464 
465 /**
466  * @tc.name: testIMCBindToIMSA
467  * @tc.desc: Bind IMSA.
468  * @tc.type: FUNC
469  */
470 HWTEST_F(InputMethodControllerTest, testIMCBindToIMSA, TestSize.Level0)
471 {
472     sptr<InputClientStub> mClient = new InputClientStub();
473     MessageParcel data;
474     auto ret = data.WriteRemoteObject(mClient->AsObject());
475     EXPECT_TRUE(ret);
476     auto remoteObject = data.ReadRemoteObject();
477     sptr<IInputClient> iface = iface_cast<IInputClient>(remoteObject);
478     EXPECT_TRUE(iface != nullptr);
479 }
480 
481 /**
482  * @tc.name: testIMCDispatchKeyEvent001
483  * @tc.desc: test IMC DispatchKeyEvent with 'keyDown/KeyUP'.
484  * @tc.type: FUNC
485  * @tc.require:
486  */
487 HWTEST_F(InputMethodControllerTest, testIMCDispatchKeyEvent001, TestSize.Level0)
488 {
489     IMSA_HILOGI("IMC testIMCDispatchKeyEvent001 Test START");
490     doesKeyEventConsume_ = true;
491     doesFUllKeyEventConsume_ = false;
492     blockKeyEvent_.Clear(nullptr);
493     auto res = inputMethodController_->Attach(textListener_);
494     EXPECT_EQ(res, ErrorCode::NO_ERROR);
495     bool ret = inputMethodController_->DispatchKeyEvent(keyEvent_);
496     EXPECT_TRUE(ret);
497     auto keyEvent = blockKeyEvent_.GetValue();
498     ASSERT_NE(keyEvent, nullptr);
499     EXPECT_EQ(keyEvent->GetKeyCode(), keyEvent_->GetKeyCode());
500     EXPECT_EQ(keyEvent->GetKeyAction(), keyEvent_->GetKeyAction());
501 }
502 
503 /**
504  * @tc.name: testIMCDispatchKeyEvent002
505  * @tc.desc: test IMC DispatchKeyEvent with 'keyEvent'.
506  * @tc.type: FUNC
507  * @tc.require:
508  */
509 HWTEST_F(InputMethodControllerTest, testIMCDispatchKeyEvent002, TestSize.Level0)
510 {
511     IMSA_HILOGI("IMC testIMCDispatchKeyEvent002 Test START");
512     doesKeyEventConsume_ = false;
513     doesFUllKeyEventConsume_ = true;
514     blockFullKeyEvent_.Clear(nullptr);
515     bool ret = inputMethodController_->DispatchKeyEvent(keyEvent_);
516     EXPECT_TRUE(ret);
517     auto keyEvent = blockFullKeyEvent_.GetValue();
518     EXPECT_NE(keyEvent, nullptr);
519     EXPECT_TRUE(CheckKeyEvent(keyEvent));
520 }
521 
522 /**
523  * @tc.name: testIMCDispatchKeyEvent003
524  * @tc.desc: test IMC DispatchKeyEvent with 'keyDown/KeyUP' and 'keyEvent'.
525  * @tc.type: FUNC
526  * @tc.require:
527  */
528 HWTEST_F(InputMethodControllerTest, testIMCDispatchKeyEvent003, TestSize.Level0)
529 {
530     IMSA_HILOGI("IMC testIMCDispatchKeyEvent003 Test START");
531     doesKeyEventConsume_ = true;
532     doesFUllKeyEventConsume_ = true;
533     blockKeyEvent_.Clear(nullptr);
534     blockFullKeyEvent_.Clear(nullptr);
535     bool ret = inputMethodController_->DispatchKeyEvent(keyEvent_);
536     EXPECT_TRUE(ret);
537     auto keyEvent = blockKeyEvent_.GetValue();
538     auto keyFullEvent = blockFullKeyEvent_.GetValue();
539     EXPECT_NE(keyEvent, nullptr);
540     EXPECT_NE(keyFullEvent, nullptr);
541     EXPECT_EQ(keyEvent->GetKeyCode(), keyEvent_->GetKeyCode());
542     EXPECT_EQ(keyEvent->GetKeyAction(), keyEvent_->GetKeyAction());
543     EXPECT_TRUE(CheckKeyEvent(keyFullEvent));
544 }
545 
546 /**
547  * @tc.name: testIMCOnCursorUpdate01
548  * @tc.desc: Test update cursorInfo, call 'OnCursorUpdate' twice, if cursorInfo is the same,
549  *           the second time will not get callback.
550  * @tc.type: FUNC
551  * @tc.require:
552  * @tc.author: Zhaolinglan
553  */
554 HWTEST_F(InputMethodControllerTest, testIMCOnCursorUpdate01, TestSize.Level0)
555 {
556     IMSA_HILOGI("IMC testIMCOnCursorUpdate01 Test START");
557     auto ret = inputMethodController_->Attach(textListener_, false);
558     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
559     CursorInfo info = { 1, 3, 0, 5 };
560     InputMethodControllerTest::TriggerCursorUpdateCallback(info);
561     EXPECT_EQ(InputMethodControllerTest::cursorInfo_, info);
562 
563     InputMethodControllerTest::cursorInfo_ = {};
564     InputMethodControllerTest::TriggerCursorUpdateCallback(info);
565     EXPECT_FALSE(InputMethodControllerTest::cursorInfo_ == info);
566 }
567 
568 /**
569  * @tc.name: testIMCOnCursorUpdate02
570  * @tc.desc: Test update cursorInfo, 'Attach'->'OnCursorUpdate'->'Close'->'Attach'->'OnCursorUpdate',
571  *           it will get callback two time.
572  * @tc.type: FUNC
573  * @tc.require:
574  * @tc.author: Zhaolinglan
575  */
576 HWTEST_F(InputMethodControllerTest, testIMCOnCursorUpdate02, TestSize.Level0)
577 {
578     IMSA_HILOGI("IMC testIMCOnCursorUpdate02 Test START");
579     auto ret = inputMethodController_->Attach(textListener_, false);
580     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
581     CursorInfo info = { 2, 4, 0, 6 };
582     InputMethodControllerTest::TriggerCursorUpdateCallback(info);
583     EXPECT_EQ(InputMethodControllerTest::cursorInfo_, info);
584 
585     InputMethodControllerTest::cursorInfo_ = {};
586     ret = InputMethodControllerTest::inputMethodController_->Close();
587     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
588     ret = inputMethodController_->Attach(textListener_, false);
589     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
590     InputMethodControllerTest::TriggerCursorUpdateCallback(info);
591     EXPECT_EQ(InputMethodControllerTest::cursorInfo_, info);
592 }
593 
594 /**
595  * @tc.name: testIMCOnSelectionChange01
596  * @tc.desc: Test change selection, call 'OnSelectionChange' twice, if selection is the same,
597  *           the second time will not get callback.
598  * @tc.type: FUNC
599  * @tc.require:
600  * @tc.author: Zhaolinglan
601  */
602 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange01, TestSize.Level0)
603 {
604     IMSA_HILOGI("IMC testIMCOnSelectionChange01 Test START");
605     auto ret = inputMethodController_->Attach(textListener_, false);
606     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
607     std::u16string text = Str8ToStr16("testSelect");
608     int start = 1;
609     int end = 2;
610     InputMethodControllerTest::TriggerSelectionChangeCallback(text, start, end);
611     EXPECT_EQ(InputMethodControllerTest::text_, Str16ToStr8(text));
612 
613     InputMethodControllerTest::text_ = "";
614     InputMethodControllerTest::TriggerSelectionChangeCallback(text, start, end);
615     EXPECT_NE(InputMethodControllerTest::text_, Str16ToStr8(text));
616 }
617 
618 /**
619  * @tc.name: testIMCOnSelectionChange02
620  * @tc.desc: Test change selection, 'Attach'->'OnSelectionChange'->'Close'->'Attach'->'OnSelectionChange',
621  *           it will get callback two time.
622  * @tc.type: FUNC
623  * @tc.require:
624  * @tc.author: Zhaolinglan
625  */
626 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange02, TestSize.Level0)
627 {
628     IMSA_HILOGI("IMC testIMCOnSelectionChange02 Test START");
629     auto ret = inputMethodController_->Attach(textListener_, false);
630     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
631     std::u16string text = Str8ToStr16("testSelect2");
632     int start = 1;
633     int end = 2;
634     InputMethodControllerTest::TriggerSelectionChangeCallback(text, start, end);
635     EXPECT_EQ(InputMethodControllerTest::text_, Str16ToStr8(text));
636 
637     InputMethodControllerTest::text_ = "";
638     InputMethodControllerTest::inputMethodController_->Close();
639     inputMethodController_->Attach(textListener_, false);
640     InputMethodControllerTest::TriggerSelectionChangeCallback(text, start, end);
641     EXPECT_EQ(InputMethodControllerTest::text_, Str16ToStr8(text));
642 }
643 
644 /**
645  * @tc.name: testShowTextInput
646  * @tc.desc: IMC ShowTextInput
647  * @tc.type: FUNC
648  */
649 HWTEST_F(InputMethodControllerTest, testShowTextInput, TestSize.Level0)
650 {
651     IMSA_HILOGI("IMC ShowTextInput Test START");
652     TextListener::keyboardStatus_ = KeyboardStatus::NONE;
653     inputMethodController_->ShowTextInput();
654     EXPECT_TRUE(TextListener::WaitIMACallback());
655     EXPECT_TRUE(TextListener::keyboardStatus_ == KeyboardStatus::SHOW);
656 }
657 
658 /**
659  * @tc.name: testShowSoftKeyboard
660  * @tc.desc: IMC ShowSoftKeyboard
661  * @tc.type: FUNC
662  */
663 HWTEST_F(InputMethodControllerTest, testShowSoftKeyboard, TestSize.Level0)
664 {
665     IMSA_HILOGI("IMC ShowSoftKeyboard Test START");
666     imeListener_->keyboardState_ = false;
667     TextListener::keyboardStatus_ = KeyboardStatus::NONE;
668     int32_t ret = inputMethodController_->ShowSoftKeyboard();
669     EXPECT_TRUE(TextListener::WaitIMACallback());
670     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
671     EXPECT_TRUE(imeListener_->keyboardState_ && TextListener::keyboardStatus_ == KeyboardStatus::SHOW);
672 }
673 
674 /**
675  * @tc.name: testShowCurrentInput
676  * @tc.desc: IMC ShowCurrentInput
677  * @tc.type: FUNC
678  */
679 HWTEST_F(InputMethodControllerTest, testShowCurrentInput, TestSize.Level0)
680 {
681     IMSA_HILOGI("IMC ShowCurrentInput Test START");
682     imeListener_->keyboardState_ = false;
683     TextListener::keyboardStatus_ = KeyboardStatus::NONE;
684     int32_t ret = inputMethodController_->ShowCurrentInput();
685     EXPECT_TRUE(TextListener::WaitIMACallback());
686     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
687     EXPECT_TRUE(imeListener_->keyboardState_ && TextListener::keyboardStatus_ == KeyboardStatus::SHOW);
688 }
689 
690 /**
691  * @tc.name: testIMCGetEnterKeyType
692  * @tc.desc: IMC testGetEnterKeyType.
693  * @tc.type: FUNC
694  * @tc.require:
695  */
696 HWTEST_F(InputMethodControllerTest, testIMCGetEnterKeyType, TestSize.Level0)
697 {
698     IMSA_HILOGI("IMC GetEnterKeyType Test START");
699     int32_t keyType;
700     inputMethodController_->GetEnterKeyType(keyType);
701     EXPECT_TRUE(keyType >= static_cast<int32_t>(EnterKeyType::UNSPECIFIED)
702                 && keyType <= static_cast<int32_t>(EnterKeyType::PREVIOUS));
703 }
704 
705 /**
706  * @tc.name: testIMCGetInputPattern
707  * @tc.desc: IMC testGetInputPattern.
708  * @tc.type: FUNC
709  * @tc.require:
710  */
711 HWTEST_F(InputMethodControllerTest, testIMCGetInputPattern, TestSize.Level0)
712 {
713     IMSA_HILOGI("IMC GetInputPattern Test START");
714     int32_t inputPattern;
715     inputMethodController_->GetInputPattern(inputPattern);
716     EXPECT_TRUE(inputPattern >= static_cast<int32_t>(TextInputType::NONE)
717                 && inputPattern <= static_cast<int32_t>(TextInputType::VISIBLE_PASSWORD));
718 }
719 
720 /**
721  * @tc.name: testOnEditorAttributeChanged
722  * @tc.desc: IMC testOnEditorAttributeChanged.
723  * @tc.type: FUNC
724  * @tc.require:
725  */
726 HWTEST_F(InputMethodControllerTest, testOnEditorAttributeChanged, TestSize.Level0)
727 {
728     IMSA_HILOGI("IMC testOnEditorAttributeChanged Test START");
729     auto ret = inputMethodController_->Attach(textListener_, false);
730     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
731     Configuration info;
732     info.SetEnterKeyType(EnterKeyType::GO);
733     info.SetTextInputType(TextInputType::NUMBER);
734     InputMethodControllerTest::TriggerConfigurationChangeCallback(info);
735     EXPECT_EQ(InputMethodControllerTest::inputAttribute_.inputPattern, static_cast<int32_t>(info.GetTextInputType()));
736     EXPECT_EQ(InputMethodControllerTest::inputAttribute_.enterKeyType, static_cast<int32_t>(info.GetEnterKeyType()));
737 }
738 
739 /**
740  * @tc.name: testHideSoftKeyboard
741  * @tc.desc: IMC HideSoftKeyboard
742  * @tc.type: FUNC
743  */
744 HWTEST_F(InputMethodControllerTest, testHideSoftKeyboard, TestSize.Level0)
745 {
746     IMSA_HILOGI("IMC HideSoftKeyboard Test START");
747     imeListener_->keyboardState_ = true;
748     TextListener::keyboardStatus_ = KeyboardStatus::NONE;
749     int32_t ret = inputMethodController_->HideSoftKeyboard();
750     EXPECT_TRUE(TextListener::WaitIMACallback());
751     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
752     EXPECT_TRUE(!imeListener_->keyboardState_ && TextListener::keyboardStatus_ == KeyboardStatus::HIDE);
753 }
754 
755 /**
756  * @tc.name: testIMCHideCurrentInput
757  * @tc.desc: IMC HideCurrentInput.
758  * @tc.type: FUNC
759  * @tc.require:
760  */
761 HWTEST_F(InputMethodControllerTest, testIMCHideCurrentInput, TestSize.Level0)
762 {
763     IMSA_HILOGI("IMC HideCurrentInput Test START");
764     imeListener_->keyboardState_ = true;
765     TextListener::keyboardStatus_ = KeyboardStatus::NONE;
766     int32_t ret = inputMethodController_->HideCurrentInput();
767     EXPECT_TRUE(TextListener::WaitIMACallback());
768     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
769     EXPECT_TRUE(!imeListener_->keyboardState_ && TextListener::keyboardStatus_ == KeyboardStatus::HIDE);
770 }
771 
772 /**
773  * @tc.name: testIMCInputStopSession
774  * @tc.desc: IMC testInputStopSession.
775  * @tc.type: FUNC
776  * @tc.require: issueI5U8FZ
777  * @tc.author: Hollokin
778  */
779 HWTEST_F(InputMethodControllerTest, testIMCInputStopSession, TestSize.Level0)
780 {
781     IMSA_HILOGI("IMC StopInputSession Test START");
782     imeListener_->keyboardState_ = true;
783     TextListener::keyboardStatus_ = KeyboardStatus::NONE;
784     int32_t ret = inputMethodController_->StopInputSession();
785     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
786     WaitKeyboardStatusCallback(false);
787     EXPECT_TRUE(!imeListener_->keyboardState_);
788 }
789 
790 /**
791  * @tc.name: testIMCHideTextInput.
792  * @tc.desc: IMC testHideTextInput.
793  * @tc.type: FUNC
794  */
795 HWTEST_F(InputMethodControllerTest, testIMCHideTextInput, TestSize.Level0)
796 {
797     IMSA_HILOGI("IMC HideTextInput Test START");
798     imeListener_->keyboardState_ = true;
799     TextListener::keyboardStatus_ = KeyboardStatus::NONE;
800     inputMethodController_->HideTextInput();
801     WaitKeyboardStatusCallback(false);
802     EXPECT_TRUE(!imeListener_->keyboardState_);
803 }
804 
805 /**
806  * @tc.name: testSetControllerListener
807  * @tc.desc: IMC SetControllerListener
808  * @tc.type: FUNC
809  */
810 HWTEST_F(InputMethodControllerTest, testSetControllerListener, TestSize.Level0)
811 {
812     IMSA_HILOGI("IMC SetControllerListener Test START");
813     inputMethodController_->SetControllerListener(controllerListener_);
814 
815     int32_t ret = inputMethodController_->Attach(textListener_, false);
816     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
817     EXPECT_CALL(*controllerListener_, OnSelectByRange(Eq(1), Eq(2))).Times(1);
818     inputMethodAbility_->SelectByRange(1, 2);
819 
820     Sequence s;
821     EXPECT_CALL(*controllerListener_, OnSelectByMovement(Eq(static_cast<int32_t>(Direction::UP))))
822         .Times(1)
823         .InSequence(s);
824     EXPECT_CALL(*controllerListener_, OnSelectByMovement(Eq(static_cast<int32_t>(Direction::DOWN))))
825         .Times(1)
826         .InSequence(s);
827     EXPECT_CALL(*controllerListener_, OnSelectByMovement(Eq(static_cast<int32_t>(Direction::LEFT))))
828         .Times(1)
829         .InSequence(s);
830     EXPECT_CALL(*controllerListener_, OnSelectByMovement(Eq(static_cast<int32_t>(Direction::RIGHT))))
831         .Times(1)
832         .InSequence(s);
833     inputMethodAbility_->SelectByMovement(static_cast<int32_t>(Direction::UP));
834     inputMethodAbility_->SelectByMovement(static_cast<int32_t>(Direction::DOWN));
835     inputMethodAbility_->SelectByMovement(static_cast<int32_t>(Direction::LEFT));
836     inputMethodAbility_->SelectByMovement(static_cast<int32_t>(Direction::RIGHT));
837     controllerListener_ = nullptr;
838 }
839 
840 /**
841  * @tc.name: testWasAttached
842  * @tc.desc: IMC WasAttached
843  * @tc.type: FUNC
844  */
845 HWTEST_F(InputMethodControllerTest, testWasAttached, TestSize.Level0)
846 {
847     IMSA_HILOGI("IMC WasAttached Test START");
848     inputMethodController_->Close();
849     bool result = inputMethodController_->WasAttached();
850     EXPECT_FALSE(result);
851     int32_t ret = inputMethodController_->Attach(textListener_, false);
852     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
853     result = inputMethodController_->WasAttached();
854     EXPECT_TRUE(result);
855     inputMethodController_->Close();
856 }
857 
858 /**
859  * @tc.name: testWithoutEditableState
860  * @tc.desc: IMC testWithoutEditableState
861  * @tc.type: FUNC
862  * @tc.require:
863  */
864 HWTEST_F(InputMethodControllerTest, testWithoutEditableState, TestSize.Level0)
865 {
866     IMSA_HILOGI("IMC WithouteEditableState Test START");
867     auto ret = inputMethodController_->Attach(textListener_, false);
868     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
869     ret = inputMethodController_->HideTextInput();
870     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
871 
872     int32_t deleteForwardLength = 1;
873     ret = inputMethodAbility_->DeleteForward(deleteForwardLength);
874     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
875     usleep(100);
876     EXPECT_NE(TextListener::deleteForwardLength_, deleteForwardLength);
877 
878     int32_t deleteBackwardLength = 2;
879     ret = inputMethodAbility_->DeleteBackward(deleteBackwardLength);
880     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
881     usleep(100);
882     EXPECT_NE(TextListener::deleteBackwardLength_, deleteBackwardLength);
883 
884     std::string insertText = "t";
885     ret = inputMethodAbility_->InsertText(insertText);
886     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
887     usleep(100);
888     EXPECT_NE(TextListener::insertText_, Str8ToStr16(insertText));
889 
890     constexpr int32_t funcKey = 1;
891     ret = inputMethodAbility_->SendFunctionKey(funcKey);
892     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
893     usleep(100);
894     EXPECT_NE(TextListener::key_, funcKey);
895 
896     constexpr int32_t keyCode = 4;
897     ret = inputMethodAbility_->MoveCursor(keyCode);
898     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
899     usleep(100);
900     EXPECT_NE(TextListener::direction_, keyCode);
901 }
902 
903 /**
904  * @tc.name: testOnRemoteDied
905  * @tc.desc: IMC OnRemoteDied
906  * @tc.type: FUNC
907  */
908 HWTEST_F(InputMethodControllerTest, testOnRemoteDied, TestSize.Level0)
909 {
910     IMSA_HILOGI("IMC OnRemoteDied Test START");
911     int32_t ret = inputMethodController_->Attach(textListener_, true);
912     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
913     pid_t pid = TddUtil::GetImsaPid();
914     EXPECT_TRUE(pid > 0);
915     ret = kill(pid, SIGTERM);
916     EXPECT_EQ(ret, 0);
917     EXPECT_TRUE(WaitRemoteDiedCallback());
918     CheckProxyObject();
919     inputMethodController_->OnRemoteSaDied(nullptr);
920     EXPECT_TRUE(TextListener::WaitIMACallback());
921     bool result = inputMethodController_->WasAttached();
922     EXPECT_TRUE(result);
923     inputMethodController_->Close();
924 }
925 } // namespace MiscServices
926 } // namespace OHOS
927