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