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