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 <string>
20 #include <vector>
21
22 #include "accesstoken_kit.h"
23 #include "global.h"
24 #include "input_method_controller.h"
25 #include "input_method_property.h"
26 #include "nativetoken_kit.h"
27 #include "token_setproc.h"
28
29 using namespace testing::ext;
30 using namespace OHOS::Security::AccessToken;
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 GrantNativePermission();
40 static std::mutex imeChangeFlagLock;
41 static std::condition_variable conditionVar;
42 static bool imeChangeFlag;
43 static std::string extBundleName;
44 static std::string extAbilityName;
45 };
46 std::mutex InputMethodSwitchTest::imeChangeFlagLock;
47 std::condition_variable InputMethodSwitchTest::conditionVar;
48 bool InputMethodSwitchTest::imeChangeFlag = false;
49 std::string InputMethodSwitchTest::extBundleName = "com.example.testIme";
50 std::string InputMethodSwitchTest::extAbilityName = "InputMethodExtAbility";
51 constexpr uint32_t DEALY_TIME = 300;
52 class InputMethodSettingListenerImpl : public InputMethodSettingListener {
53 public:
54 InputMethodSettingListenerImpl() = default;
55 ~InputMethodSettingListenerImpl() = default;
OnImeChange(const Property & property,const SubProperty & subProperty)56 void OnImeChange(const Property &property, const SubProperty &subProperty)
57 {
58 {
59 std::unique_lock<std::mutex> lock(InputMethodSwitchTest::imeChangeFlagLock);
60 InputMethodSwitchTest::imeChangeFlag = true;
61 }
62 InputMethodSwitchTest::conditionVar.notify_one();
63 IMSA_HILOGI("InputMethodSettingListenerImpl OnImeChange");
64 }
65 };
66 constexpr int32_t EXT_INPUTMETHOD_SUBTYPE_NUM = 1;
SetUpTestCase(void)67 void InputMethodSwitchTest::SetUpTestCase(void)
68 {
69 IMSA_HILOGI("InputMethodSwitchTest::SetUpTestCase");
70 GrantNativePermission();
71 }
72
TearDownTestCase(void)73 void InputMethodSwitchTest::TearDownTestCase(void)
74 {
75 IMSA_HILOGI("InputMethodSwitchTest::TearDownTestCase");
76 InputMethodController::GetInstance()->Close();
77 }
78
SetUp(void)79 void InputMethodSwitchTest::SetUp(void)
80 {
81 IMSA_HILOGI("InputMethodSwitchTest::SetUp");
82 }
83
TearDown(void)84 void InputMethodSwitchTest::TearDown(void)
85 {
86 IMSA_HILOGI("InputMethodSwitchTest::TearDown");
87 }
88
GrantNativePermission()89 void InputMethodSwitchTest::GrantNativePermission()
90 {
91 const char **perms = new const char *[1];
92 perms[0] = "ohos.permission.CONNECT_IME_ABILITY";
93 TokenInfoParams infoInstance = {
94 .dcapsNum = 0,
95 .permsNum = 1,
96 .aclsNum = 0,
97 .dcaps = nullptr,
98 .perms = perms,
99 .acls = nullptr,
100 .processName = "inputmethod_imf",
101 .aplStr = "system_core",
102 };
103 uint64_t tokenId = GetAccessTokenId(&infoInstance);
104 int res = SetSelfTokenID(tokenId);
105 if (res == 0) {
106 IMSA_HILOGI("SetSelfTokenID success!");
107 } else {
108 IMSA_HILOGE("SetSelfTokenID fail!");
109 }
110 AccessTokenKit::ReloadNativeTokenInfo();
111 delete[] perms;
112 }
113
114 /**
115 * @tc.name: testIMCSetImeListener
116 * @tc.desc: IMC testSetImeListener.
117 * @tc.type: FUNC
118 * @tc.require: issuesI640YZ
119 */
120 HWTEST_F(InputMethodSwitchTest, testIMCSetImeListener, TestSize.Level0)
121 {
122 IMSA_HILOGI("IMC SetImeListener Test START");
123 auto imc = InputMethodController::GetInstance();
124 ASSERT_TRUE(imc != nullptr);
125 auto listener = std::make_shared<InputMethodSettingListenerImpl>();
126 imc->setImeListener(listener);
127 }
128
129 /**
130 * @tc.name: testIMCSwitchInputMethod
131 * @tc.desc: IMC testSwitchInputMethod.
132 * @tc.type: FUNC
133 * @tc.require: issuesI62BHB
134 * @tc.author: chenyu
135 */
136 HWTEST_F(InputMethodSwitchTest, testIMCSwitchInputMethod, TestSize.Level0)
137 {
138 IMSA_HILOGI("IMC testIMCSwitchInputMethod Test START");
139 std::unique_lock<std::mutex> lock(InputMethodSwitchTest::imeChangeFlagLock);
140 InputMethodSwitchTest::imeChangeFlag = false;
141 sptr<InputMethodController> imc = InputMethodController::GetInstance();
142 ASSERT_TRUE(imc != nullptr);
143 // switch to ext inputmethod
144 auto ret = imc->SwitchInputMethod(InputMethodSwitchTest::extBundleName, InputMethodSwitchTest::extAbilityName);
145 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
146 InputMethodSwitchTest::conditionVar.wait_for(
__anon96fe8e020102null147 lock, std::chrono::milliseconds(DEALY_TIME), [] { return InputMethodSwitchTest::imeChangeFlag == true; });
148 EXPECT_TRUE(InputMethodSwitchTest::imeChangeFlag);
149 std::shared_ptr<Property> property = imc->GetCurrentInputMethod();
150 ASSERT_TRUE(property != nullptr);
151 EXPECT_EQ(property->name, InputMethodSwitchTest::extBundleName);
152 auto subProperty = imc->GetCurrentInputMethodSubtype();
153 ASSERT_TRUE(subProperty != nullptr);
154 EXPECT_EQ(subProperty->id, InputMethodSwitchTest::extAbilityName);
155 EXPECT_EQ(subProperty->name, InputMethodSwitchTest::extBundleName);
156 }
157
158 /**
159 * @tc.name: testIMCSwitchInputMethodSelf
160 * @tc.desc: IMC testSwitchInputMethod.
161 * @tc.type: FUNC
162 * @tc.require: issuesI62BHB
163 * @tc.author: chenyu
164 */
165 HWTEST_F(InputMethodSwitchTest, testIMCSwitchInputMethodSelf, TestSize.Level0)
166 {
167 IMSA_HILOGI("IMC testIMCSwitchInputMethodSelf Test START");
168 std::unique_lock<std::mutex> lock(InputMethodSwitchTest::imeChangeFlagLock);
169 InputMethodSwitchTest::imeChangeFlag = false;
170 sptr<InputMethodController> imc = InputMethodController::GetInstance();
171 ASSERT_TRUE(imc != nullptr);
172 int32_t ret = imc->SwitchInputMethod(InputMethodSwitchTest::extBundleName, InputMethodSwitchTest::extAbilityName);
173 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
174 InputMethodSwitchTest::conditionVar.wait_for(
__anon96fe8e020202null175 lock, std::chrono::milliseconds(DEALY_TIME), [] { return InputMethodSwitchTest::imeChangeFlag == true; });
176 EXPECT_FALSE(InputMethodSwitchTest::imeChangeFlag);
177 std::shared_ptr<Property> property = imc->GetCurrentInputMethod();
178 ASSERT_TRUE(property != nullptr);
179 EXPECT_EQ(property->name, InputMethodSwitchTest::extBundleName);
180 auto subProperty = imc->GetCurrentInputMethodSubtype();
181 ASSERT_TRUE(subProperty != nullptr);
182 EXPECT_EQ(subProperty->id, InputMethodSwitchTest::extAbilityName);
183 EXPECT_EQ(subProperty->name, InputMethodSwitchTest::extBundleName);
184 }
185
186 /**
187 * @tc.name: testIMCSwitchInputMethodWithErrorBundleName
188 * @tc.desc: IMC testSwitchInputMethod.
189 * @tc.type: FUNC
190 * @tc.require: issuesI62BHB
191 * @tc.author: chenyu
192 */
193 HWTEST_F(InputMethodSwitchTest, testIMCSwitchInputMethodWithErrorBundleName, TestSize.Level0)
194 {
195 IMSA_HILOGI("IMC testIMCSwitchInputMethodWithErrorBundleName Test START");
196 sptr<InputMethodController> imc = InputMethodController::GetInstance();
197 ASSERT_TRUE(imc != nullptr);
198 std::string name = "error bundleName";
199 int32_t ret = imc->SwitchInputMethod(name, InputMethodSwitchTest::extAbilityName);
200 EXPECT_EQ(ret, ErrorCode::ERROR_BAD_PARAMETERS);
201 std::shared_ptr<Property> property = imc->GetCurrentInputMethod();
202 ASSERT_TRUE(property != nullptr);
203 EXPECT_EQ(property->name, InputMethodSwitchTest::extBundleName);
204 auto subProperty = imc->GetCurrentInputMethodSubtype();
205 ASSERT_TRUE(subProperty != nullptr);
206 EXPECT_EQ(subProperty->id, InputMethodSwitchTest::extAbilityName);
207 EXPECT_EQ(subProperty->name, InputMethodSwitchTest::extBundleName);
208 }
209
210 /**
211 * @tc.name: testIMCSwitchInputMethodWithErrorSubName
212 * @tc.desc: IMC testSwitchInputMethod.
213 * @tc.type: FUNC
214 * @tc.require: issuesI62BHB
215 * @tc.author: chenyu
216 */
217 HWTEST_F(InputMethodSwitchTest, testIMCSwitchInputMethodWithErrorSubName, TestSize.Level0)
218 {
219 IMSA_HILOGI("IMC testIMCSwitchInputMethodWithErrorSubName Test START");
220 sptr<InputMethodController> imc = InputMethodController::GetInstance();
221 ASSERT_TRUE(imc != nullptr);
222 std::string subName = "error subName";
223 int32_t ret = imc->SwitchInputMethod(InputMethodSwitchTest::extBundleName, subName);
224 EXPECT_EQ(ret, ErrorCode::ERROR_SWITCH_IME);
225 std::shared_ptr<Property> property = imc->GetCurrentInputMethod();
226 ASSERT_TRUE(property != nullptr);
227 EXPECT_EQ(property->name, InputMethodSwitchTest::extBundleName);
228 auto subProperty = imc->GetCurrentInputMethodSubtype();
229 ASSERT_TRUE(subProperty != nullptr);
230 EXPECT_EQ(subProperty->id, InputMethodSwitchTest::extAbilityName);
231 EXPECT_EQ(subProperty->name, InputMethodSwitchTest::extBundleName);
232 }
233
234 /**
235 * @tc.name: testIMCSwitchInputMethodSelfWithoutSubName
236 * @tc.desc: IMC testSwitchInputMethod.
237 * @tc.type: FUNC
238 * @tc.require: issuesI62BHB
239 * @tc.author: chenyu
240 */
241 HWTEST_F(InputMethodSwitchTest, testIMCSwitchInputMethodSelfWithoutSubName, TestSize.Level0)
242 {
243 IMSA_HILOGI("IMC testIMCSwitchInputMethodSelfWithoutSubName Test START");
244 std::unique_lock<std::mutex> lock(InputMethodSwitchTest::imeChangeFlagLock);
245 InputMethodSwitchTest::imeChangeFlag = false;
246 sptr<InputMethodController> imc = InputMethodController::GetInstance();
247 ASSERT_TRUE(imc != nullptr);
248 std::string subName;
249 int32_t ret = imc->SwitchInputMethod(InputMethodSwitchTest::extBundleName, subName);
250 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
251 InputMethodSwitchTest::conditionVar.wait_for(
__anon96fe8e020302null252 lock, std::chrono::milliseconds(DEALY_TIME), [] { return InputMethodSwitchTest::imeChangeFlag == true; });
253 EXPECT_FALSE(InputMethodSwitchTest::imeChangeFlag);
254 std::shared_ptr<Property> property = imc->GetCurrentInputMethod();
255 ASSERT_TRUE(property != nullptr);
256 EXPECT_EQ(property->name, InputMethodSwitchTest::extBundleName);
257 auto subProperty = imc->GetCurrentInputMethodSubtype();
258 ASSERT_TRUE(subProperty != nullptr);
259 EXPECT_EQ(subProperty->id, InputMethodSwitchTest::extAbilityName);
260 EXPECT_EQ(subProperty->name, InputMethodSwitchTest::extBundleName);
261 }
262
263 /**
264 * @tc.name: testIMCSwitchInputMethodWithErrorBundleNameWithoutSubName
265 * @tc.desc: IMC testSwitchInputMethod.
266 * @tc.type: FUNC
267 * @tc.require: issuesI62BHB
268 * @tc.author: chenyu
269 */
270 HWTEST_F(InputMethodSwitchTest, testIMCSwitchInputMethodWithErrorBundleNameWithoutSubName, TestSize.Level0)
271 {
272 IMSA_HILOGI("IMC testIMCSwitchInputMethodWithErrorBundleNameWithoutSubName Test START");
273 sptr<InputMethodController> imc = InputMethodController::GetInstance();
274 ASSERT_TRUE(imc != nullptr);
275 std::string name = "error bundleName";
276 std::string subName;
277 int32_t ret = imc->SwitchInputMethod(name, subName);
278 EXPECT_EQ(ret, ErrorCode::ERROR_SWITCH_IME);
279 std::shared_ptr<Property> property = imc->GetCurrentInputMethod();
280 ASSERT_TRUE(property != nullptr);
281 EXPECT_EQ(property->name, InputMethodSwitchTest::extBundleName);
282 auto subProperty = imc->GetCurrentInputMethodSubtype();
283 ASSERT_TRUE(subProperty != nullptr);
284 EXPECT_EQ(subProperty->id, InputMethodSwitchTest::extAbilityName);
285 EXPECT_EQ(subProperty->name, InputMethodSwitchTest::extBundleName);
286 }
287
288 /**
289 * @tc.name: testIMCGetCurrentInputMethod
290 * @tc.desc: IMC GetCurrentInputMethod
291 * @tc.type: FUNC
292 * @tc.require: issuesI62BHB
293 * @tc.author: chenyu
294 */
295 HWTEST_F(InputMethodSwitchTest, testIMCGetCurrentInputMethod, TestSize.Level0)
296 {
297 IMSA_HILOGI("IMC testIMCGetCurrentInputMethod Test Start");
298 sptr<InputMethodController> imc = InputMethodController::GetInstance();
299 ASSERT_TRUE(imc != nullptr);
300 std::shared_ptr<Property> property = imc->GetCurrentInputMethod();
301 ASSERT_TRUE(property != nullptr);
302 EXPECT_EQ(property->name, InputMethodSwitchTest::extBundleName);
303 }
304
305 /**
306 * @tc.name: testIMCListInputMethod
307 * @tc.desc: IMC ListInputMethod
308 * @tc.type: FUNC
309 * @tc.require: issuesI62BHB
310 * @tc.author: chenyu
311 */
312 HWTEST_F(InputMethodSwitchTest, testIMCListInputMethod, TestSize.Level0)
313 {
314 IMSA_HILOGI("IMC testIMCListInputMethod Test Start");
315 sptr<InputMethodController> imc = InputMethodController::GetInstance();
316 ASSERT_TRUE(imc != nullptr);
317 std::vector<Property> properties = {};
318 auto ret = imc->ListInputMethod(properties);
319 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
320 EXPECT_FALSE(properties.empty());
321 bool hasExtInputMethod = false;
322 for (const auto &property : properties) {
323 if (property.name == InputMethodSwitchTest::extBundleName) {
324 hasExtInputMethod = true;
325 break;
326 }
327 }
328 EXPECT_TRUE(hasExtInputMethod);
329 }
330
331 /**
332 * @tc.name: testIMCListInputMethodDisable
333 * @tc.desc: IMC ListInputMethod
334 * @tc.type: FUNC
335 * @tc.require: issuesI62BHB
336 * @tc.author: chenyu
337 */
338 HWTEST_F(InputMethodSwitchTest, testIMCListInputMethodDisable, TestSize.Level0)
339 {
340 IMSA_HILOGI("IMC testIMCListInputMethodDisable Test Start");
341 sptr<InputMethodController> imc = InputMethodController::GetInstance();
342 ASSERT_TRUE(imc != nullptr);
343 std::vector<Property> disableProperties = {};
344 auto ret = imc->ListInputMethod(false, disableProperties);
345 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
346 bool hasExtInputMethod = false;
347 for (const auto &disableProperty : disableProperties) {
348 if (disableProperty.name == InputMethodSwitchTest::extBundleName) {
349 hasExtInputMethod = true;
350 break;
351 }
352 }
353 EXPECT_FALSE(hasExtInputMethod);
354 }
355
356 /**
357 * @tc.name: testIMCListInputMethodEnable
358 * @tc.desc: IMC ListInputMethod
359 * @tc.type: FUNC
360 * @tc.require: issuesI62BHB
361 * @tc.author: chenyu
362 */
363 HWTEST_F(InputMethodSwitchTest, testIMCListInputMethodEnable, TestSize.Level0)
364 {
365 IMSA_HILOGI("IMC testIMCListInputMethodEnable Test Start");
366 sptr<InputMethodController> imc = InputMethodController::GetInstance();
367 ASSERT_TRUE(imc != nullptr);
368 std::vector<Property> enableProperties = {};
369 auto ret = imc->ListInputMethod(true, enableProperties);
370 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
371 EXPECT_FALSE(enableProperties.empty());
372 bool hasExtInputMethod = false;
373 for (const auto &enableProperty : enableProperties) {
374 if (enableProperty.name == InputMethodSwitchTest::extBundleName) {
375 hasExtInputMethod = true;
376 break;
377 }
378 }
379 EXPECT_TRUE(hasExtInputMethod);
380 }
381
382 /**
383 * @tc.name: testIMCGetCurrentInputMethodSubtype
384 * @tc.desc: GetCurrentInputMethodSubtype
385 * @tc.type: FUNC
386 * @tc.require: issuesI62BHB
387 * @tc.author: chenyu
388 */
389 HWTEST_F(InputMethodSwitchTest, testIMCGetCurrentInputMethodSubtype, TestSize.Level0)
390 {
391 IMSA_HILOGI("IMC testIMCGetCurrentInputMethodSubtype Test Start");
392 sptr<InputMethodController> imc = InputMethodController::GetInstance();
393 ASSERT_TRUE(imc != nullptr);
394 auto subProperty = imc->GetCurrentInputMethodSubtype();
395 ASSERT_TRUE(subProperty != nullptr);
396 EXPECT_EQ(subProperty->id, InputMethodSwitchTest::extAbilityName);
397 EXPECT_EQ(subProperty->name, InputMethodSwitchTest::extBundleName);
398 }
399
400 /**
401 * @tc.name: testIMCListCurrentInputMethodSubtype
402 * @tc.desc: ListCurrentInputMethodSubtype
403 * @tc.type: FUNC
404 * @tc.require: issuesI62BHB
405 * @tc.author: chenyu
406 */
407 HWTEST_F(InputMethodSwitchTest, testIMCListCurrentInputMethodSubtype, TestSize.Level0)
408 {
409 IMSA_HILOGI("IMC testIMCListCurrentInputMethodSubtype Test Start");
410 sptr<InputMethodController> imc = InputMethodController::GetInstance();
411 ASSERT_TRUE(imc != nullptr);
412 std::vector<SubProperty> subProps = {};
413 auto ret = imc->ListCurrentInputMethodSubtype(subProps);
414 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
415 ASSERT_EQ(subProps.size(), EXT_INPUTMETHOD_SUBTYPE_NUM);
416 EXPECT_EQ(subProps[0].id, InputMethodSwitchTest::extAbilityName);
417 EXPECT_EQ(subProps[0].name, InputMethodSwitchTest::extBundleName);
418 }
419
420 /**
421 * @tc.name: testIMCListInputMethodSubtype
422 * @tc.desc: ListInputMethodSubtype
423 * @tc.type: FUNC
424 * @tc.require: issuesI62BHB
425 * @tc.author: chenyu
426 */
427 HWTEST_F(InputMethodSwitchTest, tesIMCtListInputMethodSubtype, TestSize.Level0)
428 {
429 IMSA_HILOGI("IMC testIMCListInputMethodSubtype Test Start");
430 sptr<InputMethodController> imc = InputMethodController::GetInstance();
431 ASSERT_TRUE(imc != nullptr);
432 Property property = { .name = InputMethodSwitchTest::extBundleName };
433 std::vector<SubProperty> subProps;
434 auto ret = imc->ListInputMethodSubtype(property, subProps);
435 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
436 ASSERT_EQ(subProps.size(), EXT_INPUTMETHOD_SUBTYPE_NUM);
437 EXPECT_EQ(subProps[0].id, InputMethodSwitchTest::extAbilityName);
438 EXPECT_EQ(subProps[0].name, InputMethodSwitchTest::extBundleName);
439 }
440
441 /**
442 * @tc.name: testIMCListInputMethodSubtypeWithErrorBundleName
443 * @tc.desc: IMC ListInputMethodSubtype
444 * @tc.type: FUNC
445 * @tc.require: issuesI62BHB
446 * @tc.author: chenyu
447 */
448 HWTEST_F(InputMethodSwitchTest, testIMCListInputMethodSubtypeWithErrorBundleName, TestSize.Level0)
449 {
450 IMSA_HILOGI("IMC testIMCListInputMethodSubtypeWitchErrorBundleName Test START");
451 std::shared_ptr<Property> property = std::make_shared<Property>();
452 std::vector<SubProperty> properties = {};
453 auto ret = InputMethodController::GetInstance()->ListInputMethodSubtype(*property, properties);
454 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
455 EXPECT_TRUE(properties.empty());
456 }
457
458 /**
459 * @tc.name: testShowOptionalInputMethod
460 * @tc.desc: IMC ShowOptionalInputMethod
461 * @tc.type: FUNC
462 */
463 HWTEST_F(InputMethodSwitchTest, testShowOptionalInputMethod, TestSize.Level2)
464 {
465 IMSA_HILOGI("IMC ShowOptionalInputMethod Test START");
466 sptr<InputMethodController> imc = InputMethodController::GetInstance();
467 ASSERT_TRUE(imc != nullptr);
468 int32_t ret = imc->ShowOptionalInputMethod();
469 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
470 }
471
472 /**
473 * @tc.name: testDisplayOptionalInputMethod
474 * @tc.desc: IMC DisplayOptionalInputMethod
475 * @tc.type: FUNC
476 */
477 HWTEST_F(InputMethodSwitchTest, testDisplayOptionalInputMethod, TestSize.Level2)
478 {
479 IMSA_HILOGI("IMC DisplayOptionalInputMethod Test START");
480
481 sptr<InputMethodController> imc = InputMethodController::GetInstance();
482 ASSERT_TRUE(imc != nullptr);
483 sleep(2);
484 int32_t ret = imc->DisplayOptionalInputMethod();
485 EXPECT_EQ(ret, ErrorCode::NO_ERROR);
486 }
487 } // namespace MiscServices
488 } // namespace OHOS
489