• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #include <event_handler.h>
16 #include <gtest/gtest.h>
17 #include <string_ex.h>
18 #include <sys/time.h>
19 
20 #include <condition_variable>
21 #include <cstdint>
22 #include <functional>
23 #include <mutex>
24 #include <string>
25 #include <thread>
26 #include <vector>
27 
28 #include "global.h"
29 #include "i_input_method_agent.h"
30 #include "i_input_method_system_ability.h"
31 #include "input_client_stub.h"
32 #include "input_data_channel_stub.h"
33 #include "input_method_ability.h"
34 #include "input_method_controller.h"
35 #include "input_method_engine_listener_impl.h"
36 #include "input_method_system_ability_proxy.h"
37 #include "input_method_utils.h"
38 #include "keyboard_listener.h"
39 #include "message_parcel.h"
40 #include "tdd_util.h"
41 #include "text_listener.h"
42 
43 using namespace testing::ext;
44 namespace OHOS {
45 namespace MiscServices {
46 using WindowMgr = TddUtil::WindowManager;
47 class KeyboardListenerImpl : public KeyboardListener {
48 public:
KeyboardListenerImpl()49     KeyboardListenerImpl(){};
~KeyboardListenerImpl()50     ~KeyboardListenerImpl(){};
51     static int32_t keyCode_;
52     static int32_t keyStatus_;
53     static CursorInfo cursorInfo_;
54     bool OnKeyEvent(int32_t keyCode, int32_t keyStatus) override;
55     bool OnKeyEvent(const std::shared_ptr<MMI::KeyEvent> &keyEvent) override;
56     void OnCursorUpdate(int32_t positionX, int32_t positionY, int32_t height) override;
57     void OnSelectionChange(int32_t oldBegin, int32_t oldEnd, int32_t newBegin, int32_t newEnd) override;
58     void OnTextChange(const std::string &text) override;
59     void OnEditorAttributeChange(const InputAttribute &inputAttribute) override;
60 };
61 int32_t KeyboardListenerImpl::keyCode_ = 0;
62 int32_t KeyboardListenerImpl::keyStatus_ = 0;
63 CursorInfo KeyboardListenerImpl::cursorInfo_ = {};
OnKeyEvent(int32_t keyCode,int32_t keyStatus)64 bool KeyboardListenerImpl::OnKeyEvent(int32_t keyCode, int32_t keyStatus)
65 {
66     IMSA_HILOGD("KeyboardListenerImpl::OnKeyEvent %{public}d %{public}d", keyCode, keyStatus);
67     keyCode_ = keyCode;
68     keyStatus_ = keyStatus;
69     return true;
70 }
OnKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)71 bool KeyboardListenerImpl::OnKeyEvent(const std::shared_ptr<MMI::KeyEvent> &keyEvent)
72 {
73     return true;
74 }
OnCursorUpdate(int32_t positionX,int32_t positionY,int32_t height)75 void KeyboardListenerImpl::OnCursorUpdate(int32_t positionX, int32_t positionY, int32_t height)
76 {
77     IMSA_HILOGD("KeyboardListenerImpl::OnCursorUpdate %{public}d %{public}d %{public}d", positionX, positionY, height);
78     cursorInfo_ = { static_cast<double>(positionX), static_cast<double>(positionY), 0, static_cast<double>(height) };
79 }
OnSelectionChange(int32_t oldBegin,int32_t oldEnd,int32_t newBegin,int32_t newEnd)80 void KeyboardListenerImpl::OnSelectionChange(int32_t oldBegin, int32_t oldEnd, int32_t newBegin, int32_t newEnd)
81 {
82 }
OnTextChange(const std::string & text)83 void KeyboardListenerImpl::OnTextChange(const std::string &text)
84 {
85 }
OnEditorAttributeChange(const InputAttribute & inputAttribute)86 void KeyboardListenerImpl::OnEditorAttributeChange(const InputAttribute &inputAttribute)
87 {
88 }
89 
90 class InputMethodEditorTest : public testing::Test {
91 public:
92     static void SetUpTestCase(void);
93     static void TearDownTestCase(void);
94     void SetUp();
95     void TearDown();
96     static sptr<InputMethodController> inputMethodController_;
97     static sptr<InputMethodAbility> inputMethodAbility_;
98     static std::shared_ptr<MMI::KeyEvent> keyEvent_;
99     static std::shared_ptr<KeyboardListenerImpl> kbListener_;
100     static std::shared_ptr<InputMethodEngineListenerImpl> imeListener_;
101     static sptr<OnTextChangedListener> textListener_;
102 };
103 sptr<InputMethodController> InputMethodEditorTest::inputMethodController_;
104 sptr<InputMethodAbility> InputMethodEditorTest::inputMethodAbility_;
105 std::shared_ptr<MMI::KeyEvent> InputMethodEditorTest::keyEvent_;
106 std::shared_ptr<KeyboardListenerImpl> InputMethodEditorTest::kbListener_;
107 std::shared_ptr<InputMethodEngineListenerImpl> InputMethodEditorTest::imeListener_;
108 sptr<OnTextChangedListener> InputMethodEditorTest::textListener_;
109 
SetUpTestCase(void)110 void InputMethodEditorTest::SetUpTestCase(void)
111 {
112     IMSA_HILOGI("InputMethodEditorTest::SetUpTestCase");
113     TddUtil::StorageSelfTokenID();
114     std::shared_ptr<Property> property = InputMethodController::GetInstance()->GetCurrentInputMethod();
115     std::string bundleName = property != nullptr ? property->name : "default.inputmethod.unittest";
116     TddUtil::SetTestTokenID(TddUtil::GetTestTokenID(bundleName));
117     inputMethodAbility_ = InputMethodAbility::GetInstance();
118     inputMethodAbility_->OnImeReady();
119     inputMethodAbility_->SetCoreAndAgent();
120     kbListener_ = std::make_shared<KeyboardListenerImpl>();
121     imeListener_ = std::make_shared<InputMethodEngineListenerImpl>();
122     inputMethodAbility_->SetKdListener(kbListener_);
123     inputMethodAbility_->SetImeListener(imeListener_);
124 
125     textListener_ = new TextListener();
126     inputMethodController_ = InputMethodController::GetInstance();
127 
128     keyEvent_ = MMI::KeyEvent::Create();
129     constexpr int32_t keyAction = 2;
130     constexpr int32_t keyCode = 2001;
131     keyEvent_->SetKeyAction(keyAction);
132     keyEvent_->SetKeyCode(keyCode);
133     TextListener::ResetParam();
134     TddUtil::SetTestTokenID(TddUtil::AllocTestTokenID(true, false, "undefine"));
135     TddUtil::WindowManager::RegisterFocusChangeListener();
136     WindowMgr::CreateWindow();
137 }
138 
TearDownTestCase(void)139 void InputMethodEditorTest::TearDownTestCase(void)
140 {
141     IMSA_HILOGI("InputMethodEditorTest::TearDownTestCase");
142     TddUtil::RestoreSelfTokenID();
143     TextListener::ResetParam();
144     WindowMgr::DestroyWindow();
145 }
146 
SetUp(void)147 void InputMethodEditorTest::SetUp(void)
148 {
149     IMSA_HILOGI("InputMethodEditorTest::SetUp");
150 }
151 
TearDown(void)152 void InputMethodEditorTest::TearDown(void)
153 {
154     IMSA_HILOGI("InputMethodEditorTest::TearDown");
155 }
156 
157 /**
158  * @tc.name: testIMCAttachUnfocused
159  * @tc.desc: InputMethodEditorTest Attach.
160  * @tc.type: FUNC
161  */
162 HWTEST_F(InputMethodEditorTest, testIMCAttachUnfocused, TestSize.Level0)
163 {
164     IMSA_HILOGD("InputMethodEditorTest Attach Unfocused Test START");
165     int32_t ret = InputMethodEditorTest::inputMethodController_->Attach(textListener_, false);
166     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_FOCUSED);
167     ret = InputMethodEditorTest::inputMethodController_->Attach(textListener_);
168     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_FOCUSED);
169     ret = InputMethodEditorTest::inputMethodController_->Attach(textListener_, true);
170     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_FOCUSED);
171 }
172 
173 /**
174  * @tc.name: test Unfocused
175  * @tc.desc: InputMethodEditorTest ShowTextInput Unfocused
176  * @tc.type: FUNC
177  */
178 HWTEST_F(InputMethodEditorTest, testShowTextInputUnfocused, TestSize.Level0)
179 {
180     IMSA_HILOGI("InputMethodEditorTest Unfocused Test START");
181     int32_t ret = InputMethodEditorTest::inputMethodController_->ShowTextInput();
182     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_BOUND);
183     ret = InputMethodEditorTest::inputMethodController_->ShowSoftKeyboard();
184     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
185     bool result = InputMethodEditorTest::inputMethodController_->DispatchKeyEvent(InputMethodEditorTest::keyEvent_);
186     EXPECT_FALSE(result);
187     ret = InputMethodEditorTest::inputMethodController_->ShowSoftKeyboard();
188     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
189     ret = InputMethodEditorTest::inputMethodController_->HideSoftKeyboard();
190     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
191     ret = InputMethodEditorTest::inputMethodController_->StopInputSession();
192     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_FOCUSED);
193     ret = InputMethodEditorTest::inputMethodController_->ShowCurrentInput();
194     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
195     ret = InputMethodEditorTest::inputMethodController_->HideCurrentInput();
196     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
197 }
198 
199 /**
200  * @tc.name: test AttachFocused
201  * @tc.desc: InputMethodEditorTest Attach Focused
202  * @tc.type: FUNC
203  */
204 HWTEST_F(InputMethodEditorTest, testAttachFocused, TestSize.Level0)
205 {
206     IMSA_HILOGI("InputMethodEditorTest Attach Focused Test START");
207     WindowMgr::ShowWindow();
208     bool isFocused = FocusChangedListenerTestImpl::isFocused_->GetValue();
209     IMSA_HILOGI("testAttachFocused getFocus end, isFocused = %{public}d", isFocused);
210     InputMethodEditorTest::imeListener_->isInputStart_ = false;
211     InputMethodEditorTest::imeListener_->keyboardState_ = false;
212     int32_t ret = InputMethodEditorTest::inputMethodController_->Attach(InputMethodEditorTest::textListener_, false);
213     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
214 
215     InputMethodEditorTest::imeListener_->isInputStart_ = false;
216     InputMethodEditorTest::imeListener_->keyboardState_ = false;
217     ret = InputMethodEditorTest::inputMethodController_->Attach(InputMethodEditorTest::textListener_);
218     EXPECT_TRUE(TextListener::WaitIMACallback());
219     EXPECT_TRUE(imeListener_->isInputStart_ && imeListener_->keyboardState_);
220     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
221 
222     InputMethodEditorTest::imeListener_->isInputStart_ = false;
223     InputMethodEditorTest::imeListener_->keyboardState_ = false;
224     ret = InputMethodEditorTest::inputMethodController_->Attach(InputMethodEditorTest::textListener_, true);
225     EXPECT_TRUE(TextListener::WaitIMACallback());
226     EXPECT_TRUE(imeListener_->isInputStart_ && imeListener_->keyboardState_);
227     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
228     InputMethodEditorTest::inputMethodController_->Close();
229     WindowMgr::HideWindow();
230     bool unFocus = FocusChangedListenerTestImpl::unFocused_->GetValue();
231     IMSA_HILOGI("testAttachFocused unFocus end, unFocus = %{public}d", unFocus);
232 }
233 
234 /**
235  * @tc.name: testShowSoftKeyboard
236  * @tc.desc: InputMethodEditorTest ShowSoftKeyboard
237  * @tc.type: FUNC
238  */
239 HWTEST_F(InputMethodEditorTest, testShowSoftKeyboard, TestSize.Level0)
240 {
241     IMSA_HILOGI("InputMethodEditorTest ShowSoftKeyboard Test START");
242     TddUtil::SetTestTokenID(TddUtil::AllocTestTokenID(true, true, "undefined"));
243     WindowMgr::ShowWindow();
244     bool isFocused = FocusChangedListenerTestImpl::isFocused_->GetValue();
245     IMSA_HILOGI("testShowSoftKeyboard getFocus end, isFocused = %{public}d", isFocused);
246     InputMethodEditorTest::imeListener_->keyboardState_ = false;
247     TextListener::keyboardStatus_ = KeyboardStatus::NONE;
248     int32_t ret = InputMethodEditorTest::inputMethodController_->Attach(InputMethodEditorTest::textListener_, false);
249     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
250     ret = InputMethodEditorTest::inputMethodController_->ShowSoftKeyboard();
251     EXPECT_TRUE(TextListener::WaitIMACallback());
252     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
253     EXPECT_TRUE(imeListener_->keyboardState_ && TextListener::keyboardStatus_ == KeyboardStatus::SHOW);
254     WindowMgr::HideWindow();
255     bool unFocus = FocusChangedListenerTestImpl::unFocused_->GetValue();
256     IMSA_HILOGI("testShowSoftKeyboard unFocus end, unFocus = %{public}d", unFocus);
257 }
258 
259 /**
260  * @tc.name: testIMCHideTextInput.
261  * @tc.desc: InputMethodEditorTest testHideTextInput.
262  * @tc.type: FUNC
263  */
264 HWTEST_F(InputMethodEditorTest, testIMCHideTextInput, TestSize.Level0)
265 {
266     IMSA_HILOGI("InputMethodEditorTest HideTextInputAndShowTextInput Test START");
267     InputMethodEditorTest::inputMethodController_->Close();
268     WindowMgr::ShowWindow();
269     bool isFocused = FocusChangedListenerTestImpl::isFocused_->GetValue();
270     IMSA_HILOGI("testIMCHideTextInput getFocus end, isFocused = %{public}d", isFocused);
271     int32_t ret = InputMethodEditorTest::inputMethodController_->Attach(InputMethodEditorTest::textListener_, true);
272     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
273 
274     imeListener_->keyboardState_ = true;
275     TextListener::keyboardStatus_ = KeyboardStatus::NONE;
276     InputMethodEditorTest::inputMethodController_->HideTextInput();
277     bool result = InputMethodEditorTest::inputMethodController_->DispatchKeyEvent(InputMethodEditorTest::keyEvent_);
278     EXPECT_FALSE(result);
279     ret = InputMethodEditorTest::inputMethodController_->ShowSoftKeyboard();
280     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
281     ret = InputMethodEditorTest::inputMethodController_->ShowSoftKeyboard();
282     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
283     ret = InputMethodEditorTest::inputMethodController_->HideSoftKeyboard();
284     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
285     ret = InputMethodEditorTest::inputMethodController_->ShowCurrentInput();
286     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
287     ret = InputMethodEditorTest::inputMethodController_->HideCurrentInput();
288     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
289     WindowMgr::HideWindow();
290     bool unFocus = FocusChangedListenerTestImpl::unFocused_->GetValue();
291     IMSA_HILOGI("testIMCHideTextInput unFocus end, unFocus = %{public}d", unFocus);
292 }
293 
294 /**
295  * @tc.name: testShowTextInput
296  * @tc.desc: InputMethodEditorTest ShowTextInput
297  * @tc.type: FUNC
298  */
299 HWTEST_F(InputMethodEditorTest, testShowTextInput, TestSize.Level0)
300 {
301     IMSA_HILOGI("InputMethodEditorTest ShowTextInput Test START");
302     InputMethodEditorTest::inputMethodController_->Close();
303     WindowMgr::ShowWindow();
304     bool isFocused = FocusChangedListenerTestImpl::isFocused_->GetValue();
305     IMSA_HILOGI("testShowTextInput getFocus end, isFocused = %{public}d", isFocused);
306     int32_t ret = InputMethodEditorTest::inputMethodController_->Attach(InputMethodEditorTest::textListener_, true);
307     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
308     InputMethodEditorTest::inputMethodController_->HideTextInput();
309 
310     ret = InputMethodEditorTest::inputMethodController_->ShowTextInput();
311     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
312     bool result = InputMethodEditorTest::inputMethodController_->DispatchKeyEvent(InputMethodEditorTest::keyEvent_);
313     usleep(300);
314     ret = ret && kbListener_->keyCode_ == keyEvent_->GetKeyCode()
315           && kbListener_->keyStatus_ == keyEvent_->GetKeyAction();
316     EXPECT_TRUE(result);
317     WindowMgr::HideWindow();
318     bool unFocus = FocusChangedListenerTestImpl::unFocused_->GetValue();
319     IMSA_HILOGI("testShowTextInput unFocus end, unFocus = %{public}d", unFocus);
320 }
321 
322 /**
323  * @tc.name: testIMCClose.
324  * @tc.desc: InputMethodEditorTest Close.
325  * @tc.type: FUNC
326  */
327 HWTEST_F(InputMethodEditorTest, testIMCClose, TestSize.Level0)
328 {
329     IMSA_HILOGI("IMC Close Test START");
330     WindowMgr::ShowWindow();
331     bool isFocused = FocusChangedListenerTestImpl::isFocused_->GetValue();
332     IMSA_HILOGI("testIMCClose getFocus end, isFocused = %{public}d", isFocused);
333     int32_t ret = InputMethodEditorTest::inputMethodController_->Attach(InputMethodEditorTest::textListener_, true);
334     EXPECT_EQ(ret, ErrorCode::NO_ERROR);
335     InputMethodEditorTest::inputMethodController_->Close();
336 
337     ret = InputMethodEditorTest::inputMethodController_->ShowTextInput();
338     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_BOUND);
339     ret = InputMethodEditorTest::inputMethodController_->ShowSoftKeyboard();
340     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
341     bool result = InputMethodEditorTest::inputMethodController_->DispatchKeyEvent(InputMethodEditorTest::keyEvent_);
342     EXPECT_FALSE(result);
343     ret = InputMethodEditorTest::inputMethodController_->ShowSoftKeyboard();
344     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
345     ret = InputMethodEditorTest::inputMethodController_->HideSoftKeyboard();
346     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
347     ret = InputMethodEditorTest::inputMethodController_->ShowCurrentInput();
348     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
349     ret = InputMethodEditorTest::inputMethodController_->HideCurrentInput();
350     EXPECT_EQ(ret, ErrorCode::ERROR_CLIENT_NOT_EDITABLE);
351     WindowMgr::HideWindow();
352     bool unFocus = FocusChangedListenerTestImpl::unFocused_->GetValue();
353     IMSA_HILOGI("testIMCClose unFocus end, unFocus = %{public}d", unFocus);
354 }
355 } // namespace MiscServices
356 } // namespace OHOS
357