diff --git a/services/adapter/keyboard/BUILD.gn b/services/adapter/keyboard/BUILD.gn index cac9aca96..3a6ce21fa 100644 --- a/services/adapter/keyboard/BUILD.gn +++ b/services/adapter/keyboard/BUILD.gn @@ -24,6 +24,7 @@ config("inputmethod_adapter_native_config") { ohos_static_library("keboard_event_static") { sources = [ + "src/combination_key.cpp", "src/input_event_callback.cpp", "src/keyboard_event.cpp", ] diff --git a/services/adapter/keyboard/include/combination_key.h b/services/adapter/keyboard/include/combination_key.h new file mode 100644 index 000000000..e2cbc00f0 --- /dev/null +++ b/services/adapter/keyboard/include/combination_key.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 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. + */ + +#ifndef INPUTMETHOD_IMF_COMBINATION_KEY_H +#define INPUTMETHOD_IMF_COMBINATION_KEY_H + +#include + +namespace OHOS { +namespace MiscServices { +enum class CombinationKeyFunction { SWITCH_LANGUAGE = 0, SWITCH_MODE, SWITCH_IME }; + +class CombinationKey { +public: + static bool IsMatch(CombinationKeyFunction combinationKey, uint32_t state); +}; +} // namespace MiscServices +} // namespace OHOS + +#endif // INPUTMETHOD_IMF_COMBINATION_KEY_H diff --git a/services/adapter/keyboard/include/input_event_callback.h b/services/adapter/keyboard/include/input_event_callback.h index 1612fbe39..6f2493574 100644 --- a/services/adapter/keyboard/include/input_event_callback.h +++ b/services/adapter/keyboard/include/input_event_callback.h @@ -36,6 +36,7 @@ public: private: KeyHandle keyHandler_ = nullptr; static uint32_t keyState_; + static bool isKeyHandled_; }; } // namespace MiscServices } // namespace OHOS diff --git a/services/adapter/keyboard/include/keyboard_event.h b/services/adapter/keyboard/include/keyboard_event.h index 2ad7df159..5e4503482 100644 --- a/services/adapter/keyboard/include/keyboard_event.h +++ b/services/adapter/keyboard/include/keyboard_event.h @@ -18,7 +18,6 @@ #include #include -#include #include "global.h" #include "key_event.h" @@ -36,10 +35,6 @@ public: static constexpr uint8_t CTRL_LEFT_MASK = 0X1 << 2; static constexpr uint8_t CTRL_RIGHT_MASK = 0X1 << 3; static constexpr uint8_t CAPS_MASK = 0X1 << 4; - static constexpr bool IS_KEYS_DOWN(uint32_t state, uint8_t mask) - { - return state == mask; - } private: static constexpr int32_t PRESS_KEY_DELAY_MS = 200; diff --git a/services/adapter/keyboard/src/combination_key.cpp b/services/adapter/keyboard/src/combination_key.cpp new file mode 100644 index 000000000..c78b2cae1 --- /dev/null +++ b/services/adapter/keyboard/src/combination_key.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022 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 "combination_key.h" + +#include +#include + +#include "keyboard_event.h" + +namespace OHOS { +namespace MiscServices { +const std::map> COMBINATION_KEY_MAP{ + { CombinationKeyFunction::SWITCH_LANGUAGE, { KeyboardEvent::SHIFT_LEFT_MASK, KeyboardEvent::SHIFT_RIGHT_MASK } }, + { CombinationKeyFunction::SWITCH_IME, + { + KeyboardEvent::SHIFT_LEFT_MASK | KeyboardEvent::CTRL_LEFT_MASK, + KeyboardEvent::SHIFT_RIGHT_MASK | KeyboardEvent::CTRL_RIGHT_MASK, + KeyboardEvent::SHIFT_LEFT_MASK | KeyboardEvent::CTRL_RIGHT_MASK, + KeyboardEvent::SHIFT_RIGHT_MASK | KeyboardEvent::CTRL_LEFT_MASK, + } }, + { CombinationKeyFunction::SWITCH_MODE, { KeyboardEvent::CAPS_MASK } }, +}; + +bool CombinationKey::IsMatch(CombinationKeyFunction combinationKey, uint32_t state) +{ + IMSA_HILOGD("combinationKey: %{public}d, state: %{public}d", combinationKey, state); + auto expectedKeys = COMBINATION_KEY_MAP.find(combinationKey); + if (expectedKeys == COMBINATION_KEY_MAP.end()) { + IMSA_HILOGD("known key function"); + return false; + } + return expectedKeys->second.find(state) != expectedKeys->second.end(); +} +} // namespace MiscServices +} // namespace OHOS \ No newline at end of file diff --git a/services/adapter/keyboard/src/input_event_callback.cpp b/services/adapter/keyboard/src/input_event_callback.cpp index 3d2134050..fdae509e9 100644 --- a/services/adapter/keyboard/src/input_event_callback.cpp +++ b/services/adapter/keyboard/src/input_event_callback.cpp @@ -20,6 +20,7 @@ namespace OHOS { namespace MiscServices { uint32_t InputEventCallback::keyState_ = static_cast(0); +bool InputEventCallback::isKeyHandled_ = false; const std::map MASK_MAP{ { MMI::KeyEvent::KEYCODE_SHIFT_LEFT, KeyboardEvent::SHIFT_LEFT_MASK }, { MMI::KeyEvent::KEYCODE_SHIFT_RIGHT, KeyboardEvent::SHIFT_RIGHT_MASK }, @@ -35,6 +36,7 @@ void InputEventCallback::OnInputEvent(std::shared_ptr keyEvent) c auto currKey = MASK_MAP.find(keyCode); if (currKey == MASK_MAP.end()) { IMSA_HILOGD("key code unknown"); + keyState_ = 0; return; } IMSA_HILOGD("keyCode: %{public}d, keyAction: %{public}d", keyCode, keyAction); @@ -42,14 +44,24 @@ void InputEventCallback::OnInputEvent(std::shared_ptr keyEvent) c if (keyAction == MMI::KeyEvent::KEY_ACTION_DOWN) { IMSA_HILOGD("key %{public}d pressed down", keyCode); keyState_ = static_cast(keyState_ | currKey->second); + if (keyCode == MMI::KeyEvent::KEYCODE_CAPS_LOCK) { + if (keyHandler_ != nullptr) { + int32_t ret = keyHandler_(keyState_); + IMSA_HILOGI("handle key event ret: %{public}d", ret); + } + isKeyHandled_ = true; + return; + } + isKeyHandled_ = false; return; } if (keyAction == MMI::KeyEvent::KEY_ACTION_UP) { - if (keyHandler_ != nullptr) { + if (keyHandler_ != nullptr && !isKeyHandled_) { int32_t ret = keyHandler_(keyState_); IMSA_HILOGI("handle key event ret: %{public}d", ret); } + isKeyHandled_ = true; keyState_ = static_cast(keyState_ & ~currKey->second); } } diff --git a/services/include/input_method_system_ability.h b/services/include/input_method_system_ability.h index 657ac53e6..9c23de782 100644 --- a/services/include/input_method_system_ability.h +++ b/services/include/input_method_system_ability.h @@ -28,7 +28,6 @@ #include "input_method_system_ability_stub.h" #include "inputmethod_dump.h" #include "inputmethod_trace.h" -#include "keyboard_event.h" #include "peruser_session.h" #include "system_ability.h" diff --git a/services/src/input_method_system_ability.cpp b/services/src/input_method_system_ability.cpp index f31c14804..82889d069 100644 --- a/services/src/input_method_system_ability.cpp +++ b/services/src/input_method_system_ability.cpp @@ -23,6 +23,7 @@ #include "ability_manager_interface.h" #include "application_info.h" #include "bundle_mgr_proxy.h" +#include "combination_key.h" #include "common_event_support.h" #include "errors.h" #include "global.h" @@ -431,7 +432,7 @@ int32_t InputMethodSystemAbility::ListDisabledInputMethod(int32_t userId, std::v return ErrorCode::ERROR_NULL_POINTER; } for (auto iter = props.begin(); iter != props.end();) { - if (iter->name == filter->name && iter->id == filter->id) { + if (iter->name == filter->name) { iter = props.erase(iter); continue; } @@ -996,30 +997,26 @@ int32_t InputMethodSystemAbility::SwitchByCombinationKey(uint32_t state) IMSA_HILOGE("GetCurrentInputMethodSubtype failed"); return ErrorCode::ERROR_EX_NULL_POINTER; } - if (KeyboardEvent::IS_KEYS_DOWN(state, KeyboardEvent::CAPS_MASK)) { - IMSA_HILOGI("CAPS press"); - auto target = current->mode == "upper" ? - FindSubPropertyByCompare(current->id, - [¤t](const SubProperty &property) { return property.mode == "lower"; }) : - FindSubPropertyByCompare(current->id, - [¤t](const SubProperty &property) { return property.mode == "upper"; }); + if (CombinationKey::IsMatch(CombinationKeyFunction::SWITCH_MODE, state)) { + IMSA_HILOGI("switch mode"); + auto target = current->mode == "upper" + ? FindSubPropertyByCompare(current->id, + [¤t](const SubProperty &property) { return property.mode == "lower"; }) + : FindSubPropertyByCompare(current->id, + [¤t](const SubProperty &property) { return property.mode == "upper"; }); return SwitchInputMethod(target.id, target.label); } - if (KeyboardEvent::IS_KEYS_DOWN(state, KeyboardEvent::SHIFT_LEFT_MASK) || - KeyboardEvent::IS_KEYS_DOWN(state, KeyboardEvent::SHIFT_RIGHT_MASK)) { - IMSA_HILOGI("SHIFT press"); - auto target = current->language == "chinese" ? - FindSubPropertyByCompare(current->id, - [¤t](const SubProperty &property) { return property.language == "english"; }) : - FindSubPropertyByCompare(current->id, - [¤t](const SubProperty &property) { return property.language == "chinese"; }); + if (CombinationKey::IsMatch(CombinationKeyFunction::SWITCH_LANGUAGE, state)) { + IMSA_HILOGI("switch language"); + auto target = current->language == "chinese" + ? FindSubPropertyByCompare(current->id, + [¤t](const SubProperty &property) { return property.language == "english"; }) + : FindSubPropertyByCompare(current->id, + [¤t](const SubProperty &property) { return property.language == "chinese"; }); return SwitchInputMethod(target.id, target.label); } - if (KeyboardEvent::IS_KEYS_DOWN(state, KeyboardEvent::CTRL_LEFT_MASK | KeyboardEvent::SHIFT_LEFT_MASK) || - KeyboardEvent::IS_KEYS_DOWN(state, KeyboardEvent::CTRL_LEFT_MASK | KeyboardEvent::SHIFT_RIGHT_MASK) || - KeyboardEvent::IS_KEYS_DOWN(state, KeyboardEvent::CTRL_RIGHT_MASK | KeyboardEvent::SHIFT_LEFT_MASK) || - KeyboardEvent::IS_KEYS_DOWN(state, KeyboardEvent::CTRL_RIGHT_MASK | KeyboardEvent::SHIFT_RIGHT_MASK)) { - IMSA_HILOGI("CTRL_SHIFT press"); + if (CombinationKey::IsMatch(CombinationKeyFunction::SWITCH_IME, state)) { + IMSA_HILOGI("switch ime"); std::vector props = {}; auto ret = ListProperty(MAIN_USER_ID, props); if (ret != ErrorCode::NO_ERROR) {