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