1 /*
2 * Copyright (C) 2021 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 <gtest/gtest.h>
16 #include <sys/time.h>
17 #include <unistd.h>
18
19 #include <condition_variable>
20 #include <string>
21 #include <vector>
22
23 #include "global.h"
24 #include "ime_event_monitor_manager_impl.h"
25 #include "ime_setting_listener_test_impl.h"
26 #include "input_method_controller.h"
27 #include "input_method_property.h"
28 #include "tdd_util.h"
29
30 using namespace testing::ext;
31 namespace OHOS {
32 namespace MiscServices {
33 class InputMethodSwitchTest : public testing::Test {
34 public:
35 static void SetUpTestCase(void);
36 static void TearDownTestCase(void);
37 void SetUp();
38 void TearDown();
39 static void CheckCurrentProp(const std::string &extName);
40 static void CheckCurrentSubProp(const std::string &extName);
41 static void CheckCurrentSubProps();
42 static sptr<InputMethodController> imc_;
43 static std::string newImeBundleName;
44 static std::vector<std::string> newImeSubName;
45 static std::string bundleName;
46 static std::vector<std::string> extName;
47 static std::vector<std::string> language;
48 static std::vector<std::string> locale;
49 static std::string beforeValue;
50 static std::string allEnableIme;
51 };
52 sptr<InputMethodController> InputMethodSwitchTest::imc_;
53 std::string InputMethodSwitchTest::newImeBundleName = "com.example.newTestIme";
54 std::vector<std::string> InputMethodSwitchTest::newImeSubName{ "lowerInput", "upperInput", "chineseInput" };
55 std::string InputMethodSwitchTest::bundleName = "com.example.testIme";
56 std::vector<std::string> InputMethodSwitchTest::extName{ "InputMethodExtAbility", "InputMethodExtAbility2" };
57 std::vector<std::string> InputMethodSwitchTest::language{ "chinese", "english" };
58 std::vector<std::string> InputMethodSwitchTest::locale{ "zh-CN", "en-US" };
59 std::string InputMethodSwitchTest::beforeValue;
60 std::string InputMethodSwitchTest::allEnableIme = "{\"enableImeList\" : {\"100\" : [ \"com.example.newTestIme\", "
61 "\"com.example.testIme\"]}}";
62 constexpr uint32_t IME_EXT_NUM = 2;
63 constexpr uint32_t NEW_IME_SUBTYPE_NUM = 3;
64 constexpr uint32_t TOTAL_IME_MIN_NUM = 2;
65 constexpr uint32_t ENABLE_IME_NUM = 1;
66 constexpr uint32_t WAIT_IME_READY_TIME = 1;
67 constexpr const char *ENABLE_IME_KEYWORD = "settings.inputmethod.enable_ime";
SetUpTestCase(void)68 void InputMethodSwitchTest::SetUpTestCase(void)
69 {
70 IMSA_HILOGI("InputMethodSwitchTest::SetUpTestCase");
71 TddUtil::GrantNativePermission();
72 int32_t ret = TddUtil::GetEnableData(beforeValue);
73 if (ret == ErrorCode::NO_ERROR) {
74 IMSA_HILOGI("Enable ime switch test.");
75 TddUtil::PushEnableImeValue(ENABLE_IME_KEYWORD, allEnableIme);
76 }
77 TddUtil::StorageSelfTokenID();
78 TddUtil::SetTestTokenID(
79 TddUtil::AllocTestTokenID(true, "ohos.inputMethod.test", { "ohos.permission.CONNECT_IME_ABILITY" }));
80 imc_ = InputMethodController::GetInstance();
81 auto listener = std::make_shared<ImeSettingListenerTestImpl>();
82 ImeEventMonitorManagerImpl::GetInstance().RegisterImeEventListener(EVENT_IME_CHANGE_MASK, listener);
83 }
84
TearDownTestCase(void)85 void InputMethodSwitchTest::TearDownTestCase(void)
86 {
87 IMSA_HILOGI("InputMethodSwitchTest::TearDownTestCase");
88 TddUtil::GrantNativePermission();
89 TddUtil::PushEnableImeValue(ENABLE_IME_KEYWORD, beforeValue);
90 InputMethodController::GetInstance()->Close();
91 TddUtil::RestoreSelfTokenID();
92 }
93
SetUp(void)94 void InputMethodSwitchTest::SetUp(void)
95 {
96 IMSA_HILOGI("InputMethodSwitchTest::SetUp");
97 }
98
TearDown(void)99 void InputMethodSwitchTest::TearDown(void)
100 {
101 IMSA_HILOGI("InputMethodSwitchTest::TearDown");
102 }
103
CheckCurrentProp(const std::string & extName)104 void InputMethodSwitchTest::CheckCurrentProp(const std::string &extName)
105 {
106 std::shared_ptr<Property> property = imc_->GetCurrentInputMethod();
107 ASSERT_TRUE(property != nullptr);
108 EXPECT_EQ(property->name, bundleName);
109 EXPECT_EQ(property->id, extName);
110 }
111
CheckCurrentSubProp(const std::string & extName)112 void InputMethodSwitchTest::CheckCurrentSubProp(const std::string &extName)
113 {
114 auto subProperty = imc_->GetCurrentInputMethodSubtype();
115 ASSERT_TRUE(subProperty != nullptr);
116 EXPECT_EQ(subProperty->id, extName);
117 EXPECT_EQ(subProperty->name, bundleName);
118 }
119
CheckCurrentSubProps()120 void InputMethodSwitchTest::CheckCurrentSubProps()
121 {
122 std::vector<SubProperty> subProps;
123 auto ret = imc_->ListCurrentInputMethodSubtype(subProps);
124 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
125 ASSERT_EQ(subProps.size(), IME_EXT_NUM);
126 for (uint32_t i = 0; i < IME_EXT_NUM; i++) {
127 EXPECT_EQ(subProps[i].id, extName[i]);
128 EXPECT_EQ(subProps[i].name, bundleName);
129 EXPECT_EQ(subProps[i].language, language[i]);
130 EXPECT_EQ(subProps[i].locale, locale[i]);
131 }
132 }
133
134 /**
135 * @tc.name: testImeSwitch
136 * @tc.desc: switch to testIme
137 * @tc.type: FUNC
138 * @tc.require: issuesI62BHB
139 * @tc.author: chenyu
140 */
141 HWTEST_F(InputMethodSwitchTest, testImeSwitch, TestSize.Level0)
142 {
143 IMSA_HILOGI("oldIme testImeSwitch Test START");
144 ImeSettingListenerTestImpl::ResetParam();
145 // switch to ext testIme
146 auto ret = imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, bundleName);
147 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
148 EXPECT_TRUE(ImeSettingListenerTestImpl::WaitImeChange());
149 CheckCurrentProp(extName[0]);
150 CheckCurrentSubProp(extName[0]);
151 CheckCurrentSubProps();
152 sleep(WAIT_IME_READY_TIME);
153 }
154
155 /**
156 * @tc.name: testSubTypeSwitch_001
157 * @tc.desc: switch subtype with extName1
158 * @tc.type: FUNC
159 * @tc.require: issuesI62BHB
160 * @tc.author: chenyu
161 */
162 HWTEST_F(InputMethodSwitchTest, testSubTypeSwitch_001, TestSize.Level0)
163 {
164 IMSA_HILOGI("oldIme testSubTypeSwitch_001 Test START");
165 ImeSettingListenerTestImpl::ResetParam();
166 int32_t ret = imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, bundleName, extName[0]);
167 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
168 EXPECT_FALSE(ImeSettingListenerTestImpl::WaitImeChange());
169 CheckCurrentProp(extName[0]);
170 CheckCurrentSubProp(extName[0]);
171 CheckCurrentSubProps();
172 }
173
174 /**
175 * @tc.name: testSubTypeSwitch_002
176 * @tc.desc: switch subtype with extName2
177 * @tc.type: FUNC
178 * @tc.require: issuesI62BHB
179 * @tc.author: chenyu
180 */
181 HWTEST_F(InputMethodSwitchTest, testSubTypeSwitch_002, TestSize.Level0)
182 {
183 IMSA_HILOGI("oldIme testSubTypeSwitch_002 Test START");
184 ImeSettingListenerTestImpl::ResetParam();
185 int32_t ret = imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, bundleName, extName[1]);
186 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
187 EXPECT_TRUE(ImeSettingListenerTestImpl::WaitImeChange());
188 CheckCurrentProp(extName[0]);
189 CheckCurrentSubProp(extName[1]);
190 CheckCurrentSubProps();
191 }
192
193 /**
194 * @tc.name: testSubTypeSwitch_003
195 * @tc.desc: switch subtype with extName1
196 * @tc.type: FUNC
197 * @tc.require: issuesI62BHB
198 * @tc.author: chenyu
199 */
200 HWTEST_F(InputMethodSwitchTest, testSubTypeSwitch_003, TestSize.Level0)
201 {
202 IMSA_HILOGI("oldIme testSubTypeSwitch_003 Test START");
203 ImeSettingListenerTestImpl::ResetParam();
204 int32_t ret = imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, bundleName, extName[0]);
205 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
206 EXPECT_TRUE(ImeSettingListenerTestImpl::WaitImeChange());
207 CheckCurrentProp(extName[0]);
208 CheckCurrentSubProp(extName[0]);
209 CheckCurrentSubProps();
210 }
211
212 /**
213 * @tc.name: testSubTypeSwitchWithErrorSubName
214 * @tc.desc: switch subtype with error subName.
215 * @tc.type: FUNC
216 * @tc.require: issuesI62BHB
217 * @tc.author: chenyu
218 */
219 HWTEST_F(InputMethodSwitchTest, testSubTypeSwitchWithErrorSubName, TestSize.Level0)
220 {
221 IMSA_HILOGI("oldIme testSubTypeSwitchWithErrorSubName Test START");
222 std::string subName = InputMethodSwitchTest::imc_->GetCurrentInputMethodSubtype()->id;
223 int32_t ret = imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, bundleName, "error subName");
224 EXPECT_EQ(ret, ErrorCode::ERROR_BAD_PARAMETERS);
225 CheckCurrentProp(subName);
226 CheckCurrentSubProp(subName);
227 CheckCurrentSubProps();
228 }
229
230 /**
231 * @tc.name: testSwitchToCurrentImeWithEmptySubName
232 * @tc.desc: switch to currentIme witch empty subName.
233 * @tc.type: FUNC
234 * @tc.require: issuesI62BHB
235 * @tc.author: chenyu
236 */
237 HWTEST_F(InputMethodSwitchTest, testSwitchToCurrentImeWithEmptySubName, TestSize.Level0)
238 {
239 IMSA_HILOGI("oldIme testSwitchToCurrentImeWithEmptySubName Test START");
240 ImeSettingListenerTestImpl::ResetParam();
241 std::string subName = InputMethodSwitchTest::imc_->GetCurrentInputMethodSubtype()->id;
242 int32_t ret = imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, bundleName);
243 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
244 EXPECT_FALSE(ImeSettingListenerTestImpl::WaitImeChange());
245 CheckCurrentProp(subName);
246 CheckCurrentSubProp(subName);
247 CheckCurrentSubProps();
248 }
249
250 /**
251 * @tc.name: testSwitchImeWithErrorBundleName
252 * @tc.desc: switch ime witch error bundleName
253 * @tc.type: FUNC
254 * @tc.require: issuesI62BHB
255 * @tc.author: chenyu
256 */
257 HWTEST_F(InputMethodSwitchTest, testSwitchImeWithErrorBundleName, TestSize.Level0)
258 {
259 IMSA_HILOGI("oldIme testSwitchImeWithErrorBundleName Test START");
260 std::string subName = InputMethodSwitchTest::imc_->GetCurrentInputMethodSubtype()->id;
261 int32_t ret = imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, "error bundleName", extName[0]);
262 EXPECT_TRUE(ret == ErrorCode::ERROR_ENABLE_IME || ret == ErrorCode::ERROR_BAD_PARAMETERS);
263 CheckCurrentProp(subName);
264 CheckCurrentSubProp(subName);
265 CheckCurrentSubProps();
266 }
267
268 /**
269 * @tc.name: testSwitchImeWithErrorBundleNameWitchEmptySubName
270 * @tc.desc: switch ime witch error bundleName and empty subName
271 * @tc.type: FUNC
272 * @tc.require: issuesI62BHB
273 * @tc.author: chenyu
274 */
275 HWTEST_F(InputMethodSwitchTest, testSwitchImeWithErrorBundleNameWitchEmptySubName, TestSize.Level0)
276 {
277 IMSA_HILOGI("oldIme testSwitchImeWithErrorBundleNameWitchEmptySubName Test START");
278 std::string subName = InputMethodSwitchTest::imc_->GetCurrentInputMethodSubtype()->id;
279 int32_t ret = imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, "error bundleName", " ");
280 EXPECT_TRUE(ret == ErrorCode::ERROR_ENABLE_IME || ret == ErrorCode::ERROR_BAD_PARAMETERS);
281 CheckCurrentProp(subName);
282 CheckCurrentSubProp(subName);
283 CheckCurrentSubProps();
284 }
285
286 /**
287 * @tc.name: testIMCListInputMethod
288 * @tc.desc: IMC ListInputMethod
289 * @tc.type: FUNC
290 * @tc.require: issuesI62BHB
291 * @tc.author: chenyu
292 */
293 HWTEST_F(InputMethodSwitchTest, testIMCListInputMethod, TestSize.Level0)
294 {
295 IMSA_HILOGI("IMC testIMCListInputMethod Test Start");
296 std::vector<Property> properties = {};
297 auto ret = imc_->ListInputMethod(properties);
298 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
299 EXPECT_TRUE(properties.size() >= TOTAL_IME_MIN_NUM);
300 bool hasIme = false;
301 bool hasNewIme = false;
302 for (const auto &property : properties) {
303 if (property.name == bundleName) {
304 hasIme = true;
305 }
306 if (property.name == newImeBundleName) {
307 hasNewIme = true;
308 }
309 }
310 EXPECT_TRUE(hasIme && hasNewIme);
311 }
312
313 /**
314 * @tc.name: testIMCListInputMethodDisable
315 * @tc.desc: IMC ListInputMethod
316 * @tc.type: FUNC
317 * @tc.require: issuesI62BHB
318 * @tc.author: chenyu
319 */
320 HWTEST_F(InputMethodSwitchTest, testIMCListInputMethodDisable, TestSize.Level0)
321 {
322 IMSA_HILOGI("IMC testIMCListInputMethodDisable Test Start");
323 std::vector<Property> disableProperties = {};
324 auto ret = imc_->ListInputMethod(false, disableProperties);
325 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
326 EXPECT_GE(disableProperties.size(), 0);
327 }
328
329 /**
330 * @tc.name: testIMCListInputMethodEnable
331 * @tc.desc: IMC ListInputMethod
332 * @tc.type: FUNC
333 * @tc.require: issuesI62BHB
334 * @tc.author: chenyu
335 */
336 HWTEST_F(InputMethodSwitchTest, testIMCListInputMethodEnable, TestSize.Level0)
337 {
338 IMSA_HILOGI("IMC testIMCListInputMethodEnable Test Start");
339 std::string subName = InputMethodSwitchTest::imc_->GetCurrentInputMethodSubtype()->id;
340 std::vector<Property> enableProperties = {};
341 auto ret = imc_->ListInputMethod(true, enableProperties);
342 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
343 EXPECT_GE(enableProperties.size(), ENABLE_IME_NUM);
344 }
345
346 /**
347 * @tc.name: tesIMCtListInputMethodSubtype_001
348 * @tc.desc: ListInputMethodSubtype
349 * @tc.type: FUNC
350 * @tc.require: issuesI62BHB
351 * @tc.author: chenyu
352 */
353 HWTEST_F(InputMethodSwitchTest, tesIMCtListInputMethodSubtype_001, TestSize.Level0)
354 {
355 IMSA_HILOGI("IMC tesIMCtListInputMethodSubtype_001 Test Start");
356 Property property = { .name = newImeBundleName };
357 std::vector<SubProperty> subProps;
358 auto ret = imc_->ListInputMethodSubtype(property, subProps);
359 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
360 ASSERT_EQ(subProps.size(), NEW_IME_SUBTYPE_NUM);
361 for (uint32_t i = 0; i < NEW_IME_SUBTYPE_NUM; i++) {
362 EXPECT_EQ(subProps[i].id, newImeSubName[i]);
363 EXPECT_EQ(subProps[i].name, newImeBundleName);
364 }
365 }
366
367 /**
368 * @tc.name: tesIMCtListInputMethodSubtype_002
369 * @tc.desc: ListInputMethodSubtype
370 * @tc.type: FUNC
371 * @tc.require: issuesI62BHB
372 * @tc.author: chenyu
373 */
374 HWTEST_F(InputMethodSwitchTest, tesIMCtListInputMethodSubtype_002, TestSize.Level0)
375 {
376 IMSA_HILOGI("IMC tesIMCtListInputMethodSubtype_002 Test Start");
377 Property property = { .name = bundleName };
378 std::vector<SubProperty> subProps;
379 auto ret = imc_->ListInputMethodSubtype(property, subProps);
380 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
381 ASSERT_EQ(subProps.size(), IME_EXT_NUM);
382 for (uint32_t i = 0; i < IME_EXT_NUM; i++) {
383 EXPECT_EQ(subProps[i].id, extName[i]);
384 EXPECT_EQ(subProps[i].name, bundleName);
385 }
386 }
387
388 /**
389 * @tc.name: testIMCListInputMethodSubtypeWithErrorBundleName
390 * @tc.desc: IMC ListInputMethodSubtype
391 * @tc.type: FUNC
392 * @tc.require: issuesI62BHB
393 * @tc.author: chenyu
394 */
395 HWTEST_F(InputMethodSwitchTest, testIMCListInputMethodSubtypeWithErrorBundleName, TestSize.Level0)
396 {
397 IMSA_HILOGI("IMC testIMCListInputMethodSubtypeWitchErrorBundleName Test START");
398 std::shared_ptr<Property> property = std::make_shared<Property>();
399 std::vector<SubProperty> properties = {};
400 auto ret = imc_->ListInputMethodSubtype(*property, properties);
401 EXPECT_EQ(ret, ErrorCode::ERROR_BAD_PARAMETERS);
402 EXPECT_TRUE(properties.empty());
403 }
404
405 /**
406 * @tc.name: testShowOptionalInputMethod
407 * @tc.desc: IMC ShowOptionalInputMethod
408 * @tc.type: FUNC
409 */
410 HWTEST_F(InputMethodSwitchTest, testShowOptionalInputMethod, TestSize.Level2)
411 {
412 IMSA_HILOGI("IMC ShowOptionalInputMethod Test START");
413 int32_t ret = imc_->ShowOptionalInputMethod();
414 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
415 }
416
417 /**
418 * @tc.name: testDisplayOptionalInputMethod
419 * @tc.desc: IMC DisplayOptionalInputMethod
420 * @tc.type: FUNC
421 */
422 HWTEST_F(InputMethodSwitchTest, testDisplayOptionalInputMethod, TestSize.Level2)
423 {
424 IMSA_HILOGI("IMC DisplayOptionalInputMethod Test START");
425 sleep(2);
426 int32_t ret = imc_->DisplayOptionalInputMethod();
427 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
428 }
429
430 /**
431 * @tc.name: testCombinationKeySwitchIme_001
432 * @tc.desc: switch ime by combination key.
433 * @tc.type: FUNC
434 * @tc.require: issuesI8RPP3
435 * @tc.author: mashaoyin
436 */
437 HWTEST_F(InputMethodSwitchTest, testCombinationKeySwitchIme_001, TestSize.Level0)
438 {
439 IMSA_HILOGI("testCombinationKeySwitchIme_001 Test START");
440 ImeSettingListenerTestImpl::ResetParam();
441 std::shared_ptr<Property> property = imc_->GetCurrentInputMethod();
442 std::string result;
443 static std::string cmd = "uinput -K -d 2076 -d 2050";
444 auto ret = TddUtil::ExecuteCmd(cmd, result);
445 EXPECT_TRUE(ret);
446 EXPECT_TRUE(ImeSettingListenerTestImpl::WaitImeChange());
447 imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, property->name, "");
448 }
449
450 /**
451 * @tc.name: testCombinationKeySwitchIme_002
452 * @tc.desc: switch ime by combination key.
453 * @tc.type: FUNC
454 * @tc.require: issuesI8RPP3
455 * @tc.author: mashaoyin
456 */
457 HWTEST_F(InputMethodSwitchTest, testCombinationKeySwitchIme_002, TestSize.Level0)
458 {
459 IMSA_HILOGI("testCombinationKeySwitchIme_002 Test START");
460 ImeSettingListenerTestImpl::ResetParam();
461 std::shared_ptr<Property> property = imc_->GetCurrentInputMethod();
462 std::string result;
463 static std::string cmd = "uinput -K -d 2077 -d 2050";
464 auto ret = TddUtil::ExecuteCmd(cmd, result);
465 EXPECT_TRUE(ret);
466 EXPECT_TRUE(ImeSettingListenerTestImpl::WaitImeChange());
467 imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, property->name, "");
468 }
469
470 /**
471 * @tc.name: testCombinationKeySwitchIme_003
472 * @tc.desc: switch ime by combination key.
473 * @tc.type: FUNC
474 * @tc.require: issuesI8RPP3
475 * @tc.author: mashaoyin
476 */
477 HWTEST_F(InputMethodSwitchTest, testCombinationKeySwitchIme_003, TestSize.Level0)
478 {
479 IMSA_HILOGI("testCombinationKeySwitchIme_003 Test START");
480 ImeSettingListenerTestImpl::ResetParam();
481 std::shared_ptr<Property> property = imc_->GetCurrentInputMethod();
482 std::vector<Property> props;
483 imc_->ListInputMethod(props);
484 std::string result;
485 static std::string cmd = "uinput -K -d 2077 -d 2050 -u 2050 -u 2077";
486 for (auto iter = 0; iter < props.size(); ++iter) {
487 auto ret = TddUtil::ExecuteCmd(cmd, result);
488 EXPECT_TRUE(ret);
489 }
490 EXPECT_TRUE(ImeSettingListenerTestImpl::WaitTargetImeChange(property->name));
491 std::shared_ptr<Property> curProperty = imc_->GetCurrentInputMethod();
492 EXPECT_EQ(property->name, curProperty->name);
493 imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, property->name, "");
494 }
495 } // namespace MiscServices
496 } // namespace OHOS
497