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_ability.h"
18 
19 #include "input_method_controller.h"
20 #include "input_method_system_ability.h"
21 #undef private
22 
23 #include <gtest/gtest.h>
24 #include <string_ex.h>
25 #include <unistd.h>
26 
27 #include <cstdint>
28 #include <functional>
29 #include <string>
30 #include <thread>
31 #include <vector>
32 
33 #include "global.h"
34 #include "i_input_data_channel.h"
35 #include "identity_checker_mock.h"
36 #include "input_attribute.h"
37 #include "input_control_channel_stub.h"
38 #include "input_data_channel_proxy.h"
39 #include "input_data_channel_stub.h"
40 #include "input_method_agent_stub.h"
41 #include "input_method_core_proxy.h"
42 #include "input_method_core_stub.h"
43 #include "input_method_panel.h"
44 #include "input_method_system_ability_proxy.h"
45 #include "message_handler.h"
46 #include "scope_utils.h"
47 #include "tdd_util.h"
48 #include "text_listener.h"
49 
50 using namespace testing::ext;
51 namespace OHOS {
52 namespace MiscServices {
53 constexpr uint32_t DEALY_TIME = 1;
54 class InputMethodAbilityTest : public testing::Test {
55 public:
56     static std::mutex imeListenerCallbackLock_;
57     static std::condition_variable imeListenerCv_;
58     static bool showKeyboard_;
59     static constexpr int CURSOR_DIRECTION_BASE_VALUE = 2011;
60     static sptr<InputMethodController> imc_;
61     static sptr<OnTextChangedListener> textListener_;
62     static sptr<InputMethodAbility> inputMethodAbility_;
63     static uint32_t windowId_;
64     static int32_t security_;
65     static uint64_t currentImeTokenId_;
66     static int32_t currentImeUid_;
67     static sptr<InputMethodSystemAbility> imsa_;
68     static sptr<InputMethodSystemAbilityProxy> imsaProxy_;
69 
70     class InputMethodEngineListenerImpl : public InputMethodEngineListener {
71     public:
72         InputMethodEngineListenerImpl() = default;
73         ~InputMethodEngineListenerImpl() = default;
74 
OnKeyboardStatus(bool isShow)75         void OnKeyboardStatus(bool isShow)
76         {
77             showKeyboard_ = isShow;
78             InputMethodAbilityTest::imeListenerCv_.notify_one();
79             IMSA_HILOGI("InputMethodEngineListenerImpl OnKeyboardStatus");
80         }
81 
OnInputStart()82         void OnInputStart()
83         {
84             IMSA_HILOGI("InputMethodEngineListenerImpl OnInputStart");
85         }
86 
OnInputStop()87         int32_t OnInputStop()
88         {
89             IMSA_HILOGI("InputMethodEngineListenerImpl OnInputStop");
90             return ErrorCode::NO_ERROR;
91         }
92 
OnSetCallingWindow(uint32_t windowId)93         void OnSetCallingWindow(uint32_t windowId)
94         {
95             windowId_ = windowId;
96             IMSA_HILOGI("InputMethodEngineListenerImpl OnSetCallingWindow");
97         }
98 
OnSetSubtype(const SubProperty & property)99         void OnSetSubtype(const SubProperty &property)
100         {
101             IMSA_HILOGI("InputMethodEngineListenerImpl OnSetSubtype");
102         }
103 
OnSecurityChange(int32_t security)104         void OnSecurityChange(int32_t security)
105         {
106             security_ = security;
107             IMSA_HILOGI("InputMethodEngineListenerImpl OnSecurityChange");
108         }
109 
ReceivePrivateCommand(const std::unordered_map<std::string,PrivateDataValue> & privateCommand)110         void ReceivePrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
111         {
112             IMSA_HILOGI("InputMethodEngineListenerImpl ReceivePrivateCommand");
113         }
114     };
115 
SetUpTestCase(void)116     static void SetUpTestCase(void)
117     {
118         IdentityCheckerMock::ResetParam();
119         // Set the tokenID to the tokenID of the current ime
120         TddUtil::StorageSelfTokenID();
121         imsa_ = new (std::nothrow) InputMethodSystemAbility();
122         if (imsa_ == nullptr) {
123             return;
124         }
125         imsa_->OnStart();
126         imsa_->userId_ = TddUtil::GetCurrentUserId();
127         imsa_->identityChecker_ = std::make_shared<IdentityCheckerMock>();
128         sptr<InputMethodSystemAbilityStub> serviceStub = imsa_;
129         imsaProxy_ = new (std::nothrow) InputMethodSystemAbilityProxy(serviceStub->AsObject());
130         if (imsaProxy_ == nullptr) {
131             return;
132         }
133         IdentityCheckerMock::SetFocused(true);
134 
135         std::shared_ptr<Property> property = InputMethodController::GetInstance()->GetCurrentInputMethod();
136         auto currentIme = property != nullptr ? property->name : "default.inputmethod.unittest";
137         currentImeTokenId_ = TddUtil::GetTestTokenID(currentIme);
138         currentImeUid_ = TddUtil::GetUid(currentIme);
139 
140         inputMethodAbility_ = InputMethodAbility::GetInstance();
141         inputMethodAbility_->abilityManager_ = imsaProxy_;
142         TddUtil::InitCurrentImePermissionInfo();
143         IdentityCheckerMock::SetBundleName(TddUtil::currentBundleNameMock_);
144         inputMethodAbility_->SetCoreAndAgent();
145 
146         TextListener::ResetParam();
147         imc_ = InputMethodController::GetInstance();
148         imc_->abilityManager_ = imsaProxy_;
149         textListener_ = new TextListener();
150     }
TearDownTestCase(void)151     static void TearDownTestCase(void)
152     {
153         IMSA_HILOGI("InputMethodAbilityTest::TearDownTestCase");
154         imc_->Close();
155         TextListener::ResetParam();
156         TddUtil::RestoreSelfTokenID();
157         IdentityCheckerMock::ResetParam();
158         imsa_->OnStop();
159     }
GetIMCAttachIMA()160     static void GetIMCAttachIMA()
161     {
162         imc_->SetTextListener(textListener_);
163         imc_->clientInfo_.state = ClientState::ACTIVE;
164         imc_->isBound_.store(true);
165         imc_->isEditable_.store(true);
166         auto agent = inputMethodAbility_->agentStub_->AsObject();
167         imc_->SetAgent(agent);
168 
169         sptr<IInputDataChannel> channel = iface_cast<IInputDataChannel>(imc_->clientInfo_.channel);
170         inputMethodAbility_->SetInputDataChannel(channel->AsObject());
171         IMSA_HILOGI("end");
172     }
GetIMCDetachIMA()173     static void GetIMCDetachIMA()
174     {
175         imc_->OnInputStop();
176         inputMethodAbility_->ClearDataChannel(inputMethodAbility_->dataChannelObject_);
177         IMSA_HILOGI("end");
178     }
SetUp()179     void SetUp()
180     {
181         IMSA_HILOGI("InputMethodAbilityTest::SetUp");
182         TextListener::ResetParam();
183     }
TearDown()184     void TearDown()
185     {
186         IMSA_HILOGI("InputMethodAbilityTest::TearDown");
187     }
CheckPanelStatusInfo(const std::shared_ptr<InputMethodPanel> & panel,const PanelStatusInfo & info)188     void CheckPanelStatusInfo(const std::shared_ptr<InputMethodPanel> &panel, const PanelStatusInfo &info)
189     {
190         TextListener::ResetParam();
191         info.visible ? CheckPanelInfoInShow(panel, info) : CheckPanelInfoInHide(panel, info);
192     }
CheckPanelInfoInShow(const std::shared_ptr<InputMethodPanel> & panel,const PanelStatusInfo & info)193     void CheckPanelInfoInShow(const std::shared_ptr<InputMethodPanel> &panel, const PanelStatusInfo &info)
194     {
195         auto ret = inputMethodAbility_->ShowPanel(panel);
196         EXPECT_EQ(ret, ErrorCode::NO_ERROR);
197         if (info.panelInfo.panelFlag != FLG_CANDIDATE_COLUMN) {
198             if (info.panelInfo.panelType == SOFT_KEYBOARD) {
199                 EXPECT_TRUE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::SHOW));
200             } else {
201                 EXPECT_FALSE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::SHOW));
202             }
203             EXPECT_TRUE(TextListener::WaitNotifyPanelStatusInfoCallback(
204                 { { info.panelInfo.panelType, info.panelInfo.panelFlag }, info.visible, info.trigger }));
205             return;
206         }
207         EXPECT_FALSE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::SHOW));
208         EXPECT_FALSE(TextListener::WaitNotifyPanelStatusInfoCallback(
209             { { info.panelInfo.panelType, info.panelInfo.panelFlag }, info.visible, info.trigger }));
210     }
CheckPanelInfoInHide(const std::shared_ptr<InputMethodPanel> & panel,const PanelStatusInfo & info)211     void CheckPanelInfoInHide(const std::shared_ptr<InputMethodPanel> &panel, const PanelStatusInfo &info)
212     {
213         AccessScope scope(currentImeTokenId_, currentImeUid_);
214         auto ret = inputMethodAbility_->HidePanel(panel);
215         EXPECT_EQ(ret, ErrorCode::NO_ERROR);
216         if (info.panelInfo.panelFlag != FLG_CANDIDATE_COLUMN) {
217             if (info.panelInfo.panelType == SOFT_KEYBOARD) {
218                 EXPECT_TRUE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::HIDE));
219             } else {
220                 EXPECT_FALSE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::HIDE));
221             };
222             EXPECT_TRUE(TextListener::WaitNotifyPanelStatusInfoCallback(
223                 { { info.panelInfo.panelType, info.panelInfo.panelFlag }, info.visible, info.trigger }));
224             return;
225         }
226         EXPECT_FALSE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::HIDE));
227         EXPECT_FALSE(TextListener::WaitNotifyPanelStatusInfoCallback(
228             { { info.panelInfo.panelType, info.panelInfo.panelFlag }, info.visible, info.trigger }));
229     }
230 };
231 
232 std::mutex InputMethodAbilityTest::imeListenerCallbackLock_;
233 std::condition_variable InputMethodAbilityTest::imeListenerCv_;
234 bool InputMethodAbilityTest::showKeyboard_ = true;
235 sptr<InputMethodController> InputMethodAbilityTest::imc_;
236 sptr<OnTextChangedListener> InputMethodAbilityTest::textListener_;
237 sptr<InputMethodAbility> InputMethodAbilityTest::inputMethodAbility_;
238 uint32_t InputMethodAbilityTest::windowId_ = 0;
239 int32_t InputMethodAbilityTest::security_ = -1;
240 uint64_t InputMethodAbilityTest::currentImeTokenId_ = 0;
241 int32_t InputMethodAbilityTest::currentImeUid_ = 0;
242 sptr<InputMethodSystemAbility> InputMethodAbilityTest::imsa_;
243 sptr<InputMethodSystemAbilityProxy> InputMethodAbilityTest::imsaProxy_;
244 
245 /**
246 * @tc.name: testSerializedInputAttribute
247 * @tc.desc: Checkout the serialization of InputAttribute.
248 * @tc.type: FUNC
249 */
250 HWTEST_F(InputMethodAbilityTest, testSerializedInputAttribute, TestSize.Level0)
251 {
252     InputAttribute inAttribute;
253     inAttribute.inputPattern = InputAttribute::PATTERN_PASSWORD;
254     MessageParcel data;
255     EXPECT_TRUE(InputAttribute::Marshalling(inAttribute, data));
256     InputAttribute outAttribute;
257     EXPECT_TRUE(InputAttribute::Unmarshalling(outAttribute, data));
258     EXPECT_TRUE(outAttribute.GetSecurityFlag());
259 }
260 
261 /**
262  * @tc.name: testSerializedInputAttribute
263  * @tc.desc: Checkout the serialization of InputAttribute.
264  * @tc.type: FUNC
265  */
266 HWTEST_F(InputMethodAbilityTest, testSerializedInputAttribute_WithSpecificBundleName, TestSize.Level0)
267 {
268     InputAttribute inAttribute;
269     inAttribute.bundleName = "com.example.inputmethod";
270     MessageParcel data;
271     EXPECT_TRUE(InputAttribute::Marshalling(inAttribute, data));
272     InputAttribute outAttribute;
273     EXPECT_TRUE(InputAttribute::Unmarshalling(outAttribute, data));
274     EXPECT_EQ(inAttribute.bundleName, outAttribute.bundleName);
275 }
276 
277 /**
278 * @tc.name: testShowKeyboardInputMethodCoreProxy
279 * @tc.desc: Test InputMethodCoreProxy ShowKeyboard
280 * @tc.type: FUNC
281 * @tc.require: issueI5NXHK
282 */
283 HWTEST_F(InputMethodAbilityTest, testShowKeyboardInputMethodCoreProxy, TestSize.Level0)
284 {
285     IMSA_HILOGI("testShowKeyboardInputMethodCoreProxy start.");
286     sptr<InputMethodCoreStub> coreStub = new InputMethodCoreStub();
287     sptr<IInputMethodCore> core = coreStub;
288     auto msgHandler = new (std::nothrow) MessageHandler();
289     coreStub->SetMessageHandler(msgHandler);
290     sptr<InputDataChannelStub> channelStub = new InputDataChannelStub();
291 
292     MessageParcel data;
293     data.WriteRemoteObject(core->AsObject());
294     data.WriteRemoteObject(channelStub->AsObject());
295     sptr<IRemoteObject> coreObject = data.ReadRemoteObject();
296     sptr<IRemoteObject> channelObject = data.ReadRemoteObject();
297 
298     sptr<InputMethodCoreProxy> coreProxy = new InputMethodCoreProxy(coreObject);
299     sptr<InputDataChannelProxy> channelProxy = new InputDataChannelProxy(channelObject);
300     auto ret = coreProxy->ShowKeyboard();
301     EXPECT_EQ(ret, ErrorCode::ERROR_IME);
302     delete msgHandler;
303 }
304 
305 /**
306 * @tc.name: testShowKeyboardWithoutImeListener
307 * @tc.desc: InputMethodAbility ShowKeyboard without imeListener
308 * @tc.type: FUNC
309 * @tc.require:
310 */
311 HWTEST_F(InputMethodAbilityTest, testShowKeyboardWithoutImeListener, TestSize.Level0)
312 {
313     IMSA_HILOGI("InputMethodAbilityTest testShowKeyboardWithoutImeListener start.");
314     auto ret = inputMethodAbility_->ShowKeyboard();
315     EXPECT_EQ(ret, ErrorCode::ERROR_IME);
316 }
317 
318 /**
319 * @tc.name: testHideKeyboardWithoutImeListener
320 * @tc.desc: InputMethodAbility HideKeyboard without imeListener
321 * @tc.type: FUNC
322 * @tc.require:
323 */
324 HWTEST_F(InputMethodAbilityTest, testHideKeyboardWithoutImeListener, TestSize.Level0)
325 {
326     IMSA_HILOGI("InputMethodAbilityTest testHideKeyboardWithoutImeListener start.");
327     auto ret = inputMethodAbility_->HideKeyboard();
328     EXPECT_EQ(ret, ErrorCode::ERROR_IME);
329 }
330 
331 /**
332 * @tc.name: testStartInputWithoutPanel
333 * @tc.desc: InputMethodAbility StartInput Without Panel
334 * @tc.type: FUNC
335 * @tc.require:
336 */
337 HWTEST_F(InputMethodAbilityTest, testStartInputWithoutPanel, TestSize.Level0)
338 {
339     IMSA_HILOGI("InputMethodAbilityTest testStartInputWithoutAttach start.");
340     inputMethodAbility_->SetImeListener(std::make_shared<InputMethodEngineListenerImpl>());
341     sptr<InputDataChannelStub> channelStub = new InputDataChannelStub();
342     InputClientInfo clientInfo;
343     clientInfo.channel = channelStub;
344     auto ret = inputMethodAbility_->StartInput(clientInfo, false);
345     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
346     clientInfo.isShowKeyboard = true;
347     ret = inputMethodAbility_->StartInput(clientInfo, false);
348     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
349 }
350 
351 /**
352 * @tc.name: testHideKeyboardSelf
353 * @tc.desc: InputMethodAbility HideKeyboardSelf
354 * @tc.type: FUNC
355 * @tc.require:
356 * @tc.author: Hollokin
357 */
358 HWTEST_F(InputMethodAbilityTest, testHideKeyboardSelf, TestSize.Level0)
359 {
360     IMSA_HILOGI("InputMethodAbility testHideKeyboardSelf START");
361     imc_->Attach(textListener_);
362     std::unique_lock<std::mutex> lock(InputMethodAbilityTest::imeListenerCallbackLock_);
363     InputMethodAbilityTest::showKeyboard_ = true;
364     inputMethodAbility_->SetImeListener(std::make_shared<InputMethodEngineListenerImpl>());
365     auto ret = inputMethodAbility_->HideKeyboardSelf();
366     InputMethodAbilityTest::imeListenerCv_.wait_for(
__anon3abd9da90102null367         lock, std::chrono::seconds(DEALY_TIME), [] { return InputMethodAbilityTest::showKeyboard_ == false; });
368     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
369     EXPECT_FALSE(InputMethodAbilityTest::showKeyboard_);
370 }
371 
372 /**
373 * @tc.name: testMoveCursor
374 * @tc.desc: InputMethodAbility MoveCursor
375 * @tc.type: FUNC
376 * @tc.require:
377 * @tc.author: Hollokin
378 */
379 HWTEST_F(InputMethodAbilityTest, testMoveCursor, TestSize.Level0)
380 {
381     IMSA_HILOGI("InputMethodAbility MoveCursor Test START");
382     constexpr int32_t keyCode = 4;
383     auto ret = inputMethodAbility_->MoveCursor(keyCode); // move cursor right });
384     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
385     EXPECT_TRUE(TextListener::WaitMoveCursor(keyCode));
386 }
387 
388 /**
389 * @tc.name: testInsertText
390 * @tc.desc: InputMethodAbility InsertText
391 * @tc.type: FUNC
392 * @tc.require:
393 * @tc.author: Hollokin
394 */
395 HWTEST_F(InputMethodAbilityTest, testInsertText, TestSize.Level0)
396 {
397     IMSA_HILOGI("InputMethodAbility InsertText Test START");
398     std::string text = "text";
399     std::u16string u16Text = Str8ToStr16(text);
400     auto ret = inputMethodAbility_->InsertText(text);
401     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
402     EXPECT_TRUE(TextListener::WaitInsertText(u16Text));
403 }
404 
405 /**
406 * @tc.name: testSendFunctionKey
407 * @tc.desc: InputMethodAbility SendFunctionKey
408 * @tc.type: FUNC
409 * @tc.require:
410 * @tc.author: Hollokin
411 */
412 HWTEST_F(InputMethodAbilityTest, testSendFunctionKey, TestSize.Level0)
413 {
414     IMSA_HILOGI("InputMethodAbility SendFunctionKey Test START");
415     constexpr int32_t funcKey = 1;
416     auto ret = inputMethodAbility_->SendFunctionKey(funcKey);
417     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
418     EXPECT_TRUE(TextListener::WaitSendFunctionKey(funcKey));
419 }
420 
421 /**
422 * @tc.name: testSendExtendAction
423 * @tc.desc: InputMethodAbility SendExtendAction
424 * @tc.type: FUNC
425 * @tc.require:
426 * @tc.author: chenyu
427 */
428 HWTEST_F(InputMethodAbilityTest, testSendExtendAction, TestSize.Level0)
429 {
430     IMSA_HILOGI("InputMethodAbility SendExtendAction Test START");
431     constexpr int32_t action = 1;
432     auto ret = inputMethodAbility_->SendExtendAction(action);
433     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
434     EXPECT_TRUE(TextListener::WaitHandleExtendAction(action));
435 }
436 
437 /**
438 * @tc.name: testDeleteText
439 * @tc.desc: InputMethodAbility DeleteForward & DeleteBackward
440 * @tc.type: FUNC
441 * @tc.require:
442 * @tc.author: Hollokin
443 */
444 HWTEST_F(InputMethodAbilityTest, testDeleteText, TestSize.Level0)
445 {
446     IMSA_HILOGI("InputMethodAbility testDelete Test START");
447     int32_t deleteForwardLenth = 1;
448     auto ret = inputMethodAbility_->DeleteForward(deleteForwardLenth);
449     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
450     EXPECT_TRUE(TextListener::WaitDeleteBackward(deleteForwardLenth));
451 
452     int32_t deleteBackwardLenth = 2;
453     ret = inputMethodAbility_->DeleteBackward(deleteBackwardLenth);
454     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
455     EXPECT_TRUE(TextListener::WaitDeleteForward(deleteBackwardLenth));
456 }
457 
458 /**
459 * @tc.name: testGetEnterKeyType
460 * @tc.desc: InputMethodAbility GetEnterKeyType & GetInputPattern
461 * @tc.type: FUNC
462 * @tc.require:
463 * @tc.author: Hollokin
464 */
465 HWTEST_F(InputMethodAbilityTest, testGetEnterKeyType, TestSize.Level0)
466 {
467     IMSA_HILOGI("InputMethodAbility testGetEnterKeyType START");
468     Configuration config;
469     EnterKeyType keyType = EnterKeyType::NEXT;
470     config.SetEnterKeyType(keyType);
471     TextInputType textInputType = TextInputType::DATETIME;
472     config.SetTextInputType(textInputType);
473     imc_->OnConfigurationChange(config);
474     int32_t keyType2;
475     auto ret = inputMethodAbility_->GetEnterKeyType(keyType2);
476     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
477     EXPECT_EQ(keyType2, (int)keyType);
478     int32_t inputPattern;
479     ret = inputMethodAbility_->GetInputPattern(inputPattern);
480     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
481     EXPECT_EQ(inputPattern, (int)textInputType);
482 }
483 
484 /**
485 * @tc.name: testGetTextConfig
486 * @tc.desc: InputMethodAbility GetTextConfig
487 * @tc.type: FUNC
488 * @tc.require:
489 * @tc.author: Hollokin
490 */
491 HWTEST_F(InputMethodAbilityTest, testGetTextConfig, TestSize.Level0)
492 {
493     IMSA_HILOGI("InputMethodAbility testGetTextConfig START");
494     TextConfig textConfig;
495     textConfig.inputAttribute = { .inputPattern = 0, .enterKeyType = 1 };
496     auto ret = imc_->Attach(textListener_, false, textConfig);
497     TextTotalConfig textTotalConfig;
498     ret = inputMethodAbility_->GetTextConfig(textTotalConfig);
499     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
500     EXPECT_EQ(textTotalConfig.inputAttribute.inputPattern, textConfig.inputAttribute.inputPattern);
501     EXPECT_EQ(textTotalConfig.inputAttribute.enterKeyType, textConfig.inputAttribute.enterKeyType);
502 }
503 
504 /**
505 * @tc.name: testSelectByRange_001
506 * @tc.desc: InputMethodAbility SelectByRange
507 * @tc.type: FUNC
508 * @tc.require:
509 * @tc.author: Zhaolinglan
510 */
511 HWTEST_F(InputMethodAbilityTest, testSelectByRange_001, TestSize.Level0)
512 {
513     IMSA_HILOGI("InputMethodAbility testSelectByRange_001 START");
514     constexpr int32_t start = 1;
515     constexpr int32_t end = 2;
516     auto ret = inputMethodAbility_->SelectByRange(start, end);
517     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
518     EXPECT_TRUE(TextListener::WaitHandleSetSelection(start, end));
519 }
520 
521 /**
522 * @tc.name: testSelectByRange_002
523 * @tc.desc: InputMethodAbility SelectByRange
524 * @tc.type: FUNC
525 * @tc.require:
526 * @tc.author: chenyu
527 */
528 HWTEST_F(InputMethodAbilityTest, testSelectByRange_002, TestSize.Level0)
529 {
530     IMSA_HILOGI("InputMethodAbility testSelectByRange_002 START");
531     int32_t start = -2;
532     int32_t end = 2;
533     auto ret = inputMethodAbility_->SelectByRange(start, end);
534     EXPECT_EQ(ret, ErrorCode::ERROR_PARAMETER_CHECK_FAILED);
535 
536     start = 2;
537     end = -2;
538     ret = inputMethodAbility_->SelectByRange(start, end);
539     EXPECT_EQ(ret, ErrorCode::ERROR_PARAMETER_CHECK_FAILED);
540 }
541 
542 /**
543 * @tc.name: testSelectByMovement
544 * @tc.desc: InputMethodAbility SelectByMovement
545 * @tc.type: FUNC
546 * @tc.require:
547 * @tc.author: Zhaolinglan
548 */
549 HWTEST_F(InputMethodAbilityTest, testSelectByMovement, TestSize.Level0)
550 {
551     IMSA_HILOGI("InputMethodAbility testSelectByMovement START");
552     constexpr int32_t direction = 1;
553     auto ret = inputMethodAbility_->SelectByMovement(direction);
554     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
555     EXPECT_TRUE(TextListener::WaitHandleSelect(direction + InputMethodAbilityTest::CURSOR_DIRECTION_BASE_VALUE, 0));
556 }
557 
558 /**
559 * @tc.name: testGetTextAfterCursor
560 * @tc.desc:
561 * @tc.type: FUNC
562 * @tc.require:
563 */
564 HWTEST_F(InputMethodAbilityTest, testGetTextAfterCursor, TestSize.Level0)
565 {
566     IMSA_HILOGI("InputMethodAbility testGetTextAfterCursor START");
567     int32_t number = 3;
568     std::u16string text;
569     auto ret = inputMethodAbility_->GetTextAfterCursor(number, text);
570     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
571     EXPECT_EQ(text, Str8ToStr16(TextListener::TEXT_AFTER_CURSOR));
572 }
573 
574 /**
575 * @tc.name: testGetTextBeforeCursor
576 * @tc.desc:
577 * @tc.type: FUNC
578 * @tc.require:
579 */
580 HWTEST_F(InputMethodAbilityTest, testGetTextBeforeCursor, TestSize.Level0)
581 {
582     IMSA_HILOGI("InputMethodAbility testGetTextBeforeCursor START");
583     int32_t number = 5;
584     std::u16string text;
585     auto ret = inputMethodAbility_->GetTextBeforeCursor(number, text);
586     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
587     EXPECT_EQ(text, Str8ToStr16(TextListener::TEXT_BEFORE_CURSOR));
588 }
589 
590 /**
591 * @tc.name: testGetTextIndexAtCursor
592 * @tc.desc:
593 * @tc.type: FUNC
594 * @tc.require:
595 */
596 HWTEST_F(InputMethodAbilityTest, testGetTextIndexAtCursor, TestSize.Level0)
597 {
598     IMSA_HILOGI("InputMethodAbility testGetTextIndexAtCursor START");
599     int32_t index;
600     auto ret = inputMethodAbility_->GetTextIndexAtCursor(index);
601     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
602     EXPECT_EQ(index, TextListener::TEXT_INDEX);
603 }
604 
605 /**
606 * @tc.name: testCreatePanel001
607 * @tc.desc: It's allowed to create one SOFT_KEYBOARD panel, but two is denied.
608 * @tc.type: FUNC
609 * @tc.require:
610 */
611 HWTEST_F(InputMethodAbilityTest, testCreatePanel001, TestSize.Level0)
612 {
613     IMSA_HILOGI("InputMethodAbilityTest testCreatePanel001 START. You can not create two SOFT_KEYBOARD panel.");
614     AccessScope scope(currentImeTokenId_, currentImeUid_);
615     std::shared_ptr<InputMethodPanel> softKeyboardPanel1 = nullptr;
616     PanelInfo panelInfo = { .panelType = SOFT_KEYBOARD, .panelFlag = FLG_FIXED };
617     auto ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo, softKeyboardPanel1);
618     EXPECT_TRUE(softKeyboardPanel1 != nullptr);
619     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
620 
621     std::shared_ptr<InputMethodPanel> softKeyboardPanel2 = nullptr;
622     ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo, softKeyboardPanel2);
623     EXPECT_TRUE(softKeyboardPanel2 == nullptr);
624     EXPECT_EQ(ret, ErrorCode::ERROR_OPERATE_PANEL);
625 
626     ret = inputMethodAbility_->DestroyPanel(softKeyboardPanel1);
627     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
628 
629     ret = inputMethodAbility_->DestroyPanel(softKeyboardPanel2);
630     EXPECT_EQ(ret, ErrorCode::ERROR_BAD_PARAMETERS);
631 }
632 
633 /**
634 * @tc.name: testCreatePanel002
635 * @tc.desc: It's allowed to create one STATUS_BAR panel, but two is denied.
636 * @tc.type: FUNC
637 * @tc.require:
638 */
639 HWTEST_F(InputMethodAbilityTest, testCreatePanel002, TestSize.Level0)
640 {
641     IMSA_HILOGI("InputMethodAbilityTest testCreatePanel002 START. You can not create two STATUS_BAR panel.");
642     AccessScope scope(currentImeTokenId_, currentImeUid_);
643     std::shared_ptr<InputMethodPanel> statusBar1 = nullptr;
644     PanelInfo panelInfo = { .panelType = STATUS_BAR };
645     auto ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo, statusBar1);
646     EXPECT_TRUE(statusBar1 != nullptr);
647     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
648 
649     std::shared_ptr<InputMethodPanel> statusBar2 = nullptr;
650     ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo, statusBar2);
651     EXPECT_TRUE(statusBar2 == nullptr);
652     EXPECT_EQ(ret, ErrorCode::ERROR_OPERATE_PANEL);
653 
654     ret = inputMethodAbility_->DestroyPanel(statusBar1);
655     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
656 
657     ret = inputMethodAbility_->DestroyPanel(statusBar2);
658     EXPECT_EQ(ret, ErrorCode::ERROR_BAD_PARAMETERS);
659 }
660 
661 /**
662 * @tc.name: testCreatePanel003
663 * @tc.desc: It's allowed to create one STATUS_BAR panel and one SOFT_KEYBOARD panel.
664 * @tc.type: FUNC
665 * @tc.require:
666 */
667 HWTEST_F(InputMethodAbilityTest, testCreatePanel003, TestSize.Level0)
668 {
669     IMSA_HILOGI("InputMethodAbilityTest testCreatePanel006 START. Allowed to create one SOFT_KEYBOARD panel and "
670                 "one STATUS_BAR panel.");
671     AccessScope scope(currentImeTokenId_, currentImeUid_);
672     std::shared_ptr<InputMethodPanel> softKeyboardPanel = nullptr;
673     PanelInfo panelInfo1 = { .panelType = SOFT_KEYBOARD, .panelFlag = FLG_FIXED };
674     auto ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo1, softKeyboardPanel);
675     EXPECT_TRUE(softKeyboardPanel != nullptr);
676     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
677 
678     PanelInfo panelInfo2 = { .panelType = STATUS_BAR };
679     std::shared_ptr<InputMethodPanel> statusBar = nullptr;
680     ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo2, statusBar);
681     EXPECT_TRUE(statusBar != nullptr);
682     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
683 
684     ret = inputMethodAbility_->DestroyPanel(softKeyboardPanel);
685     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
686 
687     ret = inputMethodAbility_->DestroyPanel(statusBar);
688     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
689 }
690 
691 /**
692 * @tc.name: testCreatePanel004
693 * @tc.desc: It's allowed to create one STATUS_BAR panel and one SOFT_KEYBOARD panel.
694 * @tc.type: FUNC
695 * @tc.require:
696 */
697 HWTEST_F(InputMethodAbilityTest, testCreatePanel004, TestSize.Level0)
698 {
699     IMSA_HILOGI("InputMethodAbilityTest testCreatePanel006 START. Allowed to create one SOFT_KEYBOARD panel and "
700                 "one STATUS_BAR panel.");
701     AccessScope scope(currentImeTokenId_, currentImeUid_);
702     std::shared_ptr<InputMethodPanel> inputMethodPanel = nullptr;
703     PanelInfo panelInfo1 = { .panelType = SOFT_KEYBOARD, .panelFlag = FLG_FIXED };
704     auto ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo1, inputMethodPanel);
705     EXPECT_TRUE(inputMethodPanel != nullptr);
706     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
707 
708     ret = inputMethodAbility_->DestroyPanel(inputMethodPanel);
709     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
710 
711     PanelInfo panelInfo2 = { .panelType = STATUS_BAR };
712     ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo2, inputMethodPanel);
713     EXPECT_TRUE(inputMethodPanel != nullptr);
714     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
715 
716     ret = inputMethodAbility_->DestroyPanel(inputMethodPanel);
717     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
718 
719     panelInfo1.panelFlag = FLG_FLOATING;
720     ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo1, inputMethodPanel);
721     EXPECT_TRUE(inputMethodPanel != nullptr);
722     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
723 
724     ret = inputMethodAbility_->DestroyPanel(inputMethodPanel);
725     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
726 }
727 
728 /**
729 * @tc.name: testCreatePanel005
730 * @tc.desc: It's allowed to create one SOFT_KEYBOARD panel, but two is denied.
731 * @tc.type: FUNC
732 * @tc.require:
733 */
734 HWTEST_F(InputMethodAbilityTest, testCreatePanel005, TestSize.Level0)
735 {
736     IMSA_HILOGI("InputMethodAbilityTest testCreatePanel005 START.");
737     AccessScope scope(currentImeTokenId_, currentImeUid_);
738     std::shared_ptr<InputMethodPanel> softKeyboardPanel1 = nullptr;
739     PanelInfo panelInfo = { .panelType = SOFT_KEYBOARD, .panelFlag = FLG_FIXED };
740     auto ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo, softKeyboardPanel1);
741     EXPECT_TRUE(softKeyboardPanel1 != nullptr);
742     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
743 
744     ret = inputMethodAbility_->DestroyPanel(softKeyboardPanel1);
745     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
746 
747     std::shared_ptr<InputMethodPanel> softKeyboardPanel2 = nullptr;
748     ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo, softKeyboardPanel2);
749     EXPECT_TRUE(softKeyboardPanel2 != nullptr);
750     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
751 
752     ret = inputMethodAbility_->DestroyPanel(softKeyboardPanel2);
753     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
754 }
755 
756 /**
757 * @tc.name: testCreatePanel006
758 * @tc.desc: It's allowed to create one SOFT_KEYBOARD panel, but two is denied.
759 * @tc.type: FUNC
760 * @tc.require:
761 */
762 HWTEST_F(InputMethodAbilityTest, testCreatePanel006, TestSize.Level0)
763 {
764     IMSA_HILOGI("InputMethodAbilityTest testCreatePanel006 START.");
765     AccessScope scope(currentImeTokenId_, currentImeUid_);
766     std::shared_ptr<InputMethodPanel> softKeyboardPanel1 = nullptr;
767     PanelInfo panelInfo = { .panelType = SOFT_KEYBOARD, .panelFlag = FLG_FIXED };
768     auto ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo, softKeyboardPanel1);
769     EXPECT_TRUE(softKeyboardPanel1 != nullptr);
770     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
771 
772     std::shared_ptr<InputMethodPanel> softKeyboardPanel2 = nullptr;
773     ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo, softKeyboardPanel2);
774     EXPECT_TRUE(softKeyboardPanel2 == nullptr);
775     EXPECT_EQ(ret, ErrorCode::ERROR_OPERATE_PANEL);
776 
777     ret = inputMethodAbility_->DestroyPanel(softKeyboardPanel1);
778     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
779 
780     std::shared_ptr<InputMethodPanel> softKeyboardPanel3 = nullptr;
781     ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo, softKeyboardPanel3);
782     EXPECT_TRUE(softKeyboardPanel3 != nullptr);
783     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
784 
785     ret = inputMethodAbility_->DestroyPanel(softKeyboardPanel2);
786     EXPECT_EQ(ret, ErrorCode::ERROR_BAD_PARAMETERS);
787 
788     ret = inputMethodAbility_->DestroyPanel(softKeyboardPanel3);
789     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
790 }
791 
792 /**
793 * @tc.name: testSetCallingWindow001
794 * @tc.desc: InputMethodAbility SetCallingWindow
795 * @tc.type: FUNC
796 * @tc.require:
797 * @tc.author: Hollokin
798 */
799 HWTEST_F(InputMethodAbilityTest, testSetCallingWindow001, TestSize.Level0)
800 {
801     IMSA_HILOGI("InputMethodAbility testSetCallingWindow001 START");
802     std::unique_lock<std::mutex> lock(InputMethodAbilityTest::imeListenerCallbackLock_);
803     InputMethodAbilityTest::showKeyboard_ = true;
804     inputMethodAbility_->SetImeListener(std::make_shared<InputMethodEngineListenerImpl>());
805     uint32_t windowId = 10;
806     inputMethodAbility_->SetCallingWindow(windowId);
807     InputMethodAbilityTest::imeListenerCv_.wait_for(
__anon3abd9da90202null808         lock, std::chrono::seconds(DEALY_TIME), [windowId] { return InputMethodAbilityTest::windowId_ == windowId; });
809     EXPECT_EQ(InputMethodAbilityTest::windowId_, windowId);
810 }
811 
812 /**
813 * @tc.name: testNotifyPanelStatusInfo_001
814 * @tc.desc: ShowKeyboard HideKeyboard SOFT_KEYBOARD FLG_FIXED
815 * @tc.type: FUNC
816 * @tc.require:
817 * @tc.author: chenyu
818 */
819 HWTEST_F(InputMethodAbilityTest, testNotifyPanelStatusInfo_001, TestSize.Level0)
820 {
821     IMSA_HILOGI("InputMethodAbility testNotifyPanelStatusInfo_001 START");
822     imc_->Attach(textListener_);
823     PanelInfo info = { .panelType = STATUS_BAR };
824     auto panel = std::make_shared<InputMethodPanel>();
825     AccessScope scope(currentImeTokenId_, currentImeUid_);
826     auto ret = inputMethodAbility_->CreatePanel(nullptr, info, panel);
827     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
828     auto panel1 = std::make_shared<InputMethodPanel>();
829     PanelInfo info1 = { .panelType = SOFT_KEYBOARD, .panelFlag = FLG_FIXED };
830     ret = inputMethodAbility_->CreatePanel(nullptr, info1, panel1);
831     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
832 
833     TextListener::ResetParam();
834     ret = inputMethodAbility_->ShowKeyboard();
835     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
836     EXPECT_TRUE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::SHOW));
837     EXPECT_TRUE(TextListener::WaitNotifyPanelStatusInfoCallback({ info1, true, Trigger::IMF }));
838 
839     TextListener::ResetParam();
840     ret = inputMethodAbility_->HideKeyboard();
841     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
842     EXPECT_TRUE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::HIDE));
843     EXPECT_TRUE(TextListener::WaitNotifyPanelStatusInfoCallback({ info1, false, Trigger::IMF }));
844 
845     ret = inputMethodAbility_->DestroyPanel(panel);
846     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
847     ret = inputMethodAbility_->DestroyPanel(panel1);
848     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
849 }
850 
851 /**
852 * @tc.name: testNotifyPanelStatusInfo_002
853 * @tc.desc: ShowPanel HidePanel SOFT_KEYBOARD  FLG_FLOATING
854 * @tc.type: FUNC
855 * @tc.require:
856 * @tc.author: chenyu
857 */
858 HWTEST_F(InputMethodAbilityTest, testNotifyPanelStatusInfo_002, TestSize.Level0)
859 {
860     IMSA_HILOGI("InputMethodAbility testNotifyPanelStatusInfo_002 START");
861     imc_->Attach(textListener_);
862     PanelInfo info = { .panelType = SOFT_KEYBOARD, .panelFlag = FLG_FLOATING };
863     AccessScope scope(currentImeTokenId_, currentImeUid_);
864     auto panel = std::make_shared<InputMethodPanel>();
865     auto ret = inputMethodAbility_->CreatePanel(nullptr, info, panel);
866     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
867 
868     // ShowPanel
869     CheckPanelStatusInfo(panel, { info, true, Trigger::IME_APP });
870     // HidePanel
871     CheckPanelStatusInfo(panel, { info, false, Trigger::IME_APP });
872 
873     ret = inputMethodAbility_->DestroyPanel(panel);
874     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
875 }
876 
877 /**
878 * @tc.name: testNotifyPanelStatusInfo_003
879 * @tc.desc: ShowPanel HidePanel STATUS_BAR
880 * @tc.type: FUNC
881 * @tc.require:
882 * @tc.author: chenyu
883 */
884 HWTEST_F(InputMethodAbilityTest, testNotifyPanelStatusInfo_003, TestSize.Level0)
885 {
886     IMSA_HILOGI("InputMethodAbility testNotifyPanelStatusInfo_003 START");
887     imc_->Attach(textListener_);
888     PanelInfo info = { .panelType = STATUS_BAR };
889     auto panel = std::make_shared<InputMethodPanel>();
890     AccessScope scope(currentImeTokenId_, currentImeUid_);
891     auto ret = inputMethodAbility_->CreatePanel(nullptr, info, panel);
892     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
893 
894     // ShowPanel
895     CheckPanelStatusInfo(panel, { info, true, Trigger::IME_APP });
896     // HidePanel
897     CheckPanelStatusInfo(panel, { info, false, Trigger::IME_APP });
898 
899     ret = inputMethodAbility_->DestroyPanel(panel);
900     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
901 }
902 
903 /**
904 * @tc.name: testNotifyPanelStatusInfo_004
905 * @tc.desc: ShowPanel HidePanel SOFT_KEYBOARD  FLG_CANDIDATE_COLUMN
906 * @tc.type: FUNC
907 * @tc.require:
908 * @tc.author: chenyu
909 */
910 HWTEST_F(InputMethodAbilityTest, testNotifyPanelStatusInfo_004, TestSize.Level0)
911 {
912     IMSA_HILOGI("InputMethodAbility testNotifyPanelStatusInfo_004 START");
913     imc_->Attach(textListener_);
914     PanelInfo info = { .panelType = SOFT_KEYBOARD, .panelFlag = FLG_CANDIDATE_COLUMN };
915     auto panel = std::make_shared<InputMethodPanel>();
916     AccessScope scope(currentImeTokenId_, currentImeUid_);
917     auto ret = inputMethodAbility_->CreatePanel(nullptr, info, panel);
918     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
919 
920     // ShowPanel
921     CheckPanelStatusInfo(panel, { info, true, Trigger::IME_APP });
922     // HidePanel
923     CheckPanelStatusInfo(panel, { info, false, Trigger::IME_APP });
924 
925     ret = inputMethodAbility_->DestroyPanel(panel);
926     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
927 }
928 
929 /**
930 * @tc.name: testNotifyPanelStatusInfo_005
931 * @tc.desc: HideKeyboardSelf
932 * @tc.type: FUNC
933 * @tc.require:
934 * @tc.author: chenyu
935 */
936 HWTEST_F(InputMethodAbilityTest, testNotifyPanelStatusInfo_005, TestSize.Level0)
937 {
938     IMSA_HILOGI("InputMethodAbility testNotifyPanelStatusInfo_005 START");
939     PanelInfo info = { .panelType = SOFT_KEYBOARD, .panelFlag = FLG_FLOATING };
940     imc_->Attach(textListener_);
941 
942     // has no panel
943     TextListener::ResetParam();
944     auto ret = inputMethodAbility_->HideKeyboardSelf();
945     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
946     EXPECT_TRUE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::HIDE));
947     EXPECT_FALSE(TextListener::WaitNotifyPanelStatusInfoCallback({ info, false, Trigger::IME_APP }));
948 
949     AccessScope scope(currentImeTokenId_, currentImeUid_);
950     auto panel = std::make_shared<InputMethodPanel>();
951     ret = inputMethodAbility_->CreatePanel(nullptr, info, panel);
952     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
953     ret = inputMethodAbility_->ShowPanel(panel);
954     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
955     // has panel
956     TextListener::ResetParam();
957     ret = inputMethodAbility_->HideKeyboardSelf();
958     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
959     EXPECT_TRUE(TextListener::WaitSendKeyboardStatusCallback(KeyboardStatus::HIDE));
960     EXPECT_TRUE(TextListener::WaitNotifyPanelStatusInfoCallback({ info, false, Trigger::IME_APP }));
961 
962     ret = inputMethodAbility_->DestroyPanel(panel);
963     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
964 }
965 
966 /**
967 * @tc.name: testNotifyKeyboardHeight_001
968 * @tc.desc: NotifyKeyboardHeight SOFT_KEYBOARD  FLG_FIXED
969 * @tc.type: FUNC
970 * @tc.require:
971 * @tc.author: mashaoyin
972 */
973 HWTEST_F(InputMethodAbilityTest, testNotifyKeyboardHeight_001, TestSize.Level0)
974 {
975     IMSA_HILOGI("InputMethodAbility testNotifyKeyboardHeight_001 START");
976     imc_->Attach(textListener_);
977     AccessScope scope(currentImeTokenId_, currentImeUid_);
978     TextListener::ResetParam();
979     inputMethodAbility_->NotifyKeyboardHeight(1, FLG_FIXED);
980     EXPECT_TRUE(TextListener::WaitNotifyKeyboardHeightCallback(1));
981 }
982 
983 /**
984 * @tc.name: testNotifyKeyboardHeight_002
985 * @tc.desc: NotifyKeyboardHeight SOFT_KEYBOARD  FLG_CANDIDATE_COLUMN
986 * @tc.type: FUNC
987 * @tc.require:
988 * @tc.author: mashaoyin
989 */
990 HWTEST_F(InputMethodAbilityTest, testNotifyKeyboardHeight_002, TestSize.Level0)
991 {
992     IMSA_HILOGI("InputMethodAbility testNotifyKeyboardHeight_002 START");
993     imc_->Attach(textListener_);
994     AccessScope scope(currentImeTokenId_, currentImeUid_);
995     TextListener::ResetParam();
996     inputMethodAbility_->NotifyKeyboardHeight(1, FLG_CANDIDATE_COLUMN);
997     EXPECT_TRUE(TextListener::WaitNotifyKeyboardHeightCallback(0));
998 }
999 
1000 /**
1001 * @tc.name: testNotifyKeyboardHeight_003
1002 * @tc.desc: NotifyKeyboardHeight Attach with hard keyboard
1003 * @tc.type: FUNC
1004 * @tc.require:
1005 * @tc.author: mashaoyin
1006 */
1007 HWTEST_F(InputMethodAbilityTest, testNotifyKeyboardHeight_003, TestSize.Level0)
1008 {
1009     IMSA_HILOGI("InputMethodAbility testNotifyKeyboardHeight_003 START");
1010     TextListener::ResetParam();
1011     AccessScope scope(currentImeTokenId_, currentImeUid_);
1012     PanelInfo info = { .panelType = SOFT_KEYBOARD, .panelFlag = FLG_CANDIDATE_COLUMN };
1013     auto panel = std::make_shared<InputMethodPanel>();
1014     auto ret = inputMethodAbility_->CreatePanel(nullptr, info, panel);
1015     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1016     panel->Resize(1, 1);
1017     imc_->Attach(textListener_);
1018     EXPECT_TRUE(TextListener::WaitNotifyKeyboardHeightCallback(0));
1019     ret = inputMethodAbility_->DestroyPanel(panel);
1020     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1021 }
1022 
1023 /**
1024 * @tc.name: testOnSecurityChange
1025 * @tc.desc: OnSecurityChange
1026 * @tc.type: FUNC
1027 * @tc.require:
1028 * @tc.author: chenyu
1029 */
1030 HWTEST_F(InputMethodAbilityTest, testOnSecurityChange, TestSize.Level0)
1031 {
1032     IMSA_HILOGI("InputMethodAbility testOnSecurityChange START");
1033     int32_t security = 32;
1034     inputMethodAbility_->SetImeListener(std::make_shared<InputMethodEngineListenerImpl>());
1035     auto ret = inputMethodAbility_->OnSecurityChange(security);
1036     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1037     EXPECT_EQ(InputMethodAbilityTest::security_, security);
1038 }
1039 
1040 /**
1041  * @tc.name: testSendPrivateCommand_001
1042  * @tc.desc: IMA SendPrivateCommand current is not default ime.
1043  * @tc.type: FUNC
1044  * @tc.require:
1045  * @tc.author: mashaoyin
1046  */
1047 HWTEST_F(InputMethodAbilityTest, testSendPrivateCommand_001, TestSize.Level0)
1048 {
1049     IMSA_HILOGI("InputMethodAbility testSendPrivateCommand_001 Test START");
1050     IdentityCheckerMock::SetBundleNameValid(false);
1051     TextListener::ResetParam();
1052     InputMethodAbilityTest::GetIMCDetachIMA();
1053     TddUtil::RestoreSelfTokenID();
1054     std::unordered_map<std::string, PrivateDataValue> privateCommand;
1055     auto ret = inputMethodAbility_->SendPrivateCommand(privateCommand);
1056     EXPECT_EQ(ret, ErrorCode::ERROR_NOT_DEFAULT_IME);
1057     IdentityCheckerMock::SetBundleNameValid(true);
1058 }
1059 
1060 /**
1061  * @tc.name: testSendPrivateCommand_002
1062  * @tc.desc: IMA SendPrivateCommand current data specification, default ime, not bound.
1063  * @tc.type: FUNC
1064  * @tc.require:
1065  * @tc.author: mashaoyin
1066  */
1067 HWTEST_F(InputMethodAbilityTest, testSendPrivateCommand_002, TestSize.Level0)
1068 {
1069     IMSA_HILOGI("InputMethodAbility testSendPrivateCommand_002 Test START");
1070     InputMethodAbilityTest::GetIMCDetachIMA();
1071     IdentityCheckerMock::SetBundleNameValid(true);
1072     std::unordered_map<std::string, PrivateDataValue> privateCommand;
1073     PrivateDataValue privateDataValue1 = std::string("stringValue");
1074     privateCommand.insert({ "value1", privateDataValue1 });
1075     auto ret = inputMethodAbility_->SendPrivateCommand(privateCommand);
1076     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NULL_POINTER);
1077     IdentityCheckerMock::SetBundleNameValid(false);
1078 }
1079 
1080 /**
1081  * @tc.name: testSendPrivateCommand_003
1082  * @tc.desc: IMA SendPrivateCommand with correct data specification and all data type.
1083  * @tc.type: FUNC
1084  * @tc.require:
1085  * @tc.author: mashaoyin
1086  */
1087 HWTEST_F(InputMethodAbilityTest, testSendPrivateCommand_003, TestSize.Level0)
1088 {
1089     IMSA_HILOGI("InputMethodAbility testSendPrivateCommand_003 Test START");
1090     TextListener::ResetParam();
1091     InputMethodAbilityTest::GetIMCAttachIMA();
1092     IdentityCheckerMock::SetBundleNameValid(true);
1093     std::unordered_map<std::string, PrivateDataValue> privateCommand;
1094     PrivateDataValue privateDataValue1 = std::string("stringValue");
1095     PrivateDataValue privateDataValue2 = true;
1096     PrivateDataValue privateDataValue3 = 100;
1097     privateCommand.emplace("value1", privateDataValue1);
1098     privateCommand.emplace("value2", privateDataValue2);
1099     privateCommand.emplace("value3", privateDataValue3);
1100     auto ret = inputMethodAbility_->SendPrivateCommand(privateCommand);
1101     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1102     EXPECT_TRUE(TextListener::WaitSendPrivateCommandCallback(privateCommand));
1103     InputMethodAbilityTest::GetIMCDetachIMA();
1104     IdentityCheckerMock::SetBundleNameValid(false);
1105 }
1106 
1107 /**
1108  * @tc.name: testGetCallingWindowInfo_001
1109  * @tc.desc: GetCallingWindowInfo with IMC not bound
1110  * @tc.type: FUNC
1111  * @tc.require:
1112  * @tc.author: zhaolinglan
1113  */
1114 HWTEST_F(InputMethodAbilityTest, testGetCallingWindowInfo_001, TestSize.Level0)
1115 {
1116     IMSA_HILOGI("InputMethodAbility testGetCallingWindowInfo_001 Test START");
1117     InputMethodAbilityTest::GetIMCDetachIMA();
1118     CallingWindowInfo windowInfo;
1119     int32_t ret = InputMethodAbilityTest::inputMethodAbility_->GetCallingWindowInfo(windowInfo);
1120     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_FOUND);
1121 }
1122 
1123 /**
1124  * @tc.name: testGetCallingWindowInfo_002
1125  * @tc.desc: GetCallingWindowInfo with panel not created
1126  * @tc.type: FUNC
1127  * @tc.require:
1128  * @tc.author: zhaolinglan
1129  */
1130 HWTEST_F(InputMethodAbilityTest, testGetCallingWindowInfo_002, TestSize.Level0)
1131 {
1132     IMSA_HILOGI("InputMethodAbility testGetCallingWindowInfo_002 Test START");
1133     AccessScope accessScope(InputMethodAbilityTest::currentImeTokenId_, InputMethodAbilityTest::currentImeUid_);
1134     // bind IMC
1135     InputMethodAbilityTest::GetIMCAttachIMA();
1136     // no panel is created
1137     InputMethodAbilityTest::inputMethodAbility_->panels_.Clear();
1138     CallingWindowInfo windowInfo;
1139     int32_t ret = InputMethodAbilityTest::inputMethodAbility_->GetCallingWindowInfo(windowInfo);
1140     EXPECT_EQ(ret, ErrorCode::ERROR_PANEL_NOT_FOUND);
1141     InputMethodAbilityTest::GetIMCDetachIMA();
1142 }
1143 
1144 /**
1145  * @tc.name: testGetCallingWindowInfo_003
1146  * @tc.desc: GetCallingWindowInfo with only status_bar created
1147  * @tc.type: FUNC
1148  * @tc.require:
1149  * @tc.author: zhaolinglan
1150  */
1151 HWTEST_F(InputMethodAbilityTest, testGetCallingWindowInfo_003, TestSize.Level0)
1152 {
1153     IMSA_HILOGI("InputMethodAbility testGetCallingWindowInfo_003 Test START");
1154     AccessScope accessScope(InputMethodAbilityTest::currentImeTokenId_, InputMethodAbilityTest::currentImeUid_);
1155     // bind IMC
1156     InputMethodAbilityTest::GetIMCAttachIMA();
1157     // only STATUS_BAR panel in IMA
1158     auto inputMethodPanel = std::make_shared<InputMethodPanel>();
1159     PanelInfo info = { PanelType::STATUS_BAR };
1160     InputMethodAbilityTest::inputMethodAbility_->CreatePanel(nullptr, info, inputMethodPanel);
1161     CallingWindowInfo windowInfo;
1162     int32_t ret = InputMethodAbilityTest::inputMethodAbility_->GetCallingWindowInfo(windowInfo);
1163     EXPECT_EQ(ret, ErrorCode::ERROR_PANEL_NOT_FOUND);
1164     InputMethodAbilityTest::inputMethodAbility_->DestroyPanel(inputMethodPanel);
1165     InputMethodAbilityTest::GetIMCDetachIMA();
1166 }
1167 
1168 /**
1169  * @tc.name: testGetCallingWindowInfo_004
1170  * @tc.desc: GetCallingWindowInfo with invalid windowid
1171  * @tc.type: FUNC
1172  * @tc.require:
1173  * @tc.author: zhaolinglan
1174  */
1175 HWTEST_F(InputMethodAbilityTest, testGetCallingWindowInfo_004, TestSize.Level0)
1176 {
1177     IMSA_HILOGI("InputMethodAbility testGetCallingWindowInfo_004 Test START");
1178     AccessScope accessScope(InputMethodAbilityTest::currentImeTokenId_, InputMethodAbilityTest::currentImeUid_);
1179     // bind imc
1180     InputMethodAbilityTest::GetIMCAttachIMA();
1181     // SOFT_KEYBOARD panel exists
1182     auto inputMethodPanel = std::make_shared<InputMethodPanel>();
1183     PanelInfo info = { PanelType::SOFT_KEYBOARD, PanelFlag::FLG_FIXED };
1184     InputMethodAbilityTest::inputMethodAbility_->CreatePanel(nullptr, info, inputMethodPanel);
1185     // invalid window id
1186     InputMethodAbilityTest::imc_->clientInfo_.config.windowId = INVALID_WINDOW_ID;
1187     CallingWindowInfo windowInfo;
1188     int32_t ret = InputMethodAbilityTest::inputMethodAbility_->GetCallingWindowInfo(windowInfo);
1189     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1190     InputMethodAbilityTest::inputMethodAbility_->DestroyPanel(inputMethodPanel);
1191     InputMethodAbilityTest::GetIMCDetachIMA();
1192 }
1193 
1194 /**
1195  * @tc.name: testGetCallingWindowInfo_005
1196  * @tc.desc: GetCallingWindowInfo success
1197  * @tc.type: FUNC
1198  * @tc.require:
1199  * @tc.author: zhaolinglan
1200  */
1201 HWTEST_F(InputMethodAbilityTest, testGetCallingWindowInfo_005, TestSize.Level0)
1202 {
1203     IMSA_HILOGI("InputMethodAbility testGetCallingWindowInfo_005 Test START");
1204     AccessScope accessScope(InputMethodAbilityTest::currentImeTokenId_, InputMethodAbilityTest::currentImeUid_);
1205     // SOFT_KEYBOARD window is created
1206     InputMethodAbilityTest::inputMethodAbility_->panels_.Clear();
1207     auto inputMethodPanel = std::make_shared<InputMethodPanel>();
1208     PanelInfo info = { PanelType::SOFT_KEYBOARD, PanelFlag::FLG_FIXED };
1209     InputMethodAbilityTest::inputMethodAbility_->CreatePanel(nullptr, info, inputMethodPanel);
1210     // bind IMC
1211     InputMethodAbilityTest::GetIMCAttachIMA();
1212     InputMethodAbilityTest::imc_->textConfig_.windowId = TddUtil::WindowManager::currentWindowId_;
1213     // get window info success
1214     CallingWindowInfo windowInfo;
1215     int32_t ret = InputMethodAbilityTest::inputMethodAbility_->GetCallingWindowInfo(windowInfo);
1216     EXPECT_TRUE(ret == ErrorCode::NO_ERROR || ret == ErrorCode::ERROR_WINDOW_MANAGER);
1217     InputMethodAbilityTest::GetIMCDetachIMA();
1218     InputMethodAbilityTest::inputMethodAbility_->DestroyPanel(inputMethodPanel);
1219 }
1220 
1221 /**
1222  * @tc.name: testSetPreviewText_001
1223  * @tc.desc: IMA
1224  * @tc.type: FUNC
1225  * @tc.require:
1226  * @tc.author: zhaolinglan
1227  */
1228 HWTEST_F(InputMethodAbilityTest, testSetPreviewText_001, TestSize.Level0)
1229 {
1230     IMSA_HILOGI("InputMethodAbilityTest testSetPreviewText_001 Test START");
1231     TextListener::ResetParam();
1232     std::string text = "test";
1233     Range range = { 1, 2 };
1234     InputMethodAbilityTest::GetIMCAttachIMA();
1235     InputMethodAbilityTest::imc_->textConfig_.inputAttribute.isTextPreviewSupported = true;
1236     auto ret = InputMethodAbilityTest::inputMethodAbility_->SetPreviewText(text, range);
1237     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1238     EXPECT_EQ(TextListener::previewText_, text);
1239     EXPECT_EQ(TextListener::previewRange_, range);
1240     InputMethodAbilityTest::GetIMCDetachIMA();
1241 }
1242 
1243 /**
1244  * @tc.name: testSetPreviewText_002
1245  * @tc.desc: IMA
1246  * @tc.type: FUNC
1247  * @tc.require:
1248  * @tc.author: zhaolinglan
1249  */
1250 HWTEST_F(InputMethodAbilityTest, testSetPreviewText_002, TestSize.Level0)
1251 {
1252     IMSA_HILOGI("InputMethodAbilityTest testSetPreviewText_002 Test START");
1253     TextListener::ResetParam();
1254     std::string text = "test";
1255     Range range = { 1, 2 };
1256     InputMethodAbilityTest::inputMethodAbility_->ClearDataChannel(
1257         InputMethodAbilityTest::inputMethodAbility_->dataChannelObject_);
1258     auto ret = InputMethodAbilityTest::inputMethodAbility_->SetPreviewText(text, range);
1259     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NULL_POINTER);
1260     EXPECT_NE(TextListener::previewText_, text);
1261     EXPECT_FALSE(TextListener::previewRange_ == range);
1262 }
1263 
1264 /**
1265  * @tc.name: testSetPreviewText_003
1266  * @tc.desc: IMA
1267  * @tc.type: FUNC
1268  * @tc.require:
1269  * @tc.author: zhaolinglan
1270  */
1271 HWTEST_F(InputMethodAbilityTest, testSetPreviewText_003, TestSize.Level0)
1272 {
1273     IMSA_HILOGI("InputMethodAbilityTest testSetPreviewText_003 Test START");
1274     TextListener::ResetParam();
1275     std::string text = "test";
1276     Range range = { 1, 2 };
1277     InputMethodAbilityTest::GetIMCAttachIMA();
1278     InputMethodAbilityTest::imc_->textConfig_.inputAttribute.isTextPreviewSupported = false;
1279     auto ret = InputMethodAbilityTest::inputMethodAbility_->SetPreviewText(text, range);
1280     EXPECT_EQ(ret, ErrorCode::ERROR_TEXT_PREVIEW_NOT_SUPPORTED);
1281     EXPECT_NE(TextListener::previewText_, text);
1282     EXPECT_FALSE(TextListener::previewRange_ == range);
1283     InputMethodAbilityTest::GetIMCDetachIMA();
1284 }
1285 
1286 /**
1287  * @tc.name: testFinishTextPreview_001
1288  * @tc.desc: IMA
1289  * @tc.type: FUNC
1290  * @tc.require:
1291  * @tc.author: zhaolinglan
1292  */
1293 HWTEST_F(InputMethodAbilityTest, testFinishTextPreview_001, TestSize.Level0)
1294 {
1295     IMSA_HILOGI("InputMethodAbilityTest testFinishTextPreview_001 Test START");
1296     TextListener::ResetParam();
1297     InputMethodAbilityTest::GetIMCAttachIMA();
1298     InputMethodAbilityTest::imc_->textConfig_.inputAttribute.isTextPreviewSupported = true;
1299     auto ret = InputMethodAbilityTest::inputMethodAbility_->FinishTextPreview(false);
1300     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
1301     EXPECT_TRUE(TextListener::isFinishTextPreviewCalled_);
1302     InputMethodAbilityTest::GetIMCDetachIMA();
1303 }
1304 
1305 /**
1306  * @tc.name: testFinishTextPreview_002
1307  * @tc.desc: IMA
1308  * @tc.type: FUNC
1309  * @tc.require:
1310  * @tc.author: zhaolinglan
1311  */
1312 HWTEST_F(InputMethodAbilityTest, testFinishTextPreview_002, TestSize.Level0)
1313 {
1314     IMSA_HILOGI("InputMethodAbilityTest testFinishTextPreview_002 Test START");
1315     TextListener::ResetParam();
1316     InputMethodAbilityTest::inputMethodAbility_->ClearDataChannel(
1317         InputMethodAbilityTest::inputMethodAbility_->dataChannelObject_);
1318     auto ret = InputMethodAbilityTest::inputMethodAbility_->FinishTextPreview(false);
1319     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NULL_POINTER);
1320     EXPECT_FALSE(TextListener::isFinishTextPreviewCalled_);
1321 }
1322 
1323 /**
1324  * @tc.name: testFinishTextPreview_003
1325  * @tc.desc: IMA
1326  * @tc.type: FUNC
1327  * @tc.require:
1328  * @tc.author: zhaolinglan
1329  */
1330 HWTEST_F(InputMethodAbilityTest, testFinishTextPreview_003, TestSize.Level0)
1331 {
1332     IMSA_HILOGI("InputMethodAbilityTest testFinishTextPreview_003 Test START");
1333     TextListener::ResetParam();
1334     InputMethodAbilityTest::GetIMCAttachIMA();
1335     InputMethodAbilityTest::imc_->textConfig_.inputAttribute.isTextPreviewSupported = false;
1336     auto ret = InputMethodAbilityTest::inputMethodAbility_->FinishTextPreview(false);
1337     EXPECT_EQ(ret, ErrorCode::ERROR_TEXT_PREVIEW_NOT_SUPPORTED);
1338     EXPECT_FALSE(TextListener::isFinishTextPreviewCalled_);
1339     InputMethodAbilityTest::GetIMCDetachIMA();
1340 }
1341 } // namespace MiscServices
1342 } // namespace OHOS
1343