• 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 <gtest/gtest.h>
22 #include <string_ex.h>
23 #include <sys/time.h>
24 
25 #include <condition_variable>
26 #include <csignal>
27 #include <cstdint>
28 #include <functional>
29 #include <mutex>
30 #include <string>
31 #include <thread>
32 #include <unordered_map>
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 "scope_utils.h"
53 #include "system_ability.h"
54 #include "system_ability_definition.h"
55 #include "tdd_util.h"
56 #include "text_listener.h"
57 
58 using namespace testing;
59 using namespace testing::ext;
60 namespace OHOS {
61 namespace MiscServices {
62 constexpr uint32_t RETRY_TIME = 200 * 1000;
63 constexpr uint32_t RETRY_TIMES = 5;
64 constexpr uint32_t WAIT_INTERVAL = 500;
65 constexpr size_t PRIVATE_COMMAND_SIZE_MAX = 32 * 1024;
66 constexpr uint32_t WAIT_SA_DIE_TIME_OUT = 3;
67 
68 class SelectListenerMock : public ControllerListener {
69 public:
70     SelectListenerMock() = default;
71     ~SelectListenerMock() override = default;
72 
OnSelectByRange(int32_t start,int32_t end)73     void OnSelectByRange(int32_t start, int32_t end) override
74     {
75         start_ = start;
76         end_ = end;
77         selectListenerCv_.notify_all();
78     }
79 
OnSelectByMovement(int32_t direction)80     void OnSelectByMovement(int32_t direction) override
81     {
82         direction_ = direction;
83         selectListenerCv_.notify_all();
84     }
85     static void WaitSelectListenerCallback();
86     static int32_t start_;
87     static int32_t end_;
88     static int32_t direction_;
89     static std::mutex selectListenerMutex_;
90     static std::condition_variable selectListenerCv_;
91 };
92 
93 int32_t SelectListenerMock::start_ = 0;
94 int32_t SelectListenerMock::end_ = 0;
95 int32_t SelectListenerMock::direction_ = 0;
96 std::mutex SelectListenerMock::selectListenerMutex_;
97 std::condition_variable SelectListenerMock::selectListenerCv_;
WaitSelectListenerCallback()98 void SelectListenerMock::WaitSelectListenerCallback()
99 {
100     std::unique_lock<std::mutex> lock(selectListenerMutex_);
101     selectListenerCv_.wait_for(lock, std::chrono::milliseconds(WAIT_INTERVAL));
102 }
103 
104 class InputMethodControllerTest : public testing::Test {
105 public:
106     static void SetUpTestCase(void);
107     static void TearDownTestCase(void);
108     void SetUp();
109     void TearDown();
110     static void SetInputDeathRecipient();
111     static void OnRemoteSaDied(const wptr<IRemoteObject> &remote);
112     static void CheckKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent);
113     static bool WaitRemoteDiedCallback();
114     static void WaitKeyboardStatusCallback(bool keyboardState);
115     static void TriggerConfigurationChangeCallback(Configuration &info);
116     static void TriggerCursorUpdateCallback(CursorInfo &info);
117     static void TriggerSelectionChangeCallback(std::u16string &text, int start, int end);
118     static void CheckProxyObject();
119     static void DispatchKeyEventCallback(std::shared_ptr<MMI::KeyEvent> &keyEvent, bool isConsumed);
120     static bool WaitKeyEventCallback();
121     static void CheckTextConfig(const TextConfig &config);
122     static sptr<InputMethodController> inputMethodController_;
123     static sptr<InputMethodAbility> inputMethodAbility_;
124     static std::shared_ptr<MMI::KeyEvent> keyEvent_;
125     static std::shared_ptr<InputMethodEngineListenerImpl> imeListener_;
126     static std::shared_ptr<SelectListenerMock> controllerListener_;
127     static sptr<OnTextChangedListener> textListener_;
128     static std::mutex keyboardListenerMutex_;
129     static std::condition_variable keyboardListenerCv_;
130     static BlockData<std::shared_ptr<MMI::KeyEvent>> blockKeyEvent_;
131     static BlockData<std::shared_ptr<MMI::KeyEvent>> blockFullKeyEvent_;
132     static std::mutex onRemoteSaDiedMutex_;
133     static std::condition_variable onRemoteSaDiedCv_;
134     static sptr<InputDeathRecipient> deathRecipient_;
135     static CursorInfo cursorInfo_;
136     static int32_t oldBegin_;
137     static int32_t oldEnd_;
138     static int32_t newBegin_;
139     static int32_t newEnd_;
140     static std::string text_;
141     static bool doesKeyEventConsume_;
142     static bool doesFUllKeyEventConsume_;
143     static std::condition_variable keyEventCv_;
144     static std::mutex keyEventLock_;
145     static bool consumeResult_;
146     static InputAttribute inputAttribute_;
147     static std::shared_ptr<AppExecFwk::EventHandler> textConfigHandler_;
148     static constexpr uint32_t DELAY_TIME = 1;
149     static constexpr uint32_t KEY_EVENT_DELAY_TIME = 100;
150     static constexpr int32_t TASK_DELAY_TIME = 10;
151     static uint64_t defaultImeTokenId_;
152     static uint64_t permissionTokenId_;
153 
154     class KeyboardListenerImpl : public KeyboardListener {
155     public:
KeyboardListenerImpl()156         KeyboardListenerImpl()
157         {
158             std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create("InputMethodControllerTe"
159                                                                                               "st");
160             textConfigHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
161         };
~KeyboardListenerImpl()162         ~KeyboardListenerImpl(){};
OnKeyEvent(int32_t keyCode,int32_t keyStatus,sptr<KeyEventConsumerProxy> & consumer)163         bool OnKeyEvent(int32_t keyCode, int32_t keyStatus, sptr<KeyEventConsumerProxy> &consumer) override
164         {
165             if (!doesKeyEventConsume_) {
166                 return false;
167             }
168             IMSA_HILOGI("KeyboardListenerImpl::OnKeyEvent %{public}d %{public}d", keyCode, keyStatus);
169             auto keyEvent = KeyEventUtil::CreateKeyEvent(keyCode, keyStatus);
170             blockKeyEvent_.SetValue(keyEvent);
171             return true;
172         }
OnKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent,sptr<KeyEventConsumerProxy> & consumer)173         bool OnKeyEvent(const std::shared_ptr<MMI::KeyEvent> &keyEvent, sptr<KeyEventConsumerProxy> &consumer) override
174         {
175             if (!doesFUllKeyEventConsume_) {
176                 return false;
177             }
178             IMSA_HILOGI("KeyboardListenerImpl::OnKeyEvent %{public}d %{public}d", keyEvent->GetKeyCode(),
179                 keyEvent->GetKeyAction());
180             auto fullKey = keyEvent;
181             blockFullKeyEvent_.SetValue(fullKey);
182             return true;
183         }
OnDealKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent,sptr<KeyEventConsumerProxy> & consumer)184         bool OnDealKeyEvent(
185             const std::shared_ptr<MMI::KeyEvent> &keyEvent, sptr<KeyEventConsumerProxy> &consumer) override
186         {
187             bool isKeyCodeConsume = OnKeyEvent(keyEvent->GetKeyCode(), keyEvent->GetKeyAction(), consumer);
188             bool isKeyEventConsume = OnKeyEvent(keyEvent, consumer);
189             if (consumer != nullptr) {
190                 consumer->OnKeyEventResult(isKeyEventConsume | isKeyCodeConsume);
191             }
192             return true;
193         }
OnCursorUpdate(int32_t positionX,int32_t positionY,int32_t height)194         void OnCursorUpdate(int32_t positionX, int32_t positionY, int32_t height) override
195         {
196             IMSA_HILOGD(
197                 "KeyboardListenerImpl::OnCursorUpdate %{public}d %{public}d %{public}d", positionX, positionY, height);
198             cursorInfo_ = { static_cast<double>(positionX), static_cast<double>(positionY), 0,
199                 static_cast<double>(height) };
200             InputMethodControllerTest::keyboardListenerCv_.notify_one();
201         }
OnSelectionChange(int32_t oldBegin,int32_t oldEnd,int32_t newBegin,int32_t newEnd)202         void OnSelectionChange(int32_t oldBegin, int32_t oldEnd, int32_t newBegin, int32_t newEnd) override
203         {
204             IMSA_HILOGD("KeyboardListenerImpl::OnSelectionChange %{public}d %{public}d %{public}d %{public}d",
205                 oldBegin, oldEnd, newBegin, newBegin);
206             oldBegin_ = oldBegin;
207             oldEnd_ = oldEnd;
208             newBegin_ = newBegin;
209             newEnd_ = newEnd;
210             InputMethodControllerTest::keyboardListenerCv_.notify_one();
211         }
OnTextChange(const std::string & text)212         void OnTextChange(const std::string &text) override
213         {
214             IMSA_HILOGD("KeyboardListenerImpl::OnTextChange text: %{public}s", text.c_str());
215             text_ = text;
216             InputMethodControllerTest::keyboardListenerCv_.notify_one();
217         }
OnEditorAttributeChange(const InputAttribute & inputAttribute)218         void OnEditorAttributeChange(const InputAttribute &inputAttribute) override
219         {
220             IMSA_HILOGD("KeyboardListenerImpl in.");
221             inputAttribute_ = inputAttribute;
222             InputMethodControllerTest::keyboardListenerCv_.notify_one();
223         }
224     };
225 };
226 sptr<InputMethodController> InputMethodControllerTest::inputMethodController_;
227 sptr<InputMethodAbility> InputMethodControllerTest::inputMethodAbility_;
228 std::shared_ptr<MMI::KeyEvent> InputMethodControllerTest::keyEvent_;
229 std::shared_ptr<InputMethodEngineListenerImpl> InputMethodControllerTest::imeListener_;
230 std::shared_ptr<SelectListenerMock> InputMethodControllerTest::controllerListener_;
231 sptr<OnTextChangedListener> InputMethodControllerTest::textListener_;
232 CursorInfo InputMethodControllerTest::cursorInfo_ = {};
233 int32_t InputMethodControllerTest::oldBegin_ = 0;
234 int32_t InputMethodControllerTest::oldEnd_ = 0;
235 int32_t InputMethodControllerTest::newBegin_ = 0;
236 int32_t InputMethodControllerTest::newEnd_ = 0;
237 std::string InputMethodControllerTest::text_;
238 InputAttribute InputMethodControllerTest::inputAttribute_;
239 std::mutex InputMethodControllerTest::keyboardListenerMutex_;
240 std::condition_variable InputMethodControllerTest::keyboardListenerCv_;
241 sptr<InputDeathRecipient> InputMethodControllerTest::deathRecipient_;
242 std::mutex InputMethodControllerTest::onRemoteSaDiedMutex_;
243 std::condition_variable InputMethodControllerTest::onRemoteSaDiedCv_;
244 BlockData<std::shared_ptr<MMI::KeyEvent>> InputMethodControllerTest::blockKeyEvent_{
245     InputMethodControllerTest::KEY_EVENT_DELAY_TIME, nullptr
246 };
247 BlockData<std::shared_ptr<MMI::KeyEvent>> InputMethodControllerTest::blockFullKeyEvent_{
248     InputMethodControllerTest::KEY_EVENT_DELAY_TIME, nullptr
249 };
250 bool InputMethodControllerTest::doesKeyEventConsume_{ false };
251 bool InputMethodControllerTest::doesFUllKeyEventConsume_{ false };
252 std::condition_variable InputMethodControllerTest::keyEventCv_;
253 std::mutex InputMethodControllerTest::keyEventLock_;
254 bool InputMethodControllerTest::consumeResult_{ false };
255 std::shared_ptr<AppExecFwk::EventHandler> InputMethodControllerTest::textConfigHandler_{ nullptr };
256 uint64_t InputMethodControllerTest::defaultImeTokenId_ = 0;
257 uint64_t InputMethodControllerTest::permissionTokenId_ = 0;
258 
SetUpTestCase(void)259 void InputMethodControllerTest::SetUpTestCase(void)
260 {
261     IMSA_HILOGI("InputMethodControllerTest::SetUpTestCase");
262     TddUtil::StorageSelfTokenID();
263     // Set the tokenID to the tokenID of the current ime
264     std::shared_ptr<Property> property = InputMethodController::GetInstance()->GetCurrentInputMethod();
265     std::string bundleName = property != nullptr ? property->name : "default.inputmethod.unittest";
266     {
267         TokenScope tokenScope(TddUtil::GetTestTokenID(bundleName));
268         inputMethodAbility_ = InputMethodAbility::GetInstance();
269         inputMethodAbility_->SetCoreAndAgent();
270     }
271     imeListener_ = std::make_shared<InputMethodEngineListenerImpl>();
272     controllerListener_ = std::make_shared<SelectListenerMock>();
273     textListener_ = new TextListener();
274     inputMethodAbility_->SetKdListener(std::make_shared<KeyboardListenerImpl>());
275     inputMethodAbility_->SetImeListener(imeListener_);
276     inputMethodController_ = InputMethodController::GetInstance();
277 
278     keyEvent_ = KeyEventUtil::CreateKeyEvent(MMI::KeyEvent::KEYCODE_A, MMI::KeyEvent::KEY_ACTION_DOWN);
279     keyEvent_->SetFunctionKey(MMI::KeyEvent::NUM_LOCK_FUNCTION_KEY, 0);
280     keyEvent_->SetFunctionKey(MMI::KeyEvent::CAPS_LOCK_FUNCTION_KEY, 1);
281     keyEvent_->SetFunctionKey(MMI::KeyEvent::SCROLL_LOCK_FUNCTION_KEY, 1);
282 
283     TddUtil::InitWindow(true);
284     SetInputDeathRecipient();
285     TextListener::ResetParam();
286 
287     auto ret = InputMethodController::GetInstance()->GetDefaultInputMethod(property);
288     auto defaultIme = ret == ErrorCode::NO_ERROR ? property->name : "default.inputmethod.unittest";
289     defaultImeTokenId_ = TddUtil::GetTestTokenID(defaultIme);
290     permissionTokenId_ = TddUtil::AllocTestTokenID(false, "undefine", { "ohos.permission.CONNECT_IME_ABILITY" });
291 }
292 
TearDownTestCase(void)293 void InputMethodControllerTest::TearDownTestCase(void)
294 {
295     IMSA_HILOGI("InputMethodControllerTest::TearDownTestCase");
296     TextListener::ResetParam();
297     TddUtil::DestroyWindow();
298     inputMethodController_->SetControllerListener(nullptr);
299     TddUtil::RestoreSelfTokenID();
300 }
301 
SetUp(void)302 void InputMethodControllerTest::SetUp(void)
303 {
304     IMSA_HILOGI("InputMethodControllerTest::SetUp");
305 }
306 
TearDown(void)307 void InputMethodControllerTest::TearDown(void)
308 {
309     IMSA_HILOGI("InputMethodControllerTest::TearDown");
310 }
311 
SetInputDeathRecipient()312 void InputMethodControllerTest::SetInputDeathRecipient()
313 {
314     IMSA_HILOGI("InputMethodControllerTest::SetInputDeathRecipient");
315     sptr<ISystemAbilityManager> systemAbilityManager =
316         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
317     if (systemAbilityManager == nullptr) {
318         IMSA_HILOGI("InputMethodControllerTest, system ability manager is nullptr");
319         return;
320     }
321     auto systemAbility = systemAbilityManager->GetSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID, "");
322     if (systemAbility == nullptr) {
323         IMSA_HILOGI("InputMethodControllerTest, system ability is nullptr");
324         return;
325     }
326     deathRecipient_ = new (std::nothrow) InputDeathRecipient();
327     if (deathRecipient_ == nullptr) {
328         IMSA_HILOGE("InputMethodControllerTest, new death recipient failed");
329         return;
330     }
331     deathRecipient_->SetDeathRecipient([](const wptr<IRemoteObject> &remote) { OnRemoteSaDied(remote); });
332     if ((systemAbility->IsProxyObject()) && (!systemAbility->AddDeathRecipient(deathRecipient_))) {
333         IMSA_HILOGE("InputMethodControllerTest, failed to add death recipient.");
334         return;
335     }
336 }
337 
OnRemoteSaDied(const wptr<IRemoteObject> & remote)338 void InputMethodControllerTest::OnRemoteSaDied(const wptr<IRemoteObject> &remote)
339 {
340     IMSA_HILOGI("InputMethodControllerTest::OnRemoteSaDied");
341     onRemoteSaDiedCv_.notify_one();
342 }
343 
WaitRemoteDiedCallback()344 bool InputMethodControllerTest::WaitRemoteDiedCallback()
345 {
346     IMSA_HILOGI("InputMethodControllerTest::WaitRemoteDiedCallback");
347     std::unique_lock<std::mutex> lock(onRemoteSaDiedMutex_);
348     return onRemoteSaDiedCv_.wait_for(lock, std::chrono::seconds(WAIT_SA_DIE_TIME_OUT)) != std::cv_status::timeout;
349 }
350 
CheckProxyObject()351 void InputMethodControllerTest::CheckProxyObject()
352 {
353     for (uint32_t retryTimes = 0; retryTimes < RETRY_TIMES; ++retryTimes) {
354         IMSA_HILOGI("times = %{public}d", retryTimes);
355         sptr<ISystemAbilityManager> systemAbilityManager =
356             SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
357         if (systemAbilityManager == nullptr) {
358             IMSA_HILOGI("system ability manager is nullptr");
359             continue;
360         }
361         auto systemAbility = systemAbilityManager->CheckSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID);
362         if (systemAbility != nullptr) {
363             IMSA_HILOGI("CheckProxyObject success!");
364             break;
365         }
366         usleep(RETRY_TIME);
367     }
368 }
369 
CheckKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)370 void InputMethodControllerTest::CheckKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)
371 {
372     ASSERT_NE(keyEvent, nullptr);
373     bool ret = keyEvent->GetKeyCode() == keyEvent_->GetKeyCode();
374     EXPECT_TRUE(ret);
375     ret = keyEvent->GetKeyAction() == keyEvent_->GetKeyAction();
376     EXPECT_TRUE(ret);
377     ret = keyEvent->GetKeyIntention() == keyEvent_->GetKeyIntention();
378     EXPECT_TRUE(ret);
379     // check function key state
380     ret = keyEvent->GetFunctionKey(MMI::KeyEvent::NUM_LOCK_FUNCTION_KEY)
381           == keyEvent_->GetFunctionKey(MMI::KeyEvent::NUM_LOCK_FUNCTION_KEY);
382     EXPECT_TRUE(ret);
383     ret = keyEvent->GetFunctionKey(MMI::KeyEvent::CAPS_LOCK_FUNCTION_KEY)
384           == keyEvent_->GetFunctionKey(MMI::KeyEvent::CAPS_LOCK_FUNCTION_KEY);
385     EXPECT_TRUE(ret);
386     ret = keyEvent->GetFunctionKey(MMI::KeyEvent::SCROLL_LOCK_FUNCTION_KEY)
387           == keyEvent_->GetFunctionKey(MMI::KeyEvent::SCROLL_LOCK_FUNCTION_KEY);
388     EXPECT_TRUE(ret);
389     // check KeyItem
390     ret = keyEvent->GetKeyItems().size() == keyEvent_->GetKeyItems().size();
391     EXPECT_TRUE(ret);
392     ret = keyEvent->GetKeyItem()->GetKeyCode() == keyEvent_->GetKeyItem()->GetKeyCode();
393     EXPECT_TRUE(ret);
394     ret = keyEvent->GetKeyItem()->GetDownTime() == keyEvent_->GetKeyItem()->GetDownTime();
395     EXPECT_TRUE(ret);
396     ret = keyEvent->GetKeyItem()->GetDeviceId() == keyEvent_->GetKeyItem()->GetDeviceId();
397     EXPECT_TRUE(ret);
398     ret = keyEvent->GetKeyItem()->IsPressed() == keyEvent_->GetKeyItem()->IsPressed();
399     EXPECT_TRUE(ret);
400     ret = keyEvent->GetKeyItem()->GetUnicode() == keyEvent_->GetKeyItem()->GetUnicode();
401     EXPECT_TRUE(ret);
402 }
403 
WaitKeyboardStatusCallback(bool keyboardState)404 void InputMethodControllerTest::WaitKeyboardStatusCallback(bool keyboardState)
405 {
406     std::unique_lock<std::mutex> lock(InputMethodEngineListenerImpl::imeListenerMutex_);
407     InputMethodEngineListenerImpl::imeListenerCv_.wait_for(lock,
408         std::chrono::seconds(InputMethodControllerTest::DELAY_TIME),
409         [keyboardState] { return InputMethodEngineListenerImpl::keyboardState_ == keyboardState; });
410 }
411 
TriggerConfigurationChangeCallback(Configuration & info)412 void InputMethodControllerTest::TriggerConfigurationChangeCallback(Configuration &info)
413 {
414     textConfigHandler_->PostTask(
415         [info]() { inputMethodController_->OnConfigurationChange(info); }, InputMethodControllerTest::TASK_DELAY_TIME);
416     {
417         std::unique_lock<std::mutex> lock(InputMethodControllerTest::keyboardListenerMutex_);
418         InputMethodControllerTest::keyboardListenerCv_.wait_for(
419             lock, std::chrono::seconds(InputMethodControllerTest::DELAY_TIME), [&info] {
420                 return (static_cast<OHOS::MiscServices::TextInputType>(
421                             InputMethodControllerTest::inputAttribute_.inputPattern)
422                            == info.GetTextInputType())
423                        && (static_cast<OHOS::MiscServices::EnterKeyType>(
424                                InputMethodControllerTest::inputAttribute_.enterKeyType)
425                            == info.GetEnterKeyType());
426             });
427     }
428 }
429 
TriggerCursorUpdateCallback(CursorInfo & info)430 void InputMethodControllerTest::TriggerCursorUpdateCallback(CursorInfo &info)
431 {
432     textConfigHandler_->PostTask(
433         [info]() { inputMethodController_->OnCursorUpdate(info); }, InputMethodControllerTest::TASK_DELAY_TIME);
434     {
435         std::unique_lock<std::mutex> lock(InputMethodControllerTest::keyboardListenerMutex_);
436         InputMethodControllerTest::keyboardListenerCv_.wait_for(lock,
437             std::chrono::seconds(InputMethodControllerTest::DELAY_TIME),
438             [&info] { return InputMethodControllerTest::cursorInfo_ == info; });
439     }
440 }
441 
TriggerSelectionChangeCallback(std::u16string & text,int start,int end)442 void InputMethodControllerTest::TriggerSelectionChangeCallback(std::u16string &text, int start, int end)
443 {
444     textConfigHandler_->PostTask([text, start, end]() { inputMethodController_->OnSelectionChange(text, start, end); },
445         InputMethodControllerTest::TASK_DELAY_TIME);
446     {
447         std::unique_lock<std::mutex> lock(InputMethodControllerTest::keyboardListenerMutex_);
448         InputMethodControllerTest::keyboardListenerCv_.wait_for(lock,
449             std::chrono::seconds(InputMethodControllerTest::DELAY_TIME),
450             [&text] { return InputMethodControllerTest::text_ == Str16ToStr8(text); });
451     }
452 }
453 
CheckTextConfig(const TextConfig & config)454 void InputMethodControllerTest::CheckTextConfig(const TextConfig &config)
455 {
456     EXPECT_EQ(imeListener_->windowId_, config.windowId);
457     EXPECT_EQ(cursorInfo_.left, config.cursorInfo.left);
458     EXPECT_EQ(cursorInfo_.top, config.cursorInfo.top);
459     EXPECT_EQ(cursorInfo_.height, config.cursorInfo.height);
460     EXPECT_EQ(newBegin_, config.range.start);
461     EXPECT_EQ(newEnd_, config.range.end);
462     EXPECT_EQ(inputAttribute_.inputPattern, config.inputAttribute.inputPattern);
463     EXPECT_EQ(inputAttribute_.enterKeyType, config.inputAttribute.enterKeyType);
464 }
465 
DispatchKeyEventCallback(std::shared_ptr<MMI::KeyEvent> & keyEvent,bool isConsumed)466 void InputMethodControllerTest::DispatchKeyEventCallback(std::shared_ptr<MMI::KeyEvent> &keyEvent, bool isConsumed)
467 {
468     consumeResult_ = isConsumed;
469     keyEventCv_.notify_one();
470 }
471 
WaitKeyEventCallback()472 bool InputMethodControllerTest::WaitKeyEventCallback()
473 {
474     std::unique_lock<std::mutex> lock(keyEventLock_);
475     keyEventCv_.wait_for(lock, std::chrono::seconds(DELAY_TIME), [] { return consumeResult_; });
476     return consumeResult_;
477 }
478 
479 /**
480  * @tc.name: testIMCAttach001
481  * @tc.desc: IMC Attach.
482  * @tc.type: FUNC
483  * @tc.require:
484  */
485 HWTEST_F(InputMethodControllerTest, testIMCAttach001, TestSize.Level0)
486 {
487     IMSA_HILOGD("IMC testIMCAttach001 Test START");
488     imeListener_->isInputStart_ = false;
489     TextListener::ResetParam();
490     inputMethodController_->Attach(textListener_, false);
491     inputMethodController_->Attach(textListener_);
492     inputMethodController_->Attach(textListener_, true);
493     EXPECT_TRUE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::SHOW));
494     EXPECT_TRUE(imeListener_->isInputStart_ && imeListener_->keyboardState_);
495 }
496 
497 /**
498  * @tc.name: testIMCAttach002
499  * @tc.desc: IMC Attach.
500  * @tc.type: FUNC
501  * @tc.require:
502  */
503 HWTEST_F(InputMethodControllerTest, testIMCAttach002, TestSize.Level0)
504 {
505     IMSA_HILOGD("IMC testIMCAttach002 Test START");
506     TextListener::ResetParam();
507     CursorInfo cursorInfo = { 1, 1, 1, 1 };
508     Range selectionRange = { 1, 2 };
509     InputAttribute attribute = { 1, 1 };
510     uint32_t windowId = 10;
511     TextConfig textConfig = {
512         .inputAttribute = attribute, .cursorInfo = cursorInfo, .range = selectionRange, .windowId = windowId
513     };
514 
515     inputMethodController_->Attach(textListener_, true, textConfig);
516     InputMethodControllerTest::CheckTextConfig(textConfig);
517 
518     TextListener::ResetParam();
519     cursorInfo = { 2, 2, 2, 2 };
520     selectionRange = { 3, 4 };
521     attribute = { 2, 2 };
522     windowId = 11;
523     textConfig = {
524         .inputAttribute = attribute, .cursorInfo = cursorInfo, .range = selectionRange, .windowId = windowId
525     };
526     inputMethodController_->Attach(textListener_, true, textConfig);
527     InputMethodControllerTest::CheckTextConfig(textConfig);
528 }
529 
530 /**
531  * @tc.name: testIMCSetCallingWindow
532  * @tc.desc: IMC SetCallingWindow.
533  * @tc.type: FUNC
534  * @tc.require:
535  */
536 HWTEST_F(InputMethodControllerTest, testIMCSetCallingWindow, TestSize.Level0)
537 {
538     IMSA_HILOGD("IMC SetCallingWindow Test START");
539     auto ret = inputMethodController_->Attach(textListener_);
540     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
541     uint32_t windowId = 3;
542     ret = inputMethodController_->SetCallingWindow(windowId);
543     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
544     EXPECT_EQ(windowId, imeListener_->windowId_);
545 }
546 
547 /**
548  * @tc.name: testGetIMSAProxy
549  * @tc.desc: Get Imsa Proxy.
550  * @tc.type: FUNC
551  */
552 HWTEST_F(InputMethodControllerTest, testGetIMSAProxy, TestSize.Level0)
553 {
554     auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
555     ASSERT_NE(systemAbilityManager, nullptr);
556     auto systemAbility = systemAbilityManager->GetSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID, "");
557     EXPECT_TRUE(systemAbility != nullptr);
558 }
559 
560 /**
561  * @tc.name: testWriteReadIInputDataChannel
562  * @tc.desc: Checkout IInputDataChannel.
563  * @tc.type: FUNC
564  */
565 HWTEST_F(InputMethodControllerTest, testWriteReadIInputDataChannel, TestSize.Level0)
566 {
567     sptr<InputDataChannelStub> mInputDataChannel = new InputDataChannelStub();
568     MessageParcel data;
569     auto ret = data.WriteRemoteObject(mInputDataChannel->AsObject());
570     EXPECT_TRUE(ret);
571     auto remoteObject = data.ReadRemoteObject();
572     sptr<IInputDataChannel> iface = iface_cast<IInputDataChannel>(remoteObject);
573     EXPECT_TRUE(iface != nullptr);
574 }
575 
576 /**
577  * @tc.name: testIMCBindToIMSA
578  * @tc.desc: Bind IMSA.
579  * @tc.type: FUNC
580  */
581 HWTEST_F(InputMethodControllerTest, testIMCBindToIMSA, TestSize.Level0)
582 {
583     sptr<InputClientStub> mClient = new InputClientStub();
584     MessageParcel data;
585     auto ret = data.WriteRemoteObject(mClient->AsObject());
586     EXPECT_TRUE(ret);
587     auto remoteObject = data.ReadRemoteObject();
588     sptr<IInputClient> iface = iface_cast<IInputClient>(remoteObject);
589     EXPECT_TRUE(iface != nullptr);
590 }
591 
592 /**
593  * @tc.name: testIMCDispatchKeyEvent001
594  * @tc.desc: test IMC DispatchKeyEvent with 'keyDown/KeyUP'.
595  * @tc.type: FUNC
596  * @tc.require:
597  */
598 HWTEST_F(InputMethodControllerTest, testIMCDispatchKeyEvent001, TestSize.Level0)
599 {
600     IMSA_HILOGI("IMC testIMCDispatchKeyEvent001 Test START");
601     doesKeyEventConsume_ = true;
602     doesFUllKeyEventConsume_ = false;
603     blockKeyEvent_.Clear(nullptr);
604     auto res = inputMethodController_->Attach(textListener_);
605     EXPECT_EQ(res, ErrorCode::NO_ERROR);
606 
607     bool ret = inputMethodController_->DispatchKeyEvent(keyEvent_, DispatchKeyEventCallback);
608     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
609 
610     EXPECT_TRUE(WaitKeyEventCallback());
611 
612     auto keyEvent = blockKeyEvent_.GetValue();
613     ASSERT_NE(keyEvent, nullptr);
614     EXPECT_EQ(keyEvent->GetKeyCode(), keyEvent_->GetKeyCode());
615     EXPECT_EQ(keyEvent->GetKeyAction(), keyEvent_->GetKeyAction());
616 
617     doesKeyEventConsume_ = false;
618     ret = inputMethodController_->DispatchKeyEvent(keyEvent_, DispatchKeyEventCallback);
619     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
620 
621     EXPECT_TRUE(!WaitKeyEventCallback());
622 }
623 
624 /**
625  * @tc.name: testIMCDispatchKeyEvent002
626  * @tc.desc: test IMC DispatchKeyEvent with 'keyEvent'.
627  * @tc.type: FUNC
628  * @tc.require:
629  */
630 HWTEST_F(InputMethodControllerTest, testIMCDispatchKeyEvent002, TestSize.Level0)
631 {
632     IMSA_HILOGI("IMC testIMCDispatchKeyEvent002 Test START");
633     doesKeyEventConsume_ = false;
634     doesFUllKeyEventConsume_ = true;
635     blockFullKeyEvent_.Clear(nullptr);
636     int32_t ret = inputMethodController_->DispatchKeyEvent(
__anon6e7e40f40a02(std::shared_ptr<MMI::KeyEvent> &keyEvent, bool isConsumed) 637         keyEvent_, [](std::shared_ptr<MMI::KeyEvent> &keyEvent, bool isConsumed) {});
638     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
639     auto keyEvent = blockFullKeyEvent_.GetValue();
640     ASSERT_NE(keyEvent, nullptr);
641     CheckKeyEvent(keyEvent);
642 }
643 
644 /**
645  * @tc.name: testIMCDispatchKeyEvent003
646  * @tc.desc: test IMC DispatchKeyEvent with 'keyDown/KeyUP' and 'keyEvent'.
647  * @tc.type: FUNC
648  * @tc.require:
649  */
650 HWTEST_F(InputMethodControllerTest, testIMCDispatchKeyEvent003, TestSize.Level0)
651 {
652     IMSA_HILOGI("IMC testIMCDispatchKeyEvent003 Test START");
653     doesKeyEventConsume_ = true;
654     doesFUllKeyEventConsume_ = true;
655     blockKeyEvent_.Clear(nullptr);
656     blockFullKeyEvent_.Clear(nullptr);
657     int32_t ret = inputMethodController_->DispatchKeyEvent(
__anon6e7e40f40b02(std::shared_ptr<MMI::KeyEvent> &keyEvent, bool isConsumed) 658         keyEvent_, [](std::shared_ptr<MMI::KeyEvent> &keyEvent, bool isConsumed) {});
659     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
660     auto keyEvent = blockKeyEvent_.GetValue();
661     auto keyFullEvent = blockFullKeyEvent_.GetValue();
662     ASSERT_NE(keyEvent, nullptr);
663     EXPECT_EQ(keyEvent->GetKeyCode(), keyEvent_->GetKeyCode());
664     EXPECT_EQ(keyEvent->GetKeyAction(), keyEvent_->GetKeyAction());
665     ASSERT_NE(keyFullEvent, nullptr);
666     CheckKeyEvent(keyFullEvent);
667 }
668 
669 /**
670  * @tc.name: testIMCOnCursorUpdate01
671  * @tc.desc: Test update cursorInfo, call 'OnCursorUpdate' twice, if cursorInfo is the same,
672  *           the second time will not get callback.
673  * @tc.type: FUNC
674  * @tc.require:
675  * @tc.author: Zhaolinglan
676  */
677 HWTEST_F(InputMethodControllerTest, testIMCOnCursorUpdate01, TestSize.Level0)
678 {
679     IMSA_HILOGI("IMC testIMCOnCursorUpdate01 Test START");
680     auto ret = inputMethodController_->Attach(textListener_, false);
681     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
682     CursorInfo info = { 1, 3, 0, 5 };
683     InputMethodControllerTest::TriggerCursorUpdateCallback(info);
684     EXPECT_EQ(InputMethodControllerTest::cursorInfo_, info);
685 
686     InputMethodControllerTest::cursorInfo_ = {};
687     InputMethodControllerTest::TriggerCursorUpdateCallback(info);
688     EXPECT_FALSE(InputMethodControllerTest::cursorInfo_ == info);
689 }
690 
691 /**
692  * @tc.name: testIMCOnCursorUpdate02
693  * @tc.desc: Test update cursorInfo, 'Attach'->'OnCursorUpdate'->'Close'->'Attach'->'OnCursorUpdate',
694  *           it will get callback two time.
695  * @tc.type: FUNC
696  * @tc.require:
697  * @tc.author: Zhaolinglan
698  */
699 HWTEST_F(InputMethodControllerTest, testIMCOnCursorUpdate02, TestSize.Level0)
700 {
701     IMSA_HILOGI("IMC testIMCOnCursorUpdate02 Test START");
702     auto ret = inputMethodController_->Attach(textListener_, false);
703     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
704     CursorInfo info = { 2, 4, 0, 6 };
705     InputMethodControllerTest::TriggerCursorUpdateCallback(info);
706     EXPECT_EQ(InputMethodControllerTest::cursorInfo_, info);
707 
708     InputMethodControllerTest::cursorInfo_ = {};
709     ret = InputMethodControllerTest::inputMethodController_->Close();
710     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
711     ret = inputMethodController_->Attach(textListener_, false);
712     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
713     InputMethodControllerTest::TriggerCursorUpdateCallback(info);
714     EXPECT_EQ(InputMethodControllerTest::cursorInfo_, info);
715 }
716 
717 /**
718  * @tc.name: testIMCOnSelectionChange01
719  * @tc.desc: Test change selection, call 'OnSelectionChange' twice, if selection is the same,
720  *           the second time will not get callback.
721  * @tc.type: FUNC
722  * @tc.require:
723  * @tc.author: Zhaolinglan
724  */
725 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange01, TestSize.Level0)
726 {
727     IMSA_HILOGI("IMC testIMCOnSelectionChange01 Test START");
728     auto ret = inputMethodController_->Attach(textListener_, false);
729     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
730     std::u16string text = Str8ToStr16("testSelect");
731     int start = 1;
732     int end = 2;
733     InputMethodControllerTest::TriggerSelectionChangeCallback(text, start, end);
734     EXPECT_EQ(InputMethodControllerTest::text_, Str16ToStr8(text));
735 
736     InputMethodControllerTest::text_ = "";
737     InputMethodControllerTest::TriggerSelectionChangeCallback(text, start, end);
738     EXPECT_NE(InputMethodControllerTest::text_, Str16ToStr8(text));
739 }
740 
741 /**
742  * @tc.name: testIMCOnSelectionChange02
743  * @tc.desc: Test change selection, 'Attach'->'OnSelectionChange'->'Close'->'Attach'->'OnSelectionChange',
744  *           it will get callback two time.
745  * @tc.type: FUNC
746  * @tc.require:
747  * @tc.author: Zhaolinglan
748  */
749 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange02, TestSize.Level0)
750 {
751     IMSA_HILOGI("IMC testIMCOnSelectionChange02 Test START");
752     auto ret = inputMethodController_->Attach(textListener_, false);
753     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
754     std::u16string text = Str8ToStr16("testSelect2");
755     int start = 1;
756     int end = 2;
757     InputMethodControllerTest::TriggerSelectionChangeCallback(text, start, end);
758     EXPECT_EQ(InputMethodControllerTest::text_, Str16ToStr8(text));
759 
760     InputMethodControllerTest::text_ = "";
761     InputMethodControllerTest::inputMethodController_->Close();
762     inputMethodController_->Attach(textListener_, false);
763     InputMethodControllerTest::TriggerSelectionChangeCallback(text, start, end);
764     EXPECT_EQ(InputMethodControllerTest::text_, Str16ToStr8(text));
765 }
766 
767 /**
768  * @tc.name: testShowTextInput
769  * @tc.desc: IMC ShowTextInput
770  * @tc.type: FUNC
771  */
772 HWTEST_F(InputMethodControllerTest, testShowTextInput, TestSize.Level0)
773 {
774     IMSA_HILOGI("IMC ShowTextInput Test START");
775     TextListener::ResetParam();
776     inputMethodController_->ShowTextInput();
777     EXPECT_TRUE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::SHOW));
778 }
779 
780 /**
781  * @tc.name: testShowSoftKeyboard
782  * @tc.desc: IMC ShowSoftKeyboard
783  * @tc.type: FUNC
784  */
785 HWTEST_F(InputMethodControllerTest, testShowSoftKeyboard, TestSize.Level0)
786 {
787     IMSA_HILOGI("IMC ShowSoftKeyboard Test START");
788     TokenScope scope(InputMethodControllerTest::permissionTokenId_);
789     imeListener_->keyboardState_ = false;
790     TextListener::ResetParam();
791     int32_t ret = inputMethodController_->ShowSoftKeyboard();
792     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
793     EXPECT_TRUE(imeListener_->keyboardState_ && TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::SHOW));
794 }
795 
796 /**
797  * @tc.name: testShowCurrentInput
798  * @tc.desc: IMC ShowCurrentInput
799  * @tc.type: FUNC
800  */
801 HWTEST_F(InputMethodControllerTest, testShowCurrentInput, TestSize.Level0)
802 {
803     IMSA_HILOGI("IMC ShowCurrentInput Test START");
804     imeListener_->keyboardState_ = false;
805     TextListener::ResetParam();
806     int32_t ret = inputMethodController_->ShowCurrentInput();
807     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
808     EXPECT_TRUE(imeListener_->keyboardState_ && TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::SHOW));
809 }
810 
811 /**
812  * @tc.name: testIMCGetEnterKeyType
813  * @tc.desc: IMC testGetEnterKeyType.
814  * @tc.type: FUNC
815  * @tc.require:
816  */
817 HWTEST_F(InputMethodControllerTest, testIMCGetEnterKeyType, TestSize.Level0)
818 {
819     IMSA_HILOGI("IMC GetEnterKeyType Test START");
820     int32_t keyType;
821     inputMethodController_->GetEnterKeyType(keyType);
822     EXPECT_TRUE(keyType >= static_cast<int32_t>(EnterKeyType::UNSPECIFIED)
823                 && keyType <= static_cast<int32_t>(EnterKeyType::PREVIOUS));
824 }
825 
826 /**
827  * @tc.name: testIMCGetInputPattern
828  * @tc.desc: IMC testGetInputPattern.
829  * @tc.type: FUNC
830  * @tc.require:
831  */
832 HWTEST_F(InputMethodControllerTest, testIMCGetInputPattern, TestSize.Level0)
833 {
834     IMSA_HILOGI("IMC GetInputPattern Test START");
835     int32_t inputPattern;
836     inputMethodController_->GetInputPattern(inputPattern);
837     EXPECT_TRUE(inputPattern >= static_cast<int32_t>(TextInputType::NONE)
838                 && inputPattern <= static_cast<int32_t>(TextInputType::VISIBLE_PASSWORD));
839 }
840 
841 /**
842  * @tc.name: testOnEditorAttributeChanged
843  * @tc.desc: IMC testOnEditorAttributeChanged.
844  * @tc.type: FUNC
845  * @tc.require:
846  */
847 HWTEST_F(InputMethodControllerTest, testOnEditorAttributeChanged, TestSize.Level0)
848 {
849     IMSA_HILOGI("IMC testOnEditorAttributeChanged Test START");
850     auto ret = inputMethodController_->Attach(textListener_, false);
851     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
852     Configuration info;
853     info.SetEnterKeyType(EnterKeyType::GO);
854     info.SetTextInputType(TextInputType::NUMBER);
855     InputMethodControllerTest::TriggerConfigurationChangeCallback(info);
856     EXPECT_EQ(InputMethodControllerTest::inputAttribute_.inputPattern, static_cast<int32_t>(info.GetTextInputType()));
857     EXPECT_EQ(InputMethodControllerTest::inputAttribute_.enterKeyType, static_cast<int32_t>(info.GetEnterKeyType()));
858 }
859 
860 /**
861  * @tc.name: testHideSoftKeyboard
862  * @tc.desc: IMC HideSoftKeyboard
863  * @tc.type: FUNC
864  */
865 HWTEST_F(InputMethodControllerTest, testHideSoftKeyboard, TestSize.Level0)
866 {
867     IMSA_HILOGI("IMC HideSoftKeyboard Test START");
868     TokenScope scope(InputMethodControllerTest::permissionTokenId_);
869     imeListener_->keyboardState_ = true;
870     TextListener::ResetParam();
871     int32_t ret = inputMethodController_->HideSoftKeyboard();
872     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
873     EXPECT_TRUE(!imeListener_->keyboardState_ && TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::HIDE));
874 }
875 
876 /**
877  * @tc.name: testIMCHideCurrentInput
878  * @tc.desc: IMC HideCurrentInput.
879  * @tc.type: FUNC
880  * @tc.require:
881  */
882 HWTEST_F(InputMethodControllerTest, testIMCHideCurrentInput, TestSize.Level0)
883 {
884     IMSA_HILOGI("IMC HideCurrentInput Test START");
885     imeListener_->keyboardState_ = true;
886     TextListener::ResetParam();
887     int32_t ret = inputMethodController_->HideCurrentInput();
888     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
889     EXPECT_TRUE(!imeListener_->keyboardState_ && TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::HIDE));
890 }
891 
892 /**
893  * @tc.name: testIMCInputStopSession
894  * @tc.desc: IMC testInputStopSession.
895  * @tc.type: FUNC
896  * @tc.require: issueI5U8FZ
897  * @tc.author: Hollokin
898  */
899 HWTEST_F(InputMethodControllerTest, testIMCInputStopSession, TestSize.Level0)
900 {
901     IMSA_HILOGI("IMC StopInputSession Test START");
902     imeListener_->keyboardState_ = true;
903     int32_t ret = inputMethodController_->StopInputSession();
904     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
905     WaitKeyboardStatusCallback(false);
906     EXPECT_TRUE(!imeListener_->keyboardState_);
907 }
908 
909 /**
910  * @tc.name: testIMCHideTextInput.
911  * @tc.desc: IMC testHideTextInput.
912  * @tc.type: FUNC
913  */
914 HWTEST_F(InputMethodControllerTest, testIMCHideTextInput, TestSize.Level0)
915 {
916     IMSA_HILOGI("IMC HideTextInput Test START");
917     imeListener_->keyboardState_ = true;
918     inputMethodController_->HideTextInput();
919     WaitKeyboardStatusCallback(false);
920     EXPECT_TRUE(!imeListener_->keyboardState_);
921 }
922 
923 /**
924  * @tc.name: testIMCRequestShowInput.
925  * @tc.desc: IMC testIMCRequestShowInput.
926  * @tc.type: FUNC
927  */
928 HWTEST_F(InputMethodControllerTest, testIMCRequestShowInput, TestSize.Level0)
929 {
930     IMSA_HILOGI("IMC testIMCRequestShowInput Test START");
931     imeListener_->keyboardState_ = false;
932     int32_t ret = InputMethodControllerTest::inputMethodController_->RequestShowInput();
933     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
934     EXPECT_TRUE(imeListener_->keyboardState_);
935 }
936 
937 /**
938  * @tc.name: testIMCRequestHideInput.
939  * @tc.desc: IMC testIMCRequestHideInput.
940  * @tc.type: FUNC
941  */
942 HWTEST_F(InputMethodControllerTest, testIMCRequestHideInput, TestSize.Level0)
943 {
944     IMSA_HILOGI("IMC testIMCRequestHideInput Test START");
945     imeListener_->keyboardState_ = true;
946     int32_t ret = InputMethodControllerTest::inputMethodController_->RequestHideInput();
947     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
948     EXPECT_FALSE(imeListener_->keyboardState_);
949 }
950 
951 /**
952  * @tc.name: testSetControllerListener
953  * @tc.desc: IMC SetControllerListener
954  * @tc.type: FUNC
955  */
956 HWTEST_F(InputMethodControllerTest, testSetControllerListener, TestSize.Level0)
957 {
958     IMSA_HILOGI("IMC SetControllerListener Test START");
959     inputMethodController_->SetControllerListener(controllerListener_);
960 
961     int32_t ret = inputMethodController_->Attach(textListener_, false);
962     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
963     SelectListenerMock::start_ = 0;
964     SelectListenerMock::end_ = 0;
965     inputMethodAbility_->SelectByRange(1, 2);
966     SelectListenerMock::WaitSelectListenerCallback();
967     EXPECT_EQ(SelectListenerMock::start_, 1);
968     EXPECT_EQ(SelectListenerMock::end_, 2);
969 
970     SelectListenerMock::direction_ = 0;
971     inputMethodAbility_->SelectByMovement(static_cast<int32_t>(Direction::UP));
972     SelectListenerMock::WaitSelectListenerCallback();
973     EXPECT_EQ(SelectListenerMock::direction_, static_cast<int32_t>(Direction::UP));
974 
975     SelectListenerMock::direction_ = 0;
976     inputMethodAbility_->SelectByMovement(static_cast<int32_t>(Direction::DOWN));
977     SelectListenerMock::WaitSelectListenerCallback();
978     EXPECT_EQ(SelectListenerMock::direction_, static_cast<int32_t>(Direction::DOWN));
979 
980     SelectListenerMock::direction_ = 0;
981     inputMethodAbility_->SelectByMovement(static_cast<int32_t>(Direction::LEFT));
982     SelectListenerMock::WaitSelectListenerCallback();
983     EXPECT_EQ(SelectListenerMock::direction_, static_cast<int32_t>(Direction::LEFT));
984 
985     SelectListenerMock::direction_ = 0;
986     inputMethodAbility_->SelectByMovement(static_cast<int32_t>(Direction::RIGHT));
987     SelectListenerMock::WaitSelectListenerCallback();
988     EXPECT_EQ(SelectListenerMock::direction_, static_cast<int32_t>(Direction::RIGHT));
989 }
990 
991 /**
992  * @tc.name: testWasAttached
993  * @tc.desc: IMC WasAttached
994  * @tc.type: FUNC
995  */
996 HWTEST_F(InputMethodControllerTest, testWasAttached, TestSize.Level0)
997 {
998     IMSA_HILOGI("IMC WasAttached Test START");
999     inputMethodController_->Close();
1000     bool result = inputMethodController_->WasAttached();
1001     EXPECT_FALSE(result);
1002     int32_t ret = inputMethodController_->Attach(textListener_, false);
1003     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1004     result = inputMethodController_->WasAttached();
1005     EXPECT_TRUE(result);
1006     inputMethodController_->Close();
1007 }
1008 
1009 /**
1010  * @tc.name: testGetDefaultInputMethod
1011  * @tc.desc: IMC GetDefaultInputMethod
1012  * @tc.type: FUNC
1013  */
1014 HWTEST_F(InputMethodControllerTest, testGetDefaultInputMethod, TestSize.Level0)
1015 {
1016     IMSA_HILOGI("IMC testGetDefaultInputMethod Test START");
1017     std::shared_ptr<Property> property;
1018     int32_t ret = inputMethodController_->GetDefaultInputMethod(property);
1019     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1020     EXPECT_FALSE(property->name.empty());
1021 }
1022 
1023 /**
1024  * @tc.name: testGetSystemInputMethodConfig
1025  * @tc.desc: IMC GetSystemInputMethodConfig
1026  * @tc.type: FUNC
1027  */
1028 HWTEST_F(InputMethodControllerTest, GetSystemInputMethodConfig, TestSize.Level0)
1029 {
1030     IMSA_HILOGI("IMC GetSystemInputMethodConfig Test START");
1031     OHOS::AppExecFwk::ElementName inputMethodConfig;
1032     int32_t ret = inputMethodController_->GetInputMethodConfig(inputMethodConfig);
1033     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1034     EXPECT_GE(inputMethodConfig.GetBundleName().length(), 0);
1035     EXPECT_GE(inputMethodConfig.GetAbilityName().length(), 0);
1036 }
1037 
1038 /**
1039  * @tc.name: testWithoutEditableState
1040  * @tc.desc: IMC testWithoutEditableState
1041  * @tc.type: FUNC
1042  * @tc.require:
1043  */
1044 HWTEST_F(InputMethodControllerTest, testWithoutEditableState, TestSize.Level0)
1045 {
1046     IMSA_HILOGI("IMC WithouteEditableState Test START");
1047     auto ret = inputMethodController_->Attach(textListener_, false);
1048     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1049     ret = inputMethodController_->HideTextInput();
1050     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1051 
1052     int32_t deleteForwardLength = 1;
1053     ret = inputMethodAbility_->DeleteForward(deleteForwardLength);
1054     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
1055     EXPECT_NE(TextListener::deleteForwardLength_, deleteForwardLength);
1056 
1057     int32_t deleteBackwardLength = 2;
1058     ret = inputMethodAbility_->DeleteBackward(deleteBackwardLength);
1059     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
1060     EXPECT_NE(TextListener::deleteBackwardLength_, deleteBackwardLength);
1061 
1062     std::string insertText = "t";
1063     ret = inputMethodAbility_->InsertText(insertText);
1064     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
1065     EXPECT_NE(TextListener::insertText_, Str8ToStr16(insertText));
1066 
1067     constexpr int32_t funcKey = 1;
1068     ret = inputMethodAbility_->SendFunctionKey(funcKey);
1069     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
1070     EXPECT_NE(TextListener::key_, funcKey);
1071 
1072     constexpr int32_t keyCode = 4;
1073     ret = inputMethodAbility_->MoveCursor(keyCode);
1074     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
1075     EXPECT_NE(TextListener::direction_, keyCode);
1076 }
1077 
1078 /**
1079  * @tc.name: testIsInputTypeSupported
1080  * @tc.desc: IsInputTypeSupported
1081  * @tc.type: FUNC
1082  * @tc.require:
1083  * @tc.author: chenyu
1084  */
1085 HWTEST_F(InputMethodControllerTest, testIsInputTypeSupported, TestSize.Level0)
1086 {
1087     IMSA_HILOGI("IMC testIsInputTypeSupported Test START");
1088     auto ret = inputMethodController_->IsInputTypeSupported(InputType::NONE);
1089     EXPECT_FALSE(ret);
1090 }
1091 
1092 /**
1093  * @tc.name: testStartInputType
1094  * @tc.desc: StartInputType
1095  * @tc.type: FUNC
1096  * @tc.require:
1097  * @tc.author: chenyu
1098  */
1099 HWTEST_F(InputMethodControllerTest, testStartInputType, TestSize.Level0)
1100 {
1101     IMSA_HILOGI("IMC testStartInputType Test START");
1102     auto ret = inputMethodController_->StartInputType(InputType::NONE);
1103     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1104 }
1105 
1106 /**
1107  * @tc.name: testSendPrivateCommand_001
1108  * @tc.desc: IMC SendPrivateCommand without default ime
1109  * @tc.type: FUNC
1110  * @tc.require:
1111  * @tc.author: mashaoyin
1112  */
1113 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_001, TestSize.Level0)
1114 {
1115     IMSA_HILOGI("IMC testSendPrivateCommand_001 Test START");
1116     InputMethodEngineListenerImpl::ResetParam();
1117     auto ret = inputMethodController_->Attach(textListener_, false);
1118     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1119     std::unordered_map<std::string, PrivateDataValue> privateCommand;
1120     PrivateDataValue privateDataValue1 = std::string("stringValue");
1121     privateCommand.emplace("value1", privateDataValue1);
1122     ret = inputMethodController_->SendPrivateCommand(privateCommand);
1123     EXPECT_EQ(ret, ErrorCode::ERROR_NOT_DEFAULT_IME);
1124     inputMethodController_->Close();
1125 }
1126 
1127 /**
1128  * @tc.name: testSendPrivateCommand_002
1129  * @tc.desc: SendPrivateCommand not bound, and empty privateCommand.
1130  * @tc.type: FUNC
1131  * @tc.require:
1132  * @tc.author: mashaoyin
1133  */
1134 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_002, TestSize.Level0)
1135 {
1136     IMSA_HILOGI("IMC testSendPrivateCommand_002 Test START");
1137     TokenScope scope(InputMethodControllerTest::defaultImeTokenId_);
1138     InputMethodEngineListenerImpl::ResetParam();
1139     inputMethodController_->Close();
1140     std::unordered_map<std::string, PrivateDataValue> privateCommand;
1141     auto ret = inputMethodController_->SendPrivateCommand(privateCommand);
1142     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_BOUND);
1143 
1144     ret = inputMethodController_->Attach(textListener_, false);
1145     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1146     ret = inputMethodController_->SendPrivateCommand(privateCommand);
1147     EXPECT_EQ(ret, ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE);
1148     inputMethodController_->Close();
1149 }
1150 
1151 /**
1152  * @tc.name: testSendPrivateCommand_003
1153  * @tc.desc: IMC SendPrivateCommand with normal private command.
1154  * @tc.type: FUNC
1155  * @tc.require:
1156  * @tc.author: mashaoyin
1157  */
1158 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_003, TestSize.Level0)
1159 {
1160     IMSA_HILOGI("IMC testSendPrivateCommand_003 Test START");
1161     TokenScope scope(InputMethodControllerTest::defaultImeTokenId_);
1162     InputMethodEngineListenerImpl::ResetParam();
1163     auto ret = inputMethodController_->Attach(textListener_, false);
1164     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1165     std::unordered_map<std::string, PrivateDataValue> privateCommand;
1166     PrivateDataValue privateDataValue1 = std::string("stringValue");
1167     privateCommand.emplace("value1", privateDataValue1);
1168     ret = inputMethodController_->SendPrivateCommand(privateCommand);
1169     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1170     inputMethodController_->Close();
1171 }
1172 
1173 /**
1174  * @tc.name: testSendPrivateCommand_004
1175  * @tc.desc: IMC SendPrivateCommand with correct data format and all data type.
1176  * @tc.type: FUNC
1177  * @tc.require:
1178  * @tc.author: mashaoyin
1179  */
1180 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_004, TestSize.Level0)
1181 {
1182     IMSA_HILOGI("IMC testSendPrivateCommand_004 Test START");
1183     TokenScope scope(InputMethodControllerTest::defaultImeTokenId_);
1184     InputMethodEngineListenerImpl::ResetParam();
1185     auto ret = inputMethodController_->Attach(textListener_, false);
1186     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1187     std::unordered_map<std::string, PrivateDataValue> privateCommand;
1188     PrivateDataValue privateDataValue1 = std::string("stringValue");
1189     PrivateDataValue privateDataValue2 = true;
1190     PrivateDataValue privateDataValue3 = 100;
1191     privateCommand.emplace("value1", privateDataValue1);
1192     privateCommand.emplace("value2", privateDataValue2);
1193     privateCommand.emplace("value3", privateDataValue3);
1194     ret = inputMethodController_->SendPrivateCommand(privateCommand);
1195     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1196     EXPECT_TRUE(InputMethodEngineListenerImpl::WaitSendPrivateCommand(privateCommand));
1197     inputMethodController_->Close();
1198 }
1199 
1200 /**
1201  * @tc.name: testSendPrivateCommand_005
1202  * @tc.desc: IMC SendPrivateCommand with more than 5 private command.
1203  * @tc.type: FUNC
1204  * @tc.require:
1205  * @tc.author: mashaoyin
1206  */
1207 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_005, TestSize.Level0)
1208 {
1209     IMSA_HILOGI("IMC testSendPrivateCommand_005 Test START");
1210     TokenScope scope(InputMethodControllerTest::defaultImeTokenId_);
1211     InputMethodEngineListenerImpl::ResetParam();
1212     auto ret = inputMethodController_->Attach(textListener_, false);
1213     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1214     std::unordered_map<std::string, PrivateDataValue> privateCommand;
1215     PrivateDataValue privateDataValue1 = std::string("stringValue");
1216     privateCommand.emplace("value1", privateDataValue1);
1217     privateCommand.emplace("value2", privateDataValue1);
1218     privateCommand.emplace("value3", privateDataValue1);
1219     privateCommand.emplace("value4", privateDataValue1);
1220     privateCommand.emplace("value5", privateDataValue1);
1221     privateCommand.emplace("value6", privateDataValue1);
1222     ret = inputMethodController_->SendPrivateCommand(privateCommand);
1223     EXPECT_EQ(ret, ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE);
1224     inputMethodController_->Close();
1225 }
1226 
1227 /**
1228  * @tc.name: testSendPrivateCommand_006
1229  * @tc.desc: IMC SendPrivateCommand size is more than 32KB.
1230  * @tc.type: FUNC
1231  * @tc.require:
1232  * @tc.author: mashaoyin
1233  */
1234 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_006, TestSize.Level0)
1235 {
1236     IMSA_HILOGI("IMC testSendPrivateCommand_006 Test START");
1237     TokenScope scope(InputMethodControllerTest::defaultImeTokenId_);
1238     InputMethodEngineListenerImpl::ResetParam();
1239     std::unordered_map<std::string, PrivateDataValue> privateCommand;
1240     PrivateDataValue privateDataValue1 = std::string("stringValue");
1241     PrivateDataValue privateDataValue2 = true;
1242     PrivateDataValue privateDataValue3 = 100;
1243     privateCommand.emplace("value1", privateDataValue1);
1244     privateCommand.emplace("value2", privateDataValue2);
1245     privateCommand.emplace("value3", privateDataValue3);
1246     TextConfig textConfig;
1247     textConfig.privateCommand = privateCommand;
1248     textConfig.windowId = 1;
1249     auto ret = inputMethodController_->Attach(textListener_, false, textConfig);
1250     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1251     EXPECT_TRUE(InputMethodEngineListenerImpl::WaitSendPrivateCommand(privateCommand));
1252     inputMethodController_->Close();
1253 }
1254 
1255 /**
1256  * @tc.name: testSendPrivateCommand_007
1257  * @tc.desc: IMC SendPrivateCommand with Attach.
1258  * @tc.type: FUNC
1259  * @tc.require:
1260  * @tc.author: mashaoyin
1261  */
1262 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_007, TestSize.Level0)
1263 {
1264     IMSA_HILOGI("IMC testSendPrivateCommand_007 Test START");
1265     TokenScope scope(InputMethodControllerTest::defaultImeTokenId_);
1266     TextListener::ResetParam();
1267     auto ret = inputMethodController_->Attach(textListener_, false);
1268     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1269     string str(32768, 'a');
1270     std::unordered_map<std::string, PrivateDataValue> privateCommand;
1271     PrivateDataValue privateDataValue1 = str;
1272     privateCommand.emplace("value1", privateDataValue1);
1273     ret = inputMethodController_->SendPrivateCommand(privateCommand);
1274     EXPECT_EQ(ret, ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE);
1275     inputMethodController_->Close();
1276 }
1277 
1278 /**
1279  * @tc.name: testSendPrivateCommand_008
1280  * @tc.desc: IMA SendPrivateCommand total size is 32KB, 32KB - 1, 32KB + 1.
1281  * @tc.type: IMC
1282  * @tc.require:
1283  * @tc.author: mashaoyin
1284  */
1285 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_008, TestSize.Level0)
1286 {
1287     IMSA_HILOGI("IMC testSendPrivateCommand_008 Test START");
1288     auto ret = inputMethodController_->Attach(textListener_, false);
1289     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1290     TokenScope scope(InputMethodControllerTest::defaultImeTokenId_);
1291     TextListener::ResetParam();
1292     std::unordered_map<std::string, PrivateDataValue> privateCommand1{ { "v",
1293         string(PRIVATE_COMMAND_SIZE_MAX - 2, 'a') } };
1294     std::unordered_map<std::string, PrivateDataValue> privateCommand2{ { "v",
1295         string(PRIVATE_COMMAND_SIZE_MAX - 1, 'a') } };
1296     std::unordered_map<std::string, PrivateDataValue> privateCommand3{ { "v",
1297         string(PRIVATE_COMMAND_SIZE_MAX, 'a') } };
1298     ret = inputMethodController_->SendPrivateCommand(privateCommand1);
1299     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1300     ret = inputMethodController_->SendPrivateCommand(privateCommand2);
1301     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1302     ret = inputMethodController_->SendPrivateCommand(privateCommand3);
1303     EXPECT_EQ(ret, ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE);
1304     TddUtil::RestoreSelfTokenID();
1305     inputMethodController_->Close();
1306 }
1307 
1308 /**
1309  * @tc.name: testOnRemoteDied
1310  * @tc.desc: IMC OnRemoteDied
1311  * @tc.type: FUNC
1312  */
1313 HWTEST_F(InputMethodControllerTest, testOnRemoteDied, TestSize.Level0)
1314 {
1315     IMSA_HILOGI("IMC OnRemoteDied Test START");
1316     int32_t ret = inputMethodController_->Attach(textListener_, true);
1317     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1318     TextListener::ResetParam();
1319     bool result = TddUtil::KillImsaProcess();
1320     EXPECT_TRUE(result);
1321     EXPECT_TRUE(WaitRemoteDiedCallback());
1322     CheckProxyObject();
1323     inputMethodController_->OnRemoteSaDied(nullptr);
1324     EXPECT_TRUE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::SHOW));
1325     result = inputMethodController_->WasAttached();
1326     EXPECT_TRUE(result);
1327     inputMethodController_->Close();
1328 }
1329 } // namespace MiscServices
1330 } // namespace OHOS