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
46 #include "enable_ime_data_parser.h"
47 #include "input_data_channel_stub.h"
48 #include "input_death_recipient.h"
49 #include "input_method_ability.h"
50 #include "input_method_engine_listener_impl.h"
51 #include "input_method_system_ability_proxy.h"
52 #include "input_method_utils.h"
53 #include "ime_info_inquirer.h"
54 #include "iservice_registry.h"
55 #include "key_event_util.h"
56 #include "keyboard_listener.h"
57 #include "message_parcel.h"
58 #include "scope_utils.h"
59 #include "security_mode_parser.h"
60 #include "system_ability.h"
61 #include "system_ability_definition.h"
62 #include "tdd_util.h"
63 #include "text_listener.h"
64 #include "identity_checker_mock.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 void WaitKeyboardStatusCallback(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("KeyboardListenerImpl %{public}d %{public}d %{public}d %{public}d", oldBegin, oldEnd, newBegin,
216 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 imeListener_ = std::make_shared<InputMethodEngineListenerImpl>();
296 controllerListener_ = std::make_shared<SelectListenerMock>();
297 textListener_ = new TextListener();
298 inputMethodAbility_->SetKdListener(std::make_shared<KeyboardListenerImpl>());
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 }
326
TearDown(void)327 void InputMethodControllerTest::TearDown(void)
328 {
329 IMSA_HILOGI("InputMethodControllerTest::TearDown");
330 }
331
SetInputDeathRecipient()332 void InputMethodControllerTest::SetInputDeathRecipient()
333 {
334 IMSA_HILOGI("InputMethodControllerTest::SetInputDeathRecipient");
335 sptr<ISystemAbilityManager> systemAbilityManager =
336 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
337 if (systemAbilityManager == nullptr) {
338 IMSA_HILOGI("InputMethodControllerTest, system ability manager is nullptr");
339 return;
340 }
341 auto systemAbility = systemAbilityManager->GetSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID, "");
342 if (systemAbility == nullptr) {
343 IMSA_HILOGI("InputMethodControllerTest, system ability is nullptr");
344 return;
345 }
346 deathRecipient_ = new (std::nothrow) InputDeathRecipient();
347 if (deathRecipient_ == nullptr) {
348 IMSA_HILOGE("InputMethodControllerTest, new death recipient failed");
349 return;
350 }
351 deathRecipient_->SetDeathRecipient([](const wptr<IRemoteObject> &remote) { OnRemoteSaDied(remote); });
352 if ((systemAbility->IsProxyObject()) && (!systemAbility->AddDeathRecipient(deathRecipient_))) {
353 IMSA_HILOGE("InputMethodControllerTest, failed to add death recipient.");
354 return;
355 }
356 }
357
OnRemoteSaDied(const wptr<IRemoteObject> & remote)358 void InputMethodControllerTest::OnRemoteSaDied(const wptr<IRemoteObject> &remote)
359 {
360 IMSA_HILOGI("InputMethodControllerTest::OnRemoteSaDied");
361 onRemoteSaDiedCv_.notify_one();
362 }
363
WaitRemoteDiedCallback()364 bool InputMethodControllerTest::WaitRemoteDiedCallback()
365 {
366 IMSA_HILOGI("InputMethodControllerTest::WaitRemoteDiedCallback");
367 std::unique_lock<std::mutex> lock(onRemoteSaDiedMutex_);
368 return onRemoteSaDiedCv_.wait_for(lock, std::chrono::seconds(WAIT_SA_DIE_TIME_OUT)) != std::cv_status::timeout;
369 }
370
CheckProxyObject()371 void InputMethodControllerTest::CheckProxyObject()
372 {
373 for (uint32_t retryTimes = 0; retryTimes < RETRY_TIMES; ++retryTimes) {
374 IMSA_HILOGI("times = %{public}d", retryTimes);
375 sptr<ISystemAbilityManager> systemAbilityManager =
376 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
377 if (systemAbilityManager == nullptr) {
378 IMSA_HILOGI("system ability manager is nullptr");
379 continue;
380 }
381 auto systemAbility = systemAbilityManager->CheckSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID);
382 if (systemAbility != nullptr) {
383 IMSA_HILOGI("CheckProxyObject success!");
384 break;
385 }
386 usleep(RETRY_TIME);
387 }
388 }
389
CheckKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)390 void InputMethodControllerTest::CheckKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)
391 {
392 ASSERT_NE(keyEvent, nullptr);
393 bool ret = keyEvent->GetKeyCode() == keyEvent_->GetKeyCode();
394 EXPECT_TRUE(ret);
395 ret = keyEvent->GetKeyAction() == keyEvent_->GetKeyAction();
396 EXPECT_TRUE(ret);
397 ret = keyEvent->GetKeyIntention() == keyEvent_->GetKeyIntention();
398 EXPECT_TRUE(ret);
399 // check function key state
400 ret = keyEvent->GetFunctionKey(MMI::KeyEvent::NUM_LOCK_FUNCTION_KEY)
401 == keyEvent_->GetFunctionKey(MMI::KeyEvent::NUM_LOCK_FUNCTION_KEY);
402 EXPECT_TRUE(ret);
403 ret = keyEvent->GetFunctionKey(MMI::KeyEvent::CAPS_LOCK_FUNCTION_KEY)
404 == keyEvent_->GetFunctionKey(MMI::KeyEvent::CAPS_LOCK_FUNCTION_KEY);
405 EXPECT_TRUE(ret);
406 ret = keyEvent->GetFunctionKey(MMI::KeyEvent::SCROLL_LOCK_FUNCTION_KEY)
407 == keyEvent_->GetFunctionKey(MMI::KeyEvent::SCROLL_LOCK_FUNCTION_KEY);
408 EXPECT_TRUE(ret);
409 // check KeyItem
410 ret = keyEvent->GetKeyItems().size() == keyEvent_->GetKeyItems().size();
411 EXPECT_TRUE(ret);
412 ret = keyEvent->GetKeyItem()->GetKeyCode() == keyEvent_->GetKeyItem()->GetKeyCode();
413 EXPECT_TRUE(ret);
414 ret = keyEvent->GetKeyItem()->GetDownTime() == keyEvent_->GetKeyItem()->GetDownTime();
415 EXPECT_TRUE(ret);
416 ret = keyEvent->GetKeyItem()->GetDeviceId() == keyEvent_->GetKeyItem()->GetDeviceId();
417 EXPECT_TRUE(ret);
418 ret = keyEvent->GetKeyItem()->IsPressed() == keyEvent_->GetKeyItem()->IsPressed();
419 EXPECT_TRUE(ret);
420 ret = keyEvent->GetKeyItem()->GetUnicode() == keyEvent_->GetKeyItem()->GetUnicode();
421 EXPECT_TRUE(ret);
422 }
423
WaitKeyboardStatusCallback(bool keyboardState)424 void InputMethodControllerTest::WaitKeyboardStatusCallback(bool keyboardState)
425 {
426 std::unique_lock<std::mutex> lock(InputMethodEngineListenerImpl::imeListenerMutex_);
427 InputMethodEngineListenerImpl::imeListenerCv_.wait_for(lock,
428 std::chrono::seconds(InputMethodControllerTest::DELAY_TIME),
429 [keyboardState] { return InputMethodEngineListenerImpl::keyboardState_ == keyboardState; });
430 }
431
TriggerConfigurationChangeCallback(Configuration & info)432 void InputMethodControllerTest::TriggerConfigurationChangeCallback(Configuration &info)
433 {
434 textConfigHandler_->PostTask(
435 [info]() { inputMethodController_->OnConfigurationChange(info); }, InputMethodControllerTest::TASK_DELAY_TIME);
436 {
437 std::unique_lock<std::mutex> lock(InputMethodControllerTest::keyboardListenerMutex_);
438 InputMethodControllerTest::keyboardListenerCv_.wait_for(
439 lock, std::chrono::seconds(InputMethodControllerTest::DELAY_TIME), [&info] {
440 return (static_cast<OHOS::MiscServices::TextInputType>(
441 InputMethodControllerTest::inputAttribute_.inputPattern)
442 == info.GetTextInputType())
443 && (static_cast<OHOS::MiscServices::EnterKeyType>(
444 InputMethodControllerTest::inputAttribute_.enterKeyType)
445 == info.GetEnterKeyType());
446 });
447 }
448 }
449
TriggerCursorUpdateCallback(CursorInfo & info)450 void InputMethodControllerTest::TriggerCursorUpdateCallback(CursorInfo &info)
451 {
452 textConfigHandler_->PostTask(
453 [info]() { inputMethodController_->OnCursorUpdate(info); }, InputMethodControllerTest::TASK_DELAY_TIME);
454 {
455 std::unique_lock<std::mutex> lock(InputMethodControllerTest::keyboardListenerMutex_);
456 InputMethodControllerTest::keyboardListenerCv_.wait_for(lock,
457 std::chrono::seconds(InputMethodControllerTest::DELAY_TIME),
458 [&info] { return InputMethodControllerTest::cursorInfo_ == info; });
459 }
460 }
461
TriggerSelectionChangeCallback(std::u16string & text,int start,int end)462 void InputMethodControllerTest::TriggerSelectionChangeCallback(std::u16string &text, int start, int end)
463 {
464 IMSA_HILOGI("InputMethodControllerTest run in");
465 textConfigHandler_->PostTask([text, start, end]() { inputMethodController_->OnSelectionChange(text, start, end); },
466 InputMethodControllerTest::TASK_DELAY_TIME);
467 {
468 std::unique_lock<std::mutex> lock(InputMethodControllerTest::keyboardListenerMutex_);
469 InputMethodControllerTest::keyboardListenerCv_.wait_for(
470 lock, std::chrono::seconds(InputMethodControllerTest::DELAY_TIME), [&text, start, end] {
471 return InputMethodControllerTest::text_ == Str16ToStr8(text)
472 && InputMethodControllerTest::newBegin_ == start && InputMethodControllerTest::newEnd_ == end;
473 });
474 }
475 IMSA_HILOGI("InputMethodControllerTest end");
476 }
477
CheckTextConfig(const TextConfig & config)478 void InputMethodControllerTest::CheckTextConfig(const TextConfig &config)
479 {
480 EXPECT_EQ(imeListener_->windowId_, config.windowId);
481 EXPECT_EQ(cursorInfo_.left, config.cursorInfo.left);
482 EXPECT_EQ(cursorInfo_.top, config.cursorInfo.top);
483 EXPECT_EQ(cursorInfo_.height, config.cursorInfo.height);
484 EXPECT_EQ(newBegin_, config.range.start);
485 EXPECT_EQ(newEnd_, config.range.end);
486 EXPECT_EQ(inputAttribute_.inputPattern, config.inputAttribute.inputPattern);
487 EXPECT_EQ(inputAttribute_.enterKeyType, config.inputAttribute.enterKeyType);
488 }
489
DispatchKeyEventCallback(std::shared_ptr<MMI::KeyEvent> & keyEvent,bool isConsumed)490 void InputMethodControllerTest::DispatchKeyEventCallback(std::shared_ptr<MMI::KeyEvent> &keyEvent, bool isConsumed)
491 {
492 IMSA_HILOGI("InputMethodControllerTest isConsumed: %{public}d", isConsumed);
493 consumeResult_ = isConsumed;
494 keyEventCv_.notify_one();
495 }
496
WaitKeyEventCallback()497 bool InputMethodControllerTest::WaitKeyEventCallback()
498 {
499 std::unique_lock<std::mutex> lock(keyEventLock_);
500 keyEventCv_.wait_for(lock, std::chrono::seconds(DELAY_TIME), [] { return consumeResult_; });
501 return consumeResult_;
502 }
503
ResetKeyboardListenerTextConfig()504 void InputMethodControllerTest::ResetKeyboardListenerTextConfig()
505 {
506 cursorInfo_ = {};
507 oldBegin_ = INVALID_VALUE;
508 oldEnd_ = INVALID_VALUE;
509 newBegin_ = INVALID_VALUE;
510 newEnd_ = INVALID_VALUE;
511 text_ = "";
512 inputAttribute_ = {};
513 }
514
515 /**
516 * @tc.name: testIMCAttach001
517 * @tc.desc: IMC Attach.
518 * @tc.type: FUNC
519 * @tc.require:
520 */
521 HWTEST_F(InputMethodControllerTest, testIMCAttach001, TestSize.Level0)
522 {
523 IMSA_HILOGI("IMC testIMCAttach001 Test START");
524 imeListener_->isInputStart_ = false;
525 TextListener::ResetParam();
526 inputMethodController_->Attach(textListener_, false);
527 inputMethodController_->Attach(textListener_);
528 inputMethodController_->Attach(textListener_, true);
529 EXPECT_TRUE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::SHOW));
530 EXPECT_TRUE(imeListener_->isInputStart_ && imeListener_->keyboardState_);
531 }
532
533 /**
534 * @tc.name: testIMCAttach002
535 * @tc.desc: IMC Attach.
536 * @tc.type: FUNC
537 * @tc.require:
538 */
539 HWTEST_F(InputMethodControllerTest, testIMCAttach002, TestSize.Level0)
540 {
541 IMSA_HILOGI("IMC testIMCAttach002 Test START");
542 TextListener::ResetParam();
543 CursorInfo cursorInfo = { 1, 1, 1, 1 };
544 Range selectionRange = { 1, 2 };
545 InputAttribute attribute = { 1, 1 };
546 uint32_t windowId = 10;
547 TextConfig textConfig = {
548 .inputAttribute = attribute, .cursorInfo = cursorInfo, .range = selectionRange, .windowId = windowId
549 };
550
551 inputMethodController_->Attach(textListener_, true, textConfig);
552 InputMethodControllerTest::CheckTextConfig(textConfig);
553
554 TextListener::ResetParam();
555 cursorInfo = { 2, 2, 2, 2 };
556 selectionRange = { 3, 4 };
557 attribute = { 2, 2 };
558 windowId = 11;
559 textConfig = {
560 .inputAttribute = attribute, .cursorInfo = cursorInfo, .range = selectionRange, .windowId = windowId
561 };
562 inputMethodController_->Attach(textListener_, true, textConfig);
563 InputMethodControllerTest::CheckTextConfig(textConfig);
564 }
565
566 /**
567 * @tc.name: testIMCSetCallingWindow
568 * @tc.desc: IMC SetCallingWindow.
569 * @tc.type: FUNC
570 * @tc.require:
571 */
572 HWTEST_F(InputMethodControllerTest, testIMCSetCallingWindow, TestSize.Level0)
573 {
574 IMSA_HILOGI("IMC SetCallingWindow Test START");
575 auto ret = inputMethodController_->Attach(textListener_);
576 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
577 uint32_t windowId = 3;
578 ret = inputMethodController_->SetCallingWindow(windowId);
579 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
580 EXPECT_EQ(windowId, imeListener_->windowId_);
581 }
582
583 /**
584 * @tc.name: testGetIMSAProxy
585 * @tc.desc: Get Imsa Proxy.
586 * @tc.type: FUNC
587 */
588 HWTEST_F(InputMethodControllerTest, testGetIMSAProxy, TestSize.Level0)
589 {
590 auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
591 ASSERT_NE(systemAbilityManager, nullptr);
592 auto systemAbility = systemAbilityManager->GetSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID, "");
593 EXPECT_TRUE(systemAbility != nullptr);
594 }
595
596 /**
597 * @tc.name: testWriteReadIInputDataChannel
598 * @tc.desc: Checkout IInputDataChannel.
599 * @tc.type: FUNC
600 */
601 HWTEST_F(InputMethodControllerTest, testWriteReadIInputDataChannel, TestSize.Level0)
602 {
603 sptr<InputDataChannelStub> mInputDataChannel = new InputDataChannelStub();
604 MessageParcel data;
605 auto ret = data.WriteRemoteObject(mInputDataChannel->AsObject());
606 EXPECT_TRUE(ret);
607 auto remoteObject = data.ReadRemoteObject();
608 sptr<IInputDataChannel> iface = iface_cast<IInputDataChannel>(remoteObject);
609 EXPECT_TRUE(iface != nullptr);
610 }
611
612 /**
613 * @tc.name: testIMCBindToIMSA
614 * @tc.desc: Bind IMSA.
615 * @tc.type: FUNC
616 */
617 HWTEST_F(InputMethodControllerTest, testIMCBindToIMSA, TestSize.Level0)
618 {
619 sptr<InputClientStub> mClient = new InputClientStub();
620 MessageParcel data;
621 auto ret = data.WriteRemoteObject(mClient->AsObject());
622 EXPECT_TRUE(ret);
623 auto remoteObject = data.ReadRemoteObject();
624 sptr<IInputClient> iface = iface_cast<IInputClient>(remoteObject);
625 EXPECT_TRUE(iface != nullptr);
626 }
627
628 /**
629 * @tc.name: testIMCDispatchKeyEvent001
630 * @tc.desc: test IMC DispatchKeyEvent with 'keyDown/KeyUP'.
631 * @tc.type: FUNC
632 * @tc.require:
633 */
634 HWTEST_F(InputMethodControllerTest, testIMCDispatchKeyEvent001, TestSize.Level0)
635 {
636 IMSA_HILOGI("IMC testIMCDispatchKeyEvent001 Test START");
637 doesKeyEventConsume_ = true;
638 doesFUllKeyEventConsume_ = false;
639 blockKeyEvent_.Clear(nullptr);
640 auto res = inputMethodController_->Attach(textListener_);
641 EXPECT_EQ(res, ErrorCode::NO_ERROR);
642
643 bool ret = inputMethodController_->DispatchKeyEvent(keyEvent_, DispatchKeyEventCallback);
644 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
645
646 EXPECT_TRUE(WaitKeyEventCallback());
647
648 auto keyEvent = blockKeyEvent_.GetValue();
649 ASSERT_NE(keyEvent, nullptr);
650 EXPECT_EQ(keyEvent->GetKeyCode(), keyEvent_->GetKeyCode());
651 EXPECT_EQ(keyEvent->GetKeyAction(), keyEvent_->GetKeyAction());
652
653 doesKeyEventConsume_ = false;
654 ret = inputMethodController_->DispatchKeyEvent(keyEvent_, DispatchKeyEventCallback);
655 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
656
657 EXPECT_TRUE(!WaitKeyEventCallback());
658 }
659
660 /**
661 * @tc.name: testIMCDispatchKeyEvent002
662 * @tc.desc: test IMC DispatchKeyEvent with 'keyEvent'.
663 * @tc.type: FUNC
664 * @tc.require:
665 */
666 HWTEST_F(InputMethodControllerTest, testIMCDispatchKeyEvent002, TestSize.Level0)
667 {
668 IMSA_HILOGI("IMC testIMCDispatchKeyEvent002 Test START");
669 doesKeyEventConsume_ = false;
670 doesFUllKeyEventConsume_ = true;
671 blockFullKeyEvent_.Clear(nullptr);
672 int32_t ret = inputMethodController_->DispatchKeyEvent(
__anon3dad76a90a02(std::shared_ptr<MMI::KeyEvent> &keyEvent, bool isConsumed) 673 keyEvent_, [](std::shared_ptr<MMI::KeyEvent> &keyEvent, bool isConsumed) {});
674 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
675 auto keyEvent = blockFullKeyEvent_.GetValue();
676 ASSERT_NE(keyEvent, nullptr);
677 CheckKeyEvent(keyEvent);
678 }
679
680 /**
681 * @tc.name: testIMCDispatchKeyEvent003
682 * @tc.desc: test IMC DispatchKeyEvent with 'keyDown/KeyUP' and 'keyEvent'.
683 * @tc.type: FUNC
684 * @tc.require:
685 */
686 HWTEST_F(InputMethodControllerTest, testIMCDispatchKeyEvent003, TestSize.Level0)
687 {
688 IMSA_HILOGI("IMC testIMCDispatchKeyEvent003 Test START");
689 doesKeyEventConsume_ = true;
690 doesFUllKeyEventConsume_ = true;
691 blockKeyEvent_.Clear(nullptr);
692 blockFullKeyEvent_.Clear(nullptr);
693 int32_t ret = inputMethodController_->DispatchKeyEvent(
__anon3dad76a90b02(std::shared_ptr<MMI::KeyEvent> &keyEvent, bool isConsumed) 694 keyEvent_, [](std::shared_ptr<MMI::KeyEvent> &keyEvent, bool isConsumed) {});
695 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
696 auto keyEvent = blockKeyEvent_.GetValue();
697 auto keyFullEvent = blockFullKeyEvent_.GetValue();
698 ASSERT_NE(keyEvent, nullptr);
699 EXPECT_EQ(keyEvent->GetKeyCode(), keyEvent_->GetKeyCode());
700 EXPECT_EQ(keyEvent->GetKeyAction(), keyEvent_->GetKeyAction());
701 ASSERT_NE(keyFullEvent, nullptr);
702 CheckKeyEvent(keyFullEvent);
703 }
704
705 /**
706 * @tc.name: testIMCOnCursorUpdate01
707 * @tc.desc: Test update cursorInfo, call 'OnCursorUpdate' twice, if cursorInfo is the same,
708 * the second time will not get callback.
709 * @tc.type: FUNC
710 * @tc.require:
711 * @tc.author: Zhaolinglan
712 */
713 HWTEST_F(InputMethodControllerTest, testIMCOnCursorUpdate01, TestSize.Level0)
714 {
715 IMSA_HILOGI("IMC testIMCOnCursorUpdate01 Test START");
716 auto ret = inputMethodController_->Attach(textListener_, false);
717 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
718 CursorInfo info = { 1, 3, 0, 5 };
719 InputMethodControllerTest::TriggerCursorUpdateCallback(info);
720 EXPECT_EQ(InputMethodControllerTest::cursorInfo_, info);
721
722 InputMethodControllerTest::cursorInfo_ = {};
723 InputMethodControllerTest::TriggerCursorUpdateCallback(info);
724 EXPECT_FALSE(InputMethodControllerTest::cursorInfo_ == info);
725 }
726
727 /**
728 * @tc.name: testIMCOnCursorUpdate02
729 * @tc.desc: Test update cursorInfo, 'Attach'->'OnCursorUpdate'->'Close'->'Attach'->'OnCursorUpdate',
730 * it will get callback two time.
731 * @tc.type: FUNC
732 * @tc.require:
733 * @tc.author: Zhaolinglan
734 */
735 HWTEST_F(InputMethodControllerTest, testIMCOnCursorUpdate02, TestSize.Level0)
736 {
737 IMSA_HILOGI("IMC testIMCOnCursorUpdate02 Test START");
738 auto ret = inputMethodController_->Attach(textListener_, false);
739 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
740 CursorInfo info = { 2, 4, 0, 6 };
741 InputMethodControllerTest::TriggerCursorUpdateCallback(info);
742 EXPECT_EQ(InputMethodControllerTest::cursorInfo_, info);
743
744 InputMethodControllerTest::cursorInfo_ = {};
745 ret = InputMethodControllerTest::inputMethodController_->Close();
746 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
747 ret = inputMethodController_->Attach(textListener_, false);
748 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
749 InputMethodControllerTest::TriggerCursorUpdateCallback(info);
750 EXPECT_EQ(InputMethodControllerTest::cursorInfo_, info);
751 }
752
753 /**
754 * @tc.name: testIMCOnSelectionChange01
755 * @tc.desc: Test change selection, call 'OnSelectionChange' twice, if selection is the same,
756 * the second time will not get callback.
757 * @tc.type: FUNC
758 * @tc.require:
759 * @tc.author: Zhaolinglan
760 */
761 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange01, TestSize.Level0)
762 {
763 IMSA_HILOGI("IMC testIMCOnSelectionChange01 Test START");
764 auto ret = inputMethodController_->Attach(textListener_, false);
765 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
766 std::u16string text = Str8ToStr16("testSelect");
767 int start = 1;
768 int end = 2;
769 InputMethodControllerTest::TriggerSelectionChangeCallback(text, start, end);
770 EXPECT_EQ(InputMethodControllerTest::text_, Str16ToStr8(text));
771
772 InputMethodControllerTest::text_ = "";
773 InputMethodControllerTest::TriggerSelectionChangeCallback(text, start, end);
774 EXPECT_NE(InputMethodControllerTest::text_, Str16ToStr8(text));
775 }
776
777 /**
778 * @tc.name: testIMCOnSelectionChange02
779 * @tc.desc: Test change selection, 'Attach'->'OnSelectionChange'->'Close'->'Attach'->'OnSelectionChange',
780 * it will get callback two time.
781 * @tc.type: FUNC
782 * @tc.require:
783 * @tc.author: Zhaolinglan
784 */
785 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange02, TestSize.Level0)
786 {
787 IMSA_HILOGI("IMC testIMCOnSelectionChange02 Test START");
788 auto ret = inputMethodController_->Attach(textListener_, false);
789 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
790 std::u16string text = Str8ToStr16("testSelect2");
791 int start = 1;
792 int end = 2;
793 InputMethodControllerTest::TriggerSelectionChangeCallback(text, start, end);
794 EXPECT_EQ(InputMethodControllerTest::text_, Str16ToStr8(text));
795
796 InputMethodControllerTest::text_ = "";
797 InputMethodControllerTest::inputMethodController_->Close();
798 inputMethodController_->Attach(textListener_, false);
799 InputMethodControllerTest::TriggerSelectionChangeCallback(text, start, end);
800 EXPECT_EQ(InputMethodControllerTest::text_, Str16ToStr8(text));
801 }
802
803 /**
804 * @tc.name: testIMCOnSelectionChange03
805 * @tc.desc: Test change selection, 'Attach without config'->'OnSelectionChange(0, 0)', it will get callback.
806 * @tc.type: FUNC
807 * @tc.require:
808 * @tc.author: Zhaolinglan
809 */
810 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange03, TestSize.Level0)
811 {
812 IMSA_HILOGI("IMC testIMCOnSelectionChange03 Test START");
813 InputMethodControllerTest::ResetKeyboardListenerTextConfig();
814 InputMethodControllerTest::inputMethodController_->Close();
815 auto ret = inputMethodController_->Attach(textListener_, false);
816 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
817 std::u16string text = Str8ToStr16("");
818 int start = 0;
819 int end = 0;
820 InputMethodControllerTest::TriggerSelectionChangeCallback(text, start, end);
821 EXPECT_EQ(InputMethodControllerTest::text_, Str16ToStr8(text));
822 EXPECT_EQ(InputMethodControllerTest::oldBegin_, INVALID_VALUE);
823 EXPECT_EQ(InputMethodControllerTest::oldEnd_, INVALID_VALUE);
824 EXPECT_EQ(InputMethodControllerTest::newBegin_, start);
825 EXPECT_EQ(InputMethodControllerTest::newEnd_, end);
826 }
827
828 /**
829 * @tc.name: testIMCOnSelectionChange04
830 * @tc.desc: Test change selection, 'Attach with range(1, 1)'->'Attach witch range(2, 2)', it will get (1, 1, 2, 2).
831 * @tc.type: FUNC
832 * @tc.require:
833 * @tc.author: Zhaolinglan
834 */
835 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange04, TestSize.Level0)
836 {
837 IMSA_HILOGI("IMC testIMCOnSelectionChange04 Test START");
838 InputMethodControllerTest::ResetKeyboardListenerTextConfig();
839 InputMethodControllerTest::inputMethodController_->Close();
840 TextConfig textConfig;
841 textConfig.range = { 1, 1 };
842 auto ret = inputMethodController_->Attach(textListener_, false, textConfig);
843 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
844 textConfig.range = { 2, 2 };
845 ret = inputMethodController_->Attach(textListener_, false, textConfig);
846 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
847 EXPECT_EQ(InputMethodControllerTest::oldBegin_, 1);
848 EXPECT_EQ(InputMethodControllerTest::oldEnd_, 1);
849 EXPECT_EQ(InputMethodControllerTest::newBegin_, 2);
850 EXPECT_EQ(InputMethodControllerTest::newEnd_, 2);
851 }
852
853 /**
854 * @tc.name: testIMCOnSelectionChange05
855 * @tc.desc: 'Attach without range'-> it will get no selectionChange callback.
856 * @tc.type: FUNC
857 * @tc.require:
858 * @tc.author: Zhaolinglan
859 */
860 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange05, TestSize.Level0)
861 {
862 IMSA_HILOGI("IMC testIMCOnSelectionChange05 Test START");
863 InputMethodControllerTest::ResetKeyboardListenerTextConfig();
864 InputMethodControllerTest::inputMethodController_->Close();
865 inputMethodController_->Attach(textListener_, false);
866 EXPECT_EQ(InputMethodControllerTest::oldBegin_, INVALID_VALUE);
867 EXPECT_EQ(InputMethodControllerTest::oldEnd_, INVALID_VALUE);
868 EXPECT_EQ(InputMethodControllerTest::newBegin_, INVALID_VALUE);
869 EXPECT_EQ(InputMethodControllerTest::newEnd_, INVALID_VALUE);
870 }
871
872 /**
873 * @tc.name: testIMCOnSelectionChange06
874 * @tc.desc: 'Update(1, 2)'->'Attach without range', it will get no selectionChange callback.
875 * @tc.type: FUNC
876 * @tc.require:
877 * @tc.author: Zhaolinglan
878 */
879 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange06, TestSize.Level0)
880 {
881 IMSA_HILOGI("IMC testIMCOnSelectionChange06 Test START");
882 InputMethodControllerTest::inputMethodController_->Close();
883 inputMethodController_->Attach(textListener_, false);
884 std::u16string text = Str8ToStr16("");
885 InputMethodControllerTest::TriggerSelectionChangeCallback(text, 1, 2);
886 InputMethodControllerTest::ResetKeyboardListenerTextConfig();
887 inputMethodController_->Attach(textListener_, false);
888 EXPECT_EQ(InputMethodControllerTest::oldBegin_, INVALID_VALUE);
889 EXPECT_EQ(InputMethodControllerTest::oldEnd_, INVALID_VALUE);
890 EXPECT_EQ(InputMethodControllerTest::newBegin_, INVALID_VALUE);
891 EXPECT_EQ(InputMethodControllerTest::newEnd_, INVALID_VALUE);
892 }
893
894 /**
895 * @tc.name: testIMCOnSelectionChange07
896 * @tc.desc: 'Attach with range -> Attach without range', it will get no selectionChange callback.
897 * @tc.type: FUNC
898 * @tc.require:
899 * @tc.author: Zhaolinglan
900 */
901 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange07, TestSize.Level0)
902 {
903 IMSA_HILOGI("IMC testIMCOnSelectionChange07 Test START");
904 InputMethodControllerTest::inputMethodController_->Close();
905 TextConfig textConfig;
906 textConfig.range = { 1, 1 };
907 inputMethodController_->Attach(textListener_, false, textConfig);
908 InputMethodControllerTest::ResetKeyboardListenerTextConfig();
909 inputMethodController_->Attach(textListener_, false);
910 EXPECT_EQ(InputMethodControllerTest::oldBegin_, INVALID_VALUE);
911 EXPECT_EQ(InputMethodControllerTest::oldEnd_, INVALID_VALUE);
912 EXPECT_EQ(InputMethodControllerTest::newBegin_, INVALID_VALUE);
913 EXPECT_EQ(InputMethodControllerTest::newEnd_, INVALID_VALUE);
914 }
915
916 /**
917 * @tc.name: testIMCOnSelectionChange08
918 * @tc.desc: 'OnSelectionChange(1, 2) -> Attach without range -> OnSelectionChange(3, 4)', it will get (1,2,3,4)
919 * @tc.type: FUNC
920 * @tc.require:
921 * @tc.author: Zhaolinglan
922 */
923 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange08, TestSize.Level0)
924 {
925 IMSA_HILOGI("IMC testIMCOnSelectionChange08 Test START");
926 InputMethodControllerTest::inputMethodController_->Close();
927 inputMethodController_->Attach(textListener_, false);
928 std::u16string text = Str8ToStr16("");
929 InputMethodControllerTest::TriggerSelectionChangeCallback(text, 1, 2);
930 InputMethodControllerTest::ResetKeyboardListenerTextConfig();
931 inputMethodController_->Attach(textListener_, false);
932 InputMethodControllerTest::TriggerSelectionChangeCallback(text, 3, 4);
933 EXPECT_EQ(InputMethodControllerTest::oldBegin_, 1);
934 EXPECT_EQ(InputMethodControllerTest::oldEnd_, 2);
935 EXPECT_EQ(InputMethodControllerTest::newBegin_, 3);
936 EXPECT_EQ(InputMethodControllerTest::newEnd_, 4);
937 }
938
939 /**
940 * @tc.name: testIMCOnSelectionChange09
941 * @tc.desc: Attach with range(0, 0) -> OnSelectionChange("", 0, 0) -> Get 'textChange' and 'selectionChange' Callback
942 * @tc.type: FUNC
943 * @tc.require:
944 * @tc.author: Zhaolinglan
945 */
946 HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange09, TestSize.Level0)
947 {
948 IMSA_HILOGI("IMC testIMCOnSelectionChange09 Test START");
949 InputMethodControllerTest::inputMethodController_->Close();
950 TextConfig textConfig;
951 textConfig.range = { 0, 0 };
952 auto ret = inputMethodController_->Attach(textListener_, false, textConfig);
953 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
954 InputMethodControllerTest::ResetKeyboardListenerTextConfig();
955 InputMethodControllerTest::text_ = "test";
956 std::u16string text = Str8ToStr16("test1");
957 InputMethodControllerTest::TriggerSelectionChangeCallback(text, 1, 6);
958 EXPECT_EQ(InputMethodControllerTest::text_, "test1");
959 EXPECT_EQ(InputMethodControllerTest::newBegin_, 1);
960 EXPECT_EQ(InputMethodControllerTest::newEnd_, 6);
961 }
962
963 /**
964 * @tc.name: testShowTextInput
965 * @tc.desc: IMC ShowTextInput
966 * @tc.type: FUNC
967 */
968 HWTEST_F(InputMethodControllerTest, testShowTextInput, TestSize.Level0)
969 {
970 IMSA_HILOGI("IMC ShowTextInput Test START");
971 TextListener::ResetParam();
972 inputMethodController_->ShowTextInput();
973 EXPECT_TRUE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::SHOW));
974 }
975
976 /**
977 * @tc.name: testShowSoftKeyboard
978 * @tc.desc: IMC ShowSoftKeyboard
979 * @tc.type: FUNC
980 */
981 HWTEST_F(InputMethodControllerTest, testShowSoftKeyboard, TestSize.Level0)
982 {
983 IMSA_HILOGI("IMC ShowSoftKeyboard Test START");
984 IdentityCheckerMock::SetPermission(true);
985 imeListener_->keyboardState_ = false;
986 TextListener::ResetParam();
987 int32_t ret = inputMethodController_->ShowSoftKeyboard();
988 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
989 EXPECT_TRUE(imeListener_->keyboardState_ && TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::SHOW));
990 IdentityCheckerMock::SetPermission(false);
991 }
992
993 /**
994 * @tc.name: testShowCurrentInput
995 * @tc.desc: IMC ShowCurrentInput
996 * @tc.type: FUNC
997 */
998 HWTEST_F(InputMethodControllerTest, testShowCurrentInput, TestSize.Level0)
999 {
1000 IMSA_HILOGI("IMC ShowCurrentInput Test START");
1001 imeListener_->keyboardState_ = false;
1002 TextListener::ResetParam();
1003 int32_t ret = inputMethodController_->ShowCurrentInput();
1004 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1005 EXPECT_TRUE(imeListener_->keyboardState_ && TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::SHOW));
1006 }
1007
1008 /**
1009 * @tc.name: testIMCGetEnterKeyType
1010 * @tc.desc: IMC testGetEnterKeyType.
1011 * @tc.type: FUNC
1012 * @tc.require:
1013 */
1014 HWTEST_F(InputMethodControllerTest, testIMCGetEnterKeyType, TestSize.Level0)
1015 {
1016 IMSA_HILOGI("IMC GetEnterKeyType Test START");
1017 int32_t keyType;
1018 inputMethodController_->GetEnterKeyType(keyType);
1019 EXPECT_TRUE(keyType >= static_cast<int32_t>(EnterKeyType::UNSPECIFIED)
1020 && keyType <= static_cast<int32_t>(EnterKeyType::PREVIOUS));
1021 }
1022
1023 /**
1024 * @tc.name: testIMCGetInputPattern
1025 * @tc.desc: IMC testGetInputPattern.
1026 * @tc.type: FUNC
1027 * @tc.require:
1028 */
1029 HWTEST_F(InputMethodControllerTest, testIMCGetInputPattern, TestSize.Level0)
1030 {
1031 IMSA_HILOGI("IMC GetInputPattern Test START");
1032 int32_t inputPattern;
1033 inputMethodController_->GetInputPattern(inputPattern);
1034 EXPECT_TRUE(inputPattern >= static_cast<int32_t>(TextInputType::NONE)
1035 && inputPattern <= static_cast<int32_t>(TextInputType::VISIBLE_PASSWORD));
1036 }
1037
1038 /**
1039 * @tc.name: testOnEditorAttributeChanged01
1040 * @tc.desc: IMC testOnEditorAttributeChanged01.
1041 * @tc.type: FUNC
1042 * @tc.require:
1043 */
1044 HWTEST_F(InputMethodControllerTest, testOnEditorAttributeChanged01, TestSize.Level0)
1045 {
1046 IMSA_HILOGI("IMC testOnEditorAttributeChanged01 Test START");
1047 auto ret = inputMethodController_->Attach(textListener_, false);
1048 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1049 Configuration info;
1050 info.SetEnterKeyType(EnterKeyType::GO);
1051 info.SetTextInputType(TextInputType::NUMBER);
1052 InputMethodControllerTest::TriggerConfigurationChangeCallback(info);
1053 EXPECT_EQ(InputMethodControllerTest::inputAttribute_.inputPattern, static_cast<int32_t>(info.GetTextInputType()));
1054 EXPECT_EQ(InputMethodControllerTest::inputAttribute_.enterKeyType, static_cast<int32_t>(info.GetEnterKeyType()));
1055 }
1056
1057 /**
1058 * @tc.name: testOnEditorAttributeChanged02
1059 * @tc.desc: Attach(isPreviewSupport) -> OnConfigurationChange -> editorChange callback (isPreviewSupport).
1060 * @tc.type: FUNC
1061 * @tc.require:
1062 */
1063 HWTEST_F(InputMethodControllerTest, testOnEditorAttributeChanged02, TestSize.Level0)
1064 {
1065 IMSA_HILOGI("IMC testOnEditorAttributeChanged02 Test START");
1066 InputAttribute attribute = { .inputPattern = static_cast<int32_t>(TextInputType::DATETIME),
1067 .enterKeyType = static_cast<int32_t>(EnterKeyType::GO),
1068 .isTextPreviewSupported = true };
1069 auto ret = inputMethodController_->Attach(textListener_, false, attribute);
1070 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1071 Configuration info;
1072 info.SetEnterKeyType(EnterKeyType::NEW_LINE);
1073 info.SetTextInputType(TextInputType::NUMBER);
1074 InputMethodControllerTest::ResetKeyboardListenerTextConfig();
1075 InputMethodControllerTest::TriggerConfigurationChangeCallback(info);
1076 EXPECT_EQ(InputMethodControllerTest::inputAttribute_.inputPattern, static_cast<int32_t>(info.GetTextInputType()));
1077 EXPECT_EQ(InputMethodControllerTest::inputAttribute_.enterKeyType, static_cast<int32_t>(info.GetEnterKeyType()));
1078 EXPECT_EQ(InputMethodControllerTest::inputAttribute_.isTextPreviewSupported, attribute.isTextPreviewSupported);
1079 }
1080
1081 /**
1082 * @tc.name: testHideSoftKeyboard
1083 * @tc.desc: IMC HideSoftKeyboard
1084 * @tc.type: FUNC
1085 */
1086 HWTEST_F(InputMethodControllerTest, testHideSoftKeyboard, TestSize.Level0)
1087 {
1088 IMSA_HILOGI("IMC HideSoftKeyboard Test START");
1089 IdentityCheckerMock::SetPermission(true);
1090 imeListener_->keyboardState_ = true;
1091 TextListener::ResetParam();
1092 int32_t ret = inputMethodController_->HideSoftKeyboard();
1093 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1094 EXPECT_TRUE(!imeListener_->keyboardState_ && TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::HIDE));
1095 IdentityCheckerMock::SetPermission(false);
1096 }
1097
1098 /**
1099 * @tc.name: testIMCHideCurrentInput
1100 * @tc.desc: IMC HideCurrentInput.
1101 * @tc.type: FUNC
1102 * @tc.require:
1103 */
1104 HWTEST_F(InputMethodControllerTest, testIMCHideCurrentInput, TestSize.Level0)
1105 {
1106 IMSA_HILOGI("IMC HideCurrentInput Test START");
1107 imeListener_->keyboardState_ = true;
1108 TextListener::ResetParam();
1109 int32_t ret = inputMethodController_->HideCurrentInput();
1110 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1111 EXPECT_TRUE(!imeListener_->keyboardState_ && TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::HIDE));
1112 }
1113
1114 /**
1115 * @tc.name: testIMCInputStopSession
1116 * @tc.desc: IMC testInputStopSession.
1117 * @tc.type: FUNC
1118 * @tc.require: issueI5U8FZ
1119 * @tc.author: Hollokin
1120 */
1121 HWTEST_F(InputMethodControllerTest, testIMCInputStopSession, TestSize.Level0)
1122 {
1123 IMSA_HILOGI("IMC StopInputSession Test START");
1124 imeListener_->keyboardState_ = true;
1125 int32_t ret = inputMethodController_->StopInputSession();
1126 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1127 WaitKeyboardStatusCallback(false);
1128 EXPECT_TRUE(!imeListener_->keyboardState_);
1129 }
1130
1131 /**
1132 * @tc.name: testIMCHideTextInput.
1133 * @tc.desc: IMC testHideTextInput.
1134 * @tc.type: FUNC
1135 */
1136 HWTEST_F(InputMethodControllerTest, testIMCHideTextInput, TestSize.Level0)
1137 {
1138 IMSA_HILOGI("IMC HideTextInput Test START");
1139 imeListener_->keyboardState_ = true;
1140 inputMethodController_->HideTextInput();
1141 WaitKeyboardStatusCallback(false);
1142 EXPECT_TRUE(!imeListener_->keyboardState_);
1143 }
1144
1145 /**
1146 * @tc.name: testIMCRequestShowInput.
1147 * @tc.desc: IMC testIMCRequestShowInput.
1148 * @tc.type: FUNC
1149 */
1150 HWTEST_F(InputMethodControllerTest, testIMCRequestShowInput, TestSize.Level0)
1151 {
1152 IMSA_HILOGI("IMC testIMCRequestShowInput Test START");
1153 imeListener_->keyboardState_ = false;
1154 int32_t ret = InputMethodControllerTest::inputMethodController_->RequestShowInput();
1155 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1156 EXPECT_TRUE(imeListener_->keyboardState_);
1157 }
1158
1159 /**
1160 * @tc.name: testIMCRequestHideInput.
1161 * @tc.desc: IMC testIMCRequestHideInput.
1162 * @tc.type: FUNC
1163 */
1164 HWTEST_F(InputMethodControllerTest, testIMCRequestHideInput, TestSize.Level0)
1165 {
1166 IMSA_HILOGI("IMC testIMCRequestHideInput Test START");
1167 imeListener_->keyboardState_ = true;
1168 int32_t ret = InputMethodControllerTest::inputMethodController_->RequestHideInput();
1169 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1170 EXPECT_FALSE(imeListener_->keyboardState_);
1171 }
1172
1173 /**
1174 * @tc.name: testSetControllerListener
1175 * @tc.desc: IMC SetControllerListener
1176 * @tc.type: FUNC
1177 */
1178 HWTEST_F(InputMethodControllerTest, testSetControllerListener, TestSize.Level0)
1179 {
1180 IMSA_HILOGI("IMC SetControllerListener Test START");
1181 inputMethodController_->SetControllerListener(controllerListener_);
1182
1183 int32_t ret = inputMethodController_->Attach(textListener_, false);
1184 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1185 SelectListenerMock::start_ = 0;
1186 SelectListenerMock::end_ = 0;
1187 inputMethodAbility_->SelectByRange(1, 2);
1188 SelectListenerMock::WaitSelectListenerCallback();
1189 EXPECT_EQ(SelectListenerMock::start_, 1);
1190 EXPECT_EQ(SelectListenerMock::end_, 2);
1191
1192 SelectListenerMock::direction_ = 0;
1193 inputMethodAbility_->SelectByMovement(static_cast<int32_t>(Direction::UP));
1194 SelectListenerMock::WaitSelectListenerCallback();
1195 EXPECT_EQ(SelectListenerMock::direction_, static_cast<int32_t>(Direction::UP));
1196
1197 SelectListenerMock::direction_ = 0;
1198 inputMethodAbility_->SelectByMovement(static_cast<int32_t>(Direction::DOWN));
1199 SelectListenerMock::WaitSelectListenerCallback();
1200 EXPECT_EQ(SelectListenerMock::direction_, static_cast<int32_t>(Direction::DOWN));
1201
1202 SelectListenerMock::direction_ = 0;
1203 inputMethodAbility_->SelectByMovement(static_cast<int32_t>(Direction::LEFT));
1204 SelectListenerMock::WaitSelectListenerCallback();
1205 EXPECT_EQ(SelectListenerMock::direction_, static_cast<int32_t>(Direction::LEFT));
1206
1207 SelectListenerMock::direction_ = 0;
1208 inputMethodAbility_->SelectByMovement(static_cast<int32_t>(Direction::RIGHT));
1209 SelectListenerMock::WaitSelectListenerCallback();
1210 EXPECT_EQ(SelectListenerMock::direction_, static_cast<int32_t>(Direction::RIGHT));
1211 }
1212
1213 /**
1214 * @tc.name: testWasAttached
1215 * @tc.desc: IMC WasAttached
1216 * @tc.type: FUNC
1217 */
1218 HWTEST_F(InputMethodControllerTest, testWasAttached, TestSize.Level0)
1219 {
1220 IMSA_HILOGI("IMC WasAttached Test START");
1221 inputMethodController_->Close();
1222 bool result = inputMethodController_->WasAttached();
1223 EXPECT_FALSE(result);
1224 int32_t ret = inputMethodController_->Attach(textListener_, false);
1225 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1226 result = inputMethodController_->WasAttached();
1227 EXPECT_TRUE(result);
1228 inputMethodController_->Close();
1229 }
1230
1231 /**
1232 * @tc.name: testGetDefaultInputMethod
1233 * @tc.desc: IMC GetDefaultInputMethod
1234 * @tc.type: FUNC
1235 */
1236 HWTEST_F(InputMethodControllerTest, testGetDefaultInputMethod, TestSize.Level0)
1237 {
1238 IMSA_HILOGI("IMC testGetDefaultInputMethod Test START");
1239 std::shared_ptr<Property> property = nullptr;
1240 int32_t ret = inputMethodController_->GetDefaultInputMethod(property);
1241 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1242 ASSERT_NE(property, nullptr);
1243 EXPECT_FALSE(property->name.empty());
1244 }
1245
1246 /**
1247 * @tc.name: testGetSystemInputMethodConfig
1248 * @tc.desc: IMC GetSystemInputMethodConfig
1249 * @tc.type: FUNC
1250 */
1251 HWTEST_F(InputMethodControllerTest, GetSystemInputMethodConfig, TestSize.Level0)
1252 {
1253 IMSA_HILOGI("IMC GetSystemInputMethodConfig Test START");
1254 OHOS::AppExecFwk::ElementName inputMethodConfig;
1255 int32_t ret = inputMethodController_->GetInputMethodConfig(inputMethodConfig);
1256 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1257 EXPECT_GE(inputMethodConfig.GetBundleName().length(), 0);
1258 EXPECT_GE(inputMethodConfig.GetAbilityName().length(), 0);
1259 }
1260
1261 /**
1262 * @tc.name: testWithoutEditableState
1263 * @tc.desc: IMC testWithoutEditableState
1264 * @tc.type: FUNC
1265 * @tc.require:
1266 */
1267 HWTEST_F(InputMethodControllerTest, testWithoutEditableState, TestSize.Level0)
1268 {
1269 IMSA_HILOGI("IMC WithouteEditableState Test START");
1270 auto ret = inputMethodController_->Attach(textListener_, false);
1271 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1272 ret = inputMethodController_->HideTextInput();
1273 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1274
1275 int32_t deleteForwardLength = 1;
1276 ret = inputMethodAbility_->DeleteForward(deleteForwardLength);
1277 EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
1278 EXPECT_NE(TextListener::deleteForwardLength_, deleteForwardLength);
1279
1280 int32_t deleteBackwardLength = 2;
1281 ret = inputMethodAbility_->DeleteBackward(deleteBackwardLength);
1282 EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
1283 EXPECT_NE(TextListener::deleteBackwardLength_, deleteBackwardLength);
1284
1285 std::string insertText = "t";
1286 ret = inputMethodAbility_->InsertText(insertText);
1287 EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
1288 EXPECT_NE(TextListener::insertText_, Str8ToStr16(insertText));
1289
1290 constexpr int32_t funcKey = 1;
1291 ret = inputMethodAbility_->SendFunctionKey(funcKey);
1292 EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
1293 EXPECT_NE(TextListener::key_, funcKey);
1294
1295 constexpr int32_t keyCode = 4;
1296 ret = inputMethodAbility_->MoveCursor(keyCode);
1297 EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
1298 EXPECT_NE(TextListener::direction_, keyCode);
1299 }
1300
1301 /**
1302 * @tc.name: testIsInputTypeSupported
1303 * @tc.desc: IsInputTypeSupported
1304 * @tc.type: FUNC
1305 * @tc.require:
1306 * @tc.author: chenyu
1307 */
1308 HWTEST_F(InputMethodControllerTest, testIsInputTypeSupported, TestSize.Level0)
1309 {
1310 IMSA_HILOGI("IMC testIsInputTypeSupported Test START");
1311 auto ret = inputMethodController_->IsInputTypeSupported(InputType::NONE);
1312 EXPECT_FALSE(ret);
1313 }
1314
1315 /**
1316 * @tc.name: testStartInputType
1317 * @tc.desc: StartInputType
1318 * @tc.type: FUNC
1319 * @tc.require:
1320 * @tc.author: chenyu
1321 */
1322 HWTEST_F(InputMethodControllerTest, testStartInputType, TestSize.Level0)
1323 {
1324 IMSA_HILOGI("IMC testStartInputType Test START");
1325 auto ret = inputMethodController_->StartInputType(InputType::NONE);
1326 EXPECT_NE(ret, ErrorCode::NO_ERROR);
1327 }
1328
1329 /**
1330 * @tc.name: testSendPrivateCommand_001
1331 * @tc.desc: IMC SendPrivateCommand without default ime
1332 * @tc.type: FUNC
1333 * @tc.require:
1334 * @tc.author: mashaoyin
1335 */
1336 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_001, TestSize.Level0)
1337 {
1338 IMSA_HILOGI("IMC testSendPrivateCommand_001 Test START");
1339 InputMethodEngineListenerImpl::ResetParam();
1340 auto ret = inputMethodController_->Attach(textListener_, false);
1341 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1342 std::unordered_map<std::string, PrivateDataValue> privateCommand;
1343 PrivateDataValue privateDataValue1 = std::string("stringValue");
1344 privateCommand.emplace("value1", privateDataValue1);
1345 IdentityCheckerMock::SetBundleNameValid(false);
1346 ret = inputMethodController_->SendPrivateCommand(privateCommand);
1347 EXPECT_EQ(ret, ErrorCode::ERROR_NOT_DEFAULT_IME);
1348 inputMethodController_->Close();
1349 IdentityCheckerMock::SetBundleNameValid(true);
1350 }
1351
1352 /**
1353 * @tc.name: testSendPrivateCommand_002
1354 * @tc.desc: SendPrivateCommand not bound, and empty privateCommand.
1355 * @tc.type: FUNC
1356 * @tc.require:
1357 * @tc.author: mashaoyin
1358 */
1359 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_002, TestSize.Level0)
1360 {
1361 IMSA_HILOGI("IMC testSendPrivateCommand_002 Test START");
1362 InputMethodEngineListenerImpl::ResetParam();
1363 IdentityCheckerMock::SetBundleNameValid(true);
1364 inputMethodController_->Close();
1365 std::unordered_map<std::string, PrivateDataValue> privateCommand;
1366 auto ret = inputMethodController_->SendPrivateCommand(privateCommand);
1367 EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_BOUND);
1368
1369 ret = inputMethodController_->Attach(textListener_, false);
1370 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1371 ret = inputMethodController_->SendPrivateCommand(privateCommand);
1372 EXPECT_EQ(ret, ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE);
1373 inputMethodController_->Close();
1374 IdentityCheckerMock::SetBundleNameValid(false);
1375 }
1376
1377 /**
1378 * @tc.name: testSendPrivateCommand_003
1379 * @tc.desc: IMC SendPrivateCommand with normal private command.
1380 * @tc.type: FUNC
1381 * @tc.require:
1382 * @tc.author: mashaoyin
1383 */
1384 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_003, TestSize.Level0)
1385 {
1386 IMSA_HILOGI("IMC testSendPrivateCommand_003 Test START");
1387 IdentityCheckerMock::SetBundleNameValid(true);
1388 InputMethodEngineListenerImpl::ResetParam();
1389 auto ret = inputMethodController_->Attach(textListener_, false);
1390 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1391 std::unordered_map<std::string, PrivateDataValue> privateCommand;
1392 PrivateDataValue privateDataValue1 = std::string("stringValue");
1393 privateCommand.emplace("value1", privateDataValue1);
1394 ret = inputMethodController_->SendPrivateCommand(privateCommand);
1395 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1396 inputMethodController_->Close();
1397 IdentityCheckerMock::SetBundleNameValid(false);
1398 }
1399
1400 /**
1401 * @tc.name: testSendPrivateCommand_004
1402 * @tc.desc: IMC SendPrivateCommand with correct data format and all data type.
1403 * @tc.type: FUNC
1404 * @tc.require:
1405 * @tc.author: mashaoyin
1406 */
1407 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_004, TestSize.Level0)
1408 {
1409 IMSA_HILOGI("IMC testSendPrivateCommand_004 Test START");
1410 IdentityCheckerMock::SetBundleNameValid(true);
1411 InputMethodEngineListenerImpl::ResetParam();
1412 auto ret = inputMethodController_->Attach(textListener_, false);
1413 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1414 std::unordered_map<std::string, PrivateDataValue> privateCommand;
1415 PrivateDataValue privateDataValue1 = std::string("stringValue");
1416 PrivateDataValue privateDataValue2 = true;
1417 PrivateDataValue privateDataValue3 = 100;
1418 privateCommand.emplace("value1", privateDataValue1);
1419 privateCommand.emplace("value2", privateDataValue2);
1420 privateCommand.emplace("value3", privateDataValue3);
1421 ret = inputMethodController_->SendPrivateCommand(privateCommand);
1422 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1423 EXPECT_TRUE(InputMethodEngineListenerImpl::WaitSendPrivateCommand(privateCommand));
1424 inputMethodController_->Close();
1425 IdentityCheckerMock::SetBundleNameValid(false);
1426 }
1427
1428 /**
1429 * @tc.name: testSendPrivateCommand_005
1430 * @tc.desc: IMC SendPrivateCommand with more than 5 private command.
1431 * @tc.type: FUNC
1432 * @tc.require:
1433 * @tc.author: mashaoyin
1434 */
1435 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_005, TestSize.Level0)
1436 {
1437 IMSA_HILOGI("IMC testSendPrivateCommand_005 Test START");
1438 IdentityCheckerMock::SetBundleNameValid(true);
1439 InputMethodEngineListenerImpl::ResetParam();
1440 auto ret = inputMethodController_->Attach(textListener_, false);
1441 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1442 std::unordered_map<std::string, PrivateDataValue> privateCommand;
1443 PrivateDataValue privateDataValue1 = std::string("stringValue");
1444 privateCommand.emplace("value1", privateDataValue1);
1445 privateCommand.emplace("value2", privateDataValue1);
1446 privateCommand.emplace("value3", privateDataValue1);
1447 privateCommand.emplace("value4", privateDataValue1);
1448 privateCommand.emplace("value5", privateDataValue1);
1449 privateCommand.emplace("value6", privateDataValue1);
1450 ret = inputMethodController_->SendPrivateCommand(privateCommand);
1451 EXPECT_EQ(ret, ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE);
1452 inputMethodController_->Close();
1453 IdentityCheckerMock::SetBundleNameValid(false);
1454 }
1455
1456 /**
1457 * @tc.name: testSendPrivateCommand_006
1458 * @tc.desc: IMC SendPrivateCommand size is more than 32KB.
1459 * @tc.type: FUNC
1460 * @tc.require:
1461 * @tc.author: mashaoyin
1462 */
1463 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_006, TestSize.Level0)
1464 {
1465 IMSA_HILOGI("IMC testSendPrivateCommand_006 Test START");
1466 IdentityCheckerMock::SetBundleNameValid(true);
1467 InputMethodEngineListenerImpl::ResetParam();
1468 std::unordered_map<std::string, PrivateDataValue> privateCommand;
1469 PrivateDataValue privateDataValue1 = std::string("stringValue");
1470 PrivateDataValue privateDataValue2 = true;
1471 PrivateDataValue privateDataValue3 = 100;
1472 privateCommand.emplace("value1", privateDataValue1);
1473 privateCommand.emplace("value2", privateDataValue2);
1474 privateCommand.emplace("value3", privateDataValue3);
1475 TextConfig textConfig;
1476 textConfig.privateCommand = privateCommand;
1477 textConfig.windowId = 1;
1478 auto ret = inputMethodController_->Attach(textListener_, false, textConfig);
1479 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1480 EXPECT_TRUE(InputMethodEngineListenerImpl::WaitSendPrivateCommand(privateCommand));
1481 inputMethodController_->Close();
1482 IdentityCheckerMock::SetBundleNameValid(false);
1483 }
1484
1485 /**
1486 * @tc.name: testSendPrivateCommand_007
1487 * @tc.desc: IMC SendPrivateCommand with Attach.
1488 * @tc.type: FUNC
1489 * @tc.require:
1490 * @tc.author: mashaoyin
1491 */
1492 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_007, TestSize.Level0)
1493 {
1494 IMSA_HILOGI("IMC testSendPrivateCommand_007 Test START");
1495 IdentityCheckerMock::SetBundleNameValid(true);
1496 TextListener::ResetParam();
1497 auto ret = inputMethodController_->Attach(textListener_, false);
1498 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1499 string str(32768, 'a');
1500 std::unordered_map<std::string, PrivateDataValue> privateCommand;
1501 PrivateDataValue privateDataValue1 = str;
1502 privateCommand.emplace("value1", privateDataValue1);
1503 ret = inputMethodController_->SendPrivateCommand(privateCommand);
1504 EXPECT_EQ(ret, ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE);
1505 inputMethodController_->Close();
1506 IdentityCheckerMock::SetBundleNameValid(false);
1507 }
1508
1509 /**
1510 * @tc.name: testSendPrivateCommand_008
1511 * @tc.desc: IMA SendPrivateCommand total size is 32KB, 32KB - 1, 32KB + 1.
1512 * @tc.type: IMC
1513 * @tc.require:
1514 * @tc.author: mashaoyin
1515 */
1516 HWTEST_F(InputMethodControllerTest, testSendPrivateCommand_008, TestSize.Level0)
1517 {
1518 IMSA_HILOGI("IMC testSendPrivateCommand_008 Test START");
1519 IdentityCheckerMock::SetBundleNameValid(true);
1520 auto ret = inputMethodController_->Attach(textListener_, false);
1521 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1522 TextListener::ResetParam();
1523 std::unordered_map<std::string, PrivateDataValue> privateCommand1{ { "v",
1524 string(PRIVATE_COMMAND_SIZE_MAX - 2, 'a') } };
1525 std::unordered_map<std::string, PrivateDataValue> privateCommand2{ { "v",
1526 string(PRIVATE_COMMAND_SIZE_MAX - 1, 'a') } };
1527 std::unordered_map<std::string, PrivateDataValue> privateCommand3{ { "v",
1528 string(PRIVATE_COMMAND_SIZE_MAX, 'a') } };
1529 ret = inputMethodController_->SendPrivateCommand(privateCommand1);
1530 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1531 ret = inputMethodController_->SendPrivateCommand(privateCommand2);
1532 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1533 ret = inputMethodController_->SendPrivateCommand(privateCommand3);
1534 EXPECT_EQ(ret, ErrorCode::ERROR_INVALID_PRIVATE_COMMAND_SIZE);
1535 inputMethodController_->Close();
1536 IdentityCheckerMock::SetBundleNameValid(false);
1537 }
1538
1539 /**
1540 * @tc.name: testFinishTextPreviewAfterDetach_001
1541 * @tc.desc: IMC testFinishTextPreviewAfterDetach.
1542 * @tc.type: IMC
1543 * @tc.require:
1544 * @tc.author: zhaolinglan
1545 */
1546 HWTEST_F(InputMethodControllerTest, testFinishTextPreviewAfterDetach_001, TestSize.Level0)
1547 {
1548 IMSA_HILOGI("IMC testFinishTextPreviewAfterDetach_001 Test START");
1549 InputAttribute inputAttribute = { .isTextPreviewSupported = true };
1550 inputMethodController_->Attach(textListener_, false, inputAttribute);
1551 TextListener::ResetParam();
1552 inputMethodController_->Close();
1553 EXPECT_TRUE(TextListener::isFinishTextPreviewCalled_);
1554 }
1555
1556 /**
1557 * @tc.name: testFinishTextPreviewAfterDetach_002
1558 * @tc.desc: IMC testFinishTextPreviewAfterDetach_002.
1559 * @tc.type: IMC
1560 * @tc.require:
1561 * @tc.author: zhaolinglan
1562 */
1563 HWTEST_F(InputMethodControllerTest, testFinishTextPreviewAfterDetach_002, TestSize.Level0)
1564 {
1565 IMSA_HILOGI("IMC testFinishTextPreviewAfterDetach_002 Test START");
1566 InputAttribute inputAttribute = { .isTextPreviewSupported = true };
1567 inputMethodController_->Attach(textListener_, false, inputAttribute);
1568 TextListener::ResetParam();
1569 inputMethodController_->DeactivateClient();
1570 EXPECT_FALSE(TextListener::isFinishTextPreviewCalled_);
1571 }
1572
1573 /**
1574 * @tc.name: testGetInputMethodState_001
1575 * @tc.desc: IMA
1576 * @tc.type: FUNC
1577 * @tc.require:
1578 */
1579 HWTEST_F(InputMethodControllerTest, testGetInputMethodState_001, TestSize.Level0)
1580 {
1581 IMSA_HILOGI("InputMethodControllerTest GetInputMethodState_001 Test START");
1582 EnabledStatus status = EnabledStatus::DISABLED;
1583 SecurityModeParser::GetInstance()->fullModeList_.push_back(TddUtil::currentBundleNameMock_);
1584 EnableImeDataParser::GetInstance()->enableList_[IME_KEY].push_back(TddUtil::currentBundleNameMock_);
1585 auto ret = inputMethodController_->GetInputMethodState(status);
1586 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1587 EXPECT_TRUE(status == EnabledStatus::FULL_EXPERIENCE_MODE);
1588 SecurityModeParser::GetInstance()->fullModeList_.clear();
1589 EnableImeDataParser::GetInstance()->enableList_.clear();
1590 }
1591
1592 /**
1593 * @tc.name: testGetInputMethodState_002
1594 * @tc.desc: IMA
1595 * @tc.type: FUNC
1596 * @tc.require:
1597 */
1598 HWTEST_F(InputMethodControllerTest, testGetInputMethodState_002, TestSize.Level0)
1599 {
1600 IMSA_HILOGI("InputMethodControllerTest GetInputMethodState_002 Test START");
1601 EnabledStatus status = EnabledStatus::DISABLED;
1602 ImeInfoInquirer::GetInstance().systemConfig_.enableFullExperienceFeature = true;
1603 ImeInfoInquirer::GetInstance().systemConfig_.enableInputMethodFeature = true;
1604 EnableImeDataParser::GetInstance()->enableList_.clear();
1605 SecurityModeParser::GetInstance()->fullModeList_.clear();
1606 auto ret = inputMethodController_->GetInputMethodState(status);
1607 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1608 EXPECT_TRUE(status != EnabledStatus::FULL_EXPERIENCE_MODE);
1609 ImeInfoInquirer::GetInstance().systemConfig_.enableFullExperienceFeature = false;
1610 ImeInfoInquirer::GetInstance().systemConfig_.enableInputMethodFeature = false;
1611 }
1612
1613 /**
1614 * @tc.name: testGetInputMethodState_003
1615 * @tc.desc: IMA
1616 * @tc.type: FUNC
1617 * @tc.require:
1618 */
1619 HWTEST_F(InputMethodControllerTest, testGetInputMethodState_003, TestSize.Level0)
1620 {
1621 IMSA_HILOGI("InputMethodControllerTest GetInputMethodState_003 Test START");
1622 EnabledStatus status = EnabledStatus::DISABLED;
1623 ImeInfoInquirer::GetInstance().systemConfig_.enableFullExperienceFeature = true;
1624 ImeInfoInquirer::GetInstance().systemConfig_.enableInputMethodFeature = true;
1625 EnableImeDataParser::GetInstance()->enableList_[IME_KEY].push_back(TddUtil::currentBundleNameMock_);
1626 auto ret = inputMethodController_->GetInputMethodState(status);
1627 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1628 EXPECT_TRUE(status == EnabledStatus::BASIC_MODE);
1629 ImeInfoInquirer::GetInstance().systemConfig_.enableFullExperienceFeature = false;
1630 ImeInfoInquirer::GetInstance().systemConfig_.enableInputMethodFeature = false;
1631 EnableImeDataParser::GetInstance()->enableList_.clear();
1632 }
1633
1634 /**
1635 * @tc.name: testGetInputMethodState_004
1636 * @tc.desc: IMA
1637 * @tc.type: FUNC
1638 * @tc.require:
1639 */
1640 HWTEST_F(InputMethodControllerTest, testGetInputMethodState_004, TestSize.Level0)
1641 {
1642 IMSA_HILOGI("InputMethodControllerTest GetInputMethodState_004 Test START");
1643 EnabledStatus status = EnabledStatus::DISABLED;
1644 ImeInfoInquirer::GetInstance().systemConfig_.enableFullExperienceFeature = true;
1645 ImeInfoInquirer::GetInstance().systemConfig_.enableInputMethodFeature = false;
1646 auto ret = inputMethodController_->GetInputMethodState(status);
1647 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1648 EXPECT_TRUE(status == EnabledStatus::BASIC_MODE);
1649 ImeInfoInquirer::GetInstance().systemConfig_.enableFullExperienceFeature = false;
1650 }
1651
1652 /**
1653 * @tc.name: testGetInputMethodState_005
1654 * @tc.desc: IMA
1655 * @tc.type: FUNC
1656 * @tc.require:
1657 */
1658 HWTEST_F(InputMethodControllerTest, testGetInputMethodState_005, TestSize.Level0)
1659 {
1660 IMSA_HILOGI("InputMethodControllerTest GetInputMethodState_005 Test START");
1661 EnabledStatus status = EnabledStatus::DISABLED;
1662 ImeInfoInquirer::GetInstance().systemConfig_.enableFullExperienceFeature = false;
1663 ImeInfoInquirer::GetInstance().systemConfig_.enableInputMethodFeature = false;
1664 auto ret = inputMethodController_->GetInputMethodState(status);
1665 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1666 EXPECT_TRUE(status == EnabledStatus::FULL_EXPERIENCE_MODE);
1667 }
1668
1669 /**
1670 * @tc.name: testOnInputReady
1671 * @tc.desc: IMC testOnInputReady
1672 * @tc.type: IMC
1673 * @tc.require:
1674 */
1675 HWTEST_F(InputMethodControllerTest, testOnInputReady, TestSize.Level0)
1676 {
1677 IMSA_HILOGI("IMC OnInputReady Test START");
1678 InputAttribute inputAttribute = { .isTextPreviewSupported = true };
1679 inputMethodController_->Attach(textListener_, false, inputAttribute);
1680 sptr<IRemoteObject> agentObject = nullptr;
1681 inputMethodController_->OnInputReady(agentObject);
1682 TextListener::ResetParam();
1683 inputMethodController_->DeactivateClient();
1684 EXPECT_FALSE(TextListener::isFinishTextPreviewCalled_);
1685 }
1686 } // namespace MiscServices
1687 } // namespace OHOS