/* * Copyright (C) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include #include "global.h" #include "ime_event_monitor_manager_impl.h" #include "ime_setting_listener_test_impl.h" #include "input_method_controller.h" #include "input_method_property.h" #include "tdd_util.h" using namespace testing::ext; namespace OHOS { namespace MiscServices { class InputMethodSwitchTest : public testing::Test { public: static void SetUpTestCase(void); static void TearDownTestCase(void); void SetUp(); void TearDown(); static void CheckCurrentProp(const std::string &extName); static void CheckCurrentSubProp(const std::string &extName); static void CheckCurrentSubProps(); static sptr imc_; static std::string newImeBundleName; static std::vector newImeSubName; static std::string bundleName; static std::vector extName; static std::vector language; static std::vector locale; static std::string beforeValue; static std::string allEnableIme; }; sptr InputMethodSwitchTest::imc_; std::string InputMethodSwitchTest::newImeBundleName = "com.example.newTestIme"; std::vector InputMethodSwitchTest::newImeSubName{ "lowerInput", "upperInput", "chineseInput" }; std::string InputMethodSwitchTest::bundleName = "com.example.testIme"; std::vector InputMethodSwitchTest::extName{ "InputMethodExtAbility", "InputMethodExtAbility2" }; std::vector InputMethodSwitchTest::language{ "chinese", "english" }; std::vector InputMethodSwitchTest::locale{ "zh-CN", "en-US" }; std::string InputMethodSwitchTest::beforeValue; std::string InputMethodSwitchTest::allEnableIme = "{\"enableImeList\" : {\"100\" : [ \"com.example.newTestIme\", " "\"com.example.testIme\"]}}"; constexpr uint32_t IME_EXT_NUM = 2; constexpr uint32_t NEW_IME_SUBTYPE_NUM = 3; constexpr uint32_t TOTAL_IME_MIN_NUM = 2; constexpr uint32_t ENABLE_IME_NUM = 1; constexpr uint32_t WAIT_IME_READY_TIME = 1; constexpr const char *ENABLE_IME_KEYWORD = "settings.inputmethod.enable_ime"; void InputMethodSwitchTest::SetUpTestCase(void) { IMSA_HILOGI("InputMethodSwitchTest::SetUpTestCase"); TddUtil::GrantNativePermission(); int32_t ret = TddUtil::GetEnableData(beforeValue); if (ret == ErrorCode::NO_ERROR) { IMSA_HILOGI("Enable ime switch test."); TddUtil::PushEnableImeValue(ENABLE_IME_KEYWORD, allEnableIme); } TddUtil::StorageSelfTokenID(); TddUtil::SetTestTokenID(TddUtil::AllocTestTokenID(true, "ohos.inputMethod.test", { "ohos.permission.CONNECT_IME_ABILITY", "ohos.permission.INJECT_INPUT_EVENT" })); imc_ = InputMethodController::GetInstance(); auto listener = std::make_shared(); ImeEventMonitorManagerImpl::GetInstance().RegisterImeEventListener(EVENT_IME_CHANGE_MASK, listener); } void InputMethodSwitchTest::TearDownTestCase(void) { IMSA_HILOGI("InputMethodSwitchTest::TearDownTestCase"); TddUtil::GrantNativePermission(); TddUtil::PushEnableImeValue(ENABLE_IME_KEYWORD, beforeValue); InputMethodController::GetInstance()->Close(); TddUtil::RestoreSelfTokenID(); } void InputMethodSwitchTest::SetUp(void) { IMSA_HILOGI("InputMethodSwitchTest::SetUp"); } void InputMethodSwitchTest::TearDown(void) { IMSA_HILOGI("InputMethodSwitchTest::TearDown"); } void InputMethodSwitchTest::CheckCurrentProp(const std::string &extName) { std::shared_ptr property = imc_->GetCurrentInputMethod(); ASSERT_TRUE(property != nullptr); EXPECT_EQ(property->name, bundleName); EXPECT_EQ(property->id, extName); } void InputMethodSwitchTest::CheckCurrentSubProp(const std::string &extName) { auto subProperty = imc_->GetCurrentInputMethodSubtype(); ASSERT_TRUE(subProperty != nullptr); EXPECT_EQ(subProperty->id, extName); EXPECT_EQ(subProperty->name, bundleName); } void InputMethodSwitchTest::CheckCurrentSubProps() { std::vector subProps; auto ret = imc_->ListCurrentInputMethodSubtype(subProps); EXPECT_EQ(ret, ErrorCode::NO_ERROR); ASSERT_EQ(subProps.size(), IME_EXT_NUM); for (uint32_t i = 0; i < IME_EXT_NUM; i++) { EXPECT_EQ(subProps[i].id, extName[i]); EXPECT_EQ(subProps[i].name, bundleName); EXPECT_EQ(subProps[i].language, language[i]); EXPECT_EQ(subProps[i].locale, locale[i]); } } /** * @tc.name: testImeSwitch * @tc.desc: switch to testIme * @tc.type: FUNC * @tc.require: issuesI62BHB * @tc.author: chenyu */ HWTEST_F(InputMethodSwitchTest, testImeSwitch, TestSize.Level0) { IMSA_HILOGI("oldIme testImeSwitch Test START"); ImeSettingListenerTestImpl::ResetParam(); // switch to ext testIme auto ret = imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, bundleName); EXPECT_EQ(ret, ErrorCode::NO_ERROR); EXPECT_TRUE(ImeSettingListenerTestImpl::WaitImeChange()); CheckCurrentProp(extName[0]); CheckCurrentSubProp(extName[0]); CheckCurrentSubProps(); sleep(WAIT_IME_READY_TIME); } /** * @tc.name: testSubTypeSwitch_001 * @tc.desc: switch subtype with extName1 * @tc.type: FUNC * @tc.require: issuesI62BHB * @tc.author: chenyu */ HWTEST_F(InputMethodSwitchTest, testSubTypeSwitch_001, TestSize.Level0) { IMSA_HILOGI("oldIme testSubTypeSwitch_001 Test START"); ImeSettingListenerTestImpl::ResetParam(); int32_t ret = imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, bundleName, extName[0]); EXPECT_EQ(ret, ErrorCode::NO_ERROR); EXPECT_TRUE(ImeSettingListenerTestImpl::WaitImeChange()); CheckCurrentProp(extName[0]); CheckCurrentSubProp(extName[0]); CheckCurrentSubProps(); } /** * @tc.name: testSubTypeSwitch_002 * @tc.desc: switch subtype with extName2 * @tc.type: FUNC * @tc.require: issuesI62BHB * @tc.author: chenyu */ HWTEST_F(InputMethodSwitchTest, testSubTypeSwitch_002, TestSize.Level0) { IMSA_HILOGI("oldIme testSubTypeSwitch_002 Test START"); ImeSettingListenerTestImpl::ResetParam(); int32_t ret = imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, bundleName, extName[1]); EXPECT_EQ(ret, ErrorCode::NO_ERROR); EXPECT_TRUE(ImeSettingListenerTestImpl::WaitImeChange()); CheckCurrentProp(extName[0]); CheckCurrentSubProp(extName[1]); CheckCurrentSubProps(); } /** * @tc.name: testSubTypeSwitch_003 * @tc.desc: switch subtype with extName1 * @tc.type: FUNC * @tc.require: issuesI62BHB * @tc.author: chenyu */ HWTEST_F(InputMethodSwitchTest, testSubTypeSwitch_003, TestSize.Level0) { IMSA_HILOGI("oldIme testSubTypeSwitch_003 Test START"); ImeSettingListenerTestImpl::ResetParam(); int32_t ret = imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, bundleName, extName[0]); EXPECT_EQ(ret, ErrorCode::NO_ERROR); EXPECT_TRUE(ImeSettingListenerTestImpl::WaitImeChange()); CheckCurrentProp(extName[0]); CheckCurrentSubProp(extName[0]); CheckCurrentSubProps(); } /** * @tc.name: testSubTypeSwitchWithErrorSubName * @tc.desc: switch subtype with error subName. * @tc.type: FUNC * @tc.require: issuesI62BHB * @tc.author: chenyu */ HWTEST_F(InputMethodSwitchTest, testSubTypeSwitchWithErrorSubName, TestSize.Level0) { IMSA_HILOGI("oldIme testSubTypeSwitchWithErrorSubName Test START"); std::string subName = InputMethodSwitchTest::imc_->GetCurrentInputMethodSubtype()->id; int32_t ret = imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, bundleName, "error subName"); EXPECT_EQ(ret, ErrorCode::ERROR_BAD_PARAMETERS); CheckCurrentProp(subName); CheckCurrentSubProp(subName); CheckCurrentSubProps(); } /** * @tc.name: testSwitchToCurrentImeWithEmptySubName * @tc.desc: switch to currentIme witch empty subName. * @tc.type: FUNC * @tc.require: issuesI62BHB * @tc.author: chenyu */ HWTEST_F(InputMethodSwitchTest, testSwitchToCurrentImeWithEmptySubName, TestSize.Level0) { IMSA_HILOGI("oldIme testSwitchToCurrentImeWithEmptySubName Test START"); ImeSettingListenerTestImpl::ResetParam(); std::string subName = InputMethodSwitchTest::imc_->GetCurrentInputMethodSubtype()->id; int32_t ret = imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, bundleName); EXPECT_EQ(ret, ErrorCode::NO_ERROR); EXPECT_TRUE(ImeSettingListenerTestImpl::WaitImeChange()); CheckCurrentProp(subName); CheckCurrentSubProp(subName); CheckCurrentSubProps(); } /** * @tc.name: testSwitchImeWithErrorBundleName * @tc.desc: switch ime witch error bundleName * @tc.type: FUNC * @tc.require: issuesI62BHB * @tc.author: chenyu */ HWTEST_F(InputMethodSwitchTest, testSwitchImeWithErrorBundleName, TestSize.Level0) { IMSA_HILOGI("oldIme testSwitchImeWithErrorBundleName Test START"); std::string subName = InputMethodSwitchTest::imc_->GetCurrentInputMethodSubtype()->id; int32_t ret = imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, "error bundleName", extName[0]); EXPECT_TRUE(ret == ErrorCode::ERROR_ENABLE_IME || ret == ErrorCode::ERROR_BAD_PARAMETERS); CheckCurrentProp(subName); CheckCurrentSubProp(subName); CheckCurrentSubProps(); } /** * @tc.name: testSwitchImeWithErrorBundleNameWitchEmptySubName * @tc.desc: switch ime witch error bundleName and empty subName * @tc.type: FUNC * @tc.require: issuesI62BHB * @tc.author: chenyu */ HWTEST_F(InputMethodSwitchTest, testSwitchImeWithErrorBundleNameWitchEmptySubName, TestSize.Level0) { IMSA_HILOGI("oldIme testSwitchImeWithErrorBundleNameWitchEmptySubName Test START"); std::string subName = InputMethodSwitchTest::imc_->GetCurrentInputMethodSubtype()->id; int32_t ret = imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, "error bundleName", " "); EXPECT_TRUE(ret == ErrorCode::ERROR_ENABLE_IME || ret == ErrorCode::ERROR_BAD_PARAMETERS); CheckCurrentProp(subName); CheckCurrentSubProp(subName); CheckCurrentSubProps(); } /** * @tc.name: testIMCListInputMethod * @tc.desc: IMC ListInputMethod * @tc.type: FUNC * @tc.require: issuesI62BHB * @tc.author: chenyu */ HWTEST_F(InputMethodSwitchTest, testIMCListInputMethod, TestSize.Level0) { IMSA_HILOGI("IMC testIMCListInputMethod Test Start"); std::vector properties = {}; auto ret = imc_->ListInputMethod(properties); EXPECT_EQ(ret, ErrorCode::NO_ERROR); EXPECT_TRUE(properties.size() >= TOTAL_IME_MIN_NUM); bool hasIme = false; bool hasNewIme = false; for (const auto &property : properties) { if (property.name == bundleName) { hasIme = true; } if (property.name == newImeBundleName) { hasNewIme = true; } } EXPECT_TRUE(hasIme && hasNewIme); } /** * @tc.name: testIMCListInputMethodDisable * @tc.desc: IMC ListInputMethod * @tc.type: FUNC * @tc.require: issuesI62BHB * @tc.author: chenyu */ HWTEST_F(InputMethodSwitchTest, testIMCListInputMethodDisable, TestSize.Level0) { IMSA_HILOGI("IMC testIMCListInputMethodDisable Test Start"); std::vector disableProperties = {}; auto ret = imc_->ListInputMethod(false, disableProperties); EXPECT_EQ(ret, ErrorCode::NO_ERROR); EXPECT_GE(disableProperties.size(), 0); } /** * @tc.name: testIMCListInputMethodEnable * @tc.desc: IMC ListInputMethod * @tc.type: FUNC * @tc.require: issuesI62BHB * @tc.author: chenyu */ HWTEST_F(InputMethodSwitchTest, testIMCListInputMethodEnable, TestSize.Level0) { IMSA_HILOGI("IMC testIMCListInputMethodEnable Test Start"); std::string subName = InputMethodSwitchTest::imc_->GetCurrentInputMethodSubtype()->id; std::vector enableProperties = {}; auto ret = imc_->ListInputMethod(true, enableProperties); EXPECT_EQ(ret, ErrorCode::NO_ERROR); EXPECT_GE(enableProperties.size(), ENABLE_IME_NUM); } /** * @tc.name: tesIMCtListInputMethodSubtype_001 * @tc.desc: ListInputMethodSubtype * @tc.type: FUNC * @tc.require: issuesI62BHB * @tc.author: chenyu */ HWTEST_F(InputMethodSwitchTest, tesIMCtListInputMethodSubtype_001, TestSize.Level0) { IMSA_HILOGI("IMC tesIMCtListInputMethodSubtype_001 Test Start"); Property property = { .name = newImeBundleName }; std::vector subProps; auto ret = imc_->ListInputMethodSubtype(property, subProps); EXPECT_EQ(ret, ErrorCode::NO_ERROR); ASSERT_EQ(subProps.size(), NEW_IME_SUBTYPE_NUM); for (uint32_t i = 0; i < NEW_IME_SUBTYPE_NUM; i++) { EXPECT_EQ(subProps[i].id, newImeSubName[i]); EXPECT_EQ(subProps[i].name, newImeBundleName); } } /** * @tc.name: tesIMCtListInputMethodSubtype_002 * @tc.desc: ListInputMethodSubtype * @tc.type: FUNC * @tc.require: issuesI62BHB * @tc.author: chenyu */ HWTEST_F(InputMethodSwitchTest, tesIMCtListInputMethodSubtype_002, TestSize.Level0) { IMSA_HILOGI("IMC tesIMCtListInputMethodSubtype_002 Test Start"); Property property = { .name = bundleName }; std::vector subProps; auto ret = imc_->ListInputMethodSubtype(property, subProps); EXPECT_EQ(ret, ErrorCode::NO_ERROR); ASSERT_EQ(subProps.size(), IME_EXT_NUM); for (uint32_t i = 0; i < IME_EXT_NUM; i++) { EXPECT_EQ(subProps[i].id, extName[i]); EXPECT_EQ(subProps[i].name, bundleName); } } /** * @tc.name: testIMCListInputMethodSubtypeWithErrorBundleName * @tc.desc: IMC ListInputMethodSubtype * @tc.type: FUNC * @tc.require: issuesI62BHB * @tc.author: chenyu */ HWTEST_F(InputMethodSwitchTest, testIMCListInputMethodSubtypeWithErrorBundleName, TestSize.Level0) { IMSA_HILOGI("IMC testIMCListInputMethodSubtypeWitchErrorBundleName Test START"); std::shared_ptr property = std::make_shared(); std::vector properties = {}; auto ret = imc_->ListInputMethodSubtype(*property, properties); EXPECT_EQ(ret, ErrorCode::ERROR_BAD_PARAMETERS); EXPECT_TRUE(properties.empty()); } /** * @tc.name: testShowOptionalInputMethod * @tc.desc: IMC ShowOptionalInputMethod * @tc.type: FUNC */ HWTEST_F(InputMethodSwitchTest, testShowOptionalInputMethod, TestSize.Level2) { IMSA_HILOGI("IMC ShowOptionalInputMethod Test START"); int32_t ret = imc_->ShowOptionalInputMethod(); EXPECT_EQ(ret, ErrorCode::NO_ERROR); } /** * @tc.name: testDisplayOptionalInputMethod * @tc.desc: IMC DisplayOptionalInputMethod * @tc.type: FUNC */ HWTEST_F(InputMethodSwitchTest, testDisplayOptionalInputMethod, TestSize.Level2) { IMSA_HILOGI("IMC DisplayOptionalInputMethod Test START"); sleep(2); int32_t ret = imc_->DisplayOptionalInputMethod(); EXPECT_EQ(ret, ErrorCode::NO_ERROR); } /** * @tc.name: testCombinationKeySwitchIme_001 * @tc.desc: switch ime by combination key. * @tc.type: FUNC * @tc.require: issuesI8RPP3 * @tc.author: mashaoyin */ HWTEST_F(InputMethodSwitchTest, testCombinationKeySwitchIme_001, TestSize.Level0) { IMSA_HILOGI("testCombinationKeySwitchIme_001 Test START"); ImeSettingListenerTestImpl::ResetParam(); std::shared_ptr property = imc_->GetCurrentInputMethod(); std::string result; static std::string cmd = "uinput -K -d 2076 -d 2050"; auto ret = TddUtil::ExecuteCmd(cmd, result); EXPECT_TRUE(ret); EXPECT_TRUE(ImeSettingListenerTestImpl::WaitImeChange()); imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, property->name, ""); } /** * @tc.name: testCombinationKeySwitchIme_002 * @tc.desc: switch ime by combination key. * @tc.type: FUNC * @tc.require: issuesI8RPP3 * @tc.author: mashaoyin */ HWTEST_F(InputMethodSwitchTest, testCombinationKeySwitchIme_002, TestSize.Level0) { IMSA_HILOGI("testCombinationKeySwitchIme_002 Test START"); ImeSettingListenerTestImpl::ResetParam(); std::shared_ptr property = imc_->GetCurrentInputMethod(); std::string result; static std::string cmd = "uinput -K -d 2077 -d 2050"; auto ret = TddUtil::ExecuteCmd(cmd, result); EXPECT_TRUE(ret); EXPECT_TRUE(ImeSettingListenerTestImpl::WaitImeChange()); imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, property->name, ""); } /** * @tc.name: testCombinationKeySwitchIme_003 * @tc.desc: switch ime by combination key. * @tc.type: FUNC * @tc.require: issuesI8RPP3 * @tc.author: mashaoyin */ HWTEST_F(InputMethodSwitchTest, testCombinationKeySwitchIme_003, TestSize.Level0) { IMSA_HILOGI("testCombinationKeySwitchIme_003 Test START"); ImeSettingListenerTestImpl::ResetParam(); std::shared_ptr property = imc_->GetCurrentInputMethod(); std::vector props; imc_->ListInputMethod(true, props); std::string result; static std::string cmd = "uinput -K -d 2077 -d 2050 -u 2050 -u 2077"; for (auto iter = 0; iter < props.size(); ++iter) { auto ret = TddUtil::ExecuteCmd(cmd, result); EXPECT_TRUE(ret); } EXPECT_TRUE(ImeSettingListenerTestImpl::WaitTargetImeChange(property->name)); std::shared_ptr curProperty = imc_->GetCurrentInputMethod(); EXPECT_EQ(property->name, curProperty->name); imc_->SwitchInputMethod(SwitchTrigger::CURRENT_IME, property->name, ""); } } // namespace MiscServices } // namespace OHOS