diff --git a/frameworks/js/napi/inputmethodability/js_text_input_client_engine.cpp b/frameworks/js/napi/inputmethodability/js_text_input_client_engine.cpp index 89edb741653904160b989e1b562432a3312d94dd..33fcb2c6fe868c05fe6e5c19fd02a74100dc547b 100644 --- a/frameworks/js/napi/inputmethodability/js_text_input_client_engine.cpp +++ b/frameworks/js/napi/inputmethodability/js_text_input_client_engine.cpp @@ -36,7 +36,6 @@ namespace MiscServices { using namespace std::chrono; thread_local napi_ref JsTextInputClientEngine::TICRef_ = nullptr; const std::string JsTextInputClientEngine::TIC_CLASS_NAME = "TextInputClient"; -constexpr int32_t DEVICE_TYPE_2IN1 = 7; constexpr int32_t MAX_WAIT_TIME = 5000; constexpr int32_t MAX_WAIT_TIME_PRIVATE_COMMAND = 2000; constexpr int32_t MAX_WAIT_TIME_MESSAGE_HANDLER = 2000; @@ -1352,10 +1351,9 @@ napi_value JsTextInputClientEngine::GetAttachOptions(napi_env env, napi_callback { IMSA_HILOGD("GetAttachOptions requestKeyboardReason:%{public}d.", InputMethodAbility::GetInstance().GetRequestKeyboardReason()); - bool flag = IsTargetDeviceType(DEVICE_TYPE_2IN1); - if (!flag) { + if (!InputMethodAbility::GetInstance().IsCapacityTypeSupported(CapacityType::REQUEST_KEYBOARD_REASON)) { JsUtils::ThrowException( - env, JsUtils::Convert(ErrorCode::ERROR_DEVICE_UNSUPPORTED), "only 2in1 supported!", TYPE_NONE); + env, JsUtils::Convert(ErrorCode::ERROR_DEVICE_UNSUPPORTED), "device is not supported!", TYPE_NONE); return JsUtil::Const::Null(env); } AttachOptions attachOptions; @@ -1378,9 +1376,10 @@ napi_value JsTextInputClientEngine::Subscribe(napi_env env, napi_callback_info i IMSA_HILOGE("subscribe failed, type: %{public}s.", type.c_str()); return nullptr; } - if (type == "attachOptionsDidChange" && !IsTargetDeviceType(DEVICE_TYPE_2IN1)) { + if (type == "attachOptionsDidChange" && + !InputMethodAbility::GetInstance().IsCapacityTypeSupported(CapacityType::REQUEST_KEYBOARD_REASON)) { JsUtils::ThrowException( - env, JsUtils::Convert(ErrorCode::ERROR_DEVICE_UNSUPPORTED), "only 2in1 supported!", TYPE_NONE); + env, JsUtils::Convert(ErrorCode::ERROR_DEVICE_UNSUPPORTED), "device is not supported!", TYPE_NONE); return JsUtil::Const::Null(env); } IMSA_HILOGD("subscribe type:%{public}s.", type.c_str()); diff --git a/frameworks/native/inputmethod_ability/include/input_method_ability.h b/frameworks/native/inputmethod_ability/include/input_method_ability.h index d212c80f2efed16ce27ae65f4c6f124c2058eda6..277fde38e75d8adfab010e4669b7da3031bb4304 100644 --- a/frameworks/native/inputmethod_ability/include/input_method_ability.h +++ b/frameworks/native/inputmethod_ability/include/input_method_ability.h @@ -111,6 +111,7 @@ public: bool HandleUnconsumedKey(const std::shared_ptr &keyEvent); int32_t OnResponse(uint64_t msgId, int32_t code, const ResponseData &data); int32_t IsCapacitySupport(int32_t capacity, bool &isSupport); + bool IsCapacityTypeSupported(CapacityType type); public: /* called from TaskManager worker thread */ diff --git a/frameworks/native/inputmethod_ability/include/input_method_panel.h b/frameworks/native/inputmethod_ability/include/input_method_panel.h index 3ceef7cabe50a952dede983d1089df9544b61bd1..1e65242097b04d55680a75d96d29baa77fc94967 100644 --- a/frameworks/native/inputmethod_ability/include/input_method_panel.h +++ b/frameworks/native/inputmethod_ability/include/input_method_panel.h @@ -186,7 +186,6 @@ private: int32_t FullScreenPrepare(Rosen::KeyboardLayoutParams ¶m); int32_t NormalImePrepare(Rosen::KeyboardLayoutParams ¶m); int32_t PrepareAdjustLayout(Rosen::KeyboardLayoutParams ¶m); - bool IsImmersiveEffectSupported(); Rosen::KeyboardEffectOption ConvertToWmEffect(ImmersiveMode mode, const ImmersiveEffect &effect); void SetImmersiveEffectToNone(); void UpdateImmersiveHotArea(); diff --git a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp index 0c4a5317525390afac7aeb7007e17d0731a3377b..332c2dfd33f6b7fae87030e31483df8915075496 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_ability.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_ability.cpp @@ -1832,5 +1832,42 @@ int32_t InputMethodAbility::IsCapacitySupport(int32_t capacity, bool &isSupport) return proxy->IsCapacitySupport(capacity, isSupport); } + +bool InputMethodAbility::IsCapacityTypeSupported(CapacityType type) +{ + static std::unordered_map capacitySupportedCache; + static std::unordered_map> initFlags; + static std::shared_mutex cacheMutex; + + { + std::shared_lock readLock(cacheMutex); + auto it = capacitySupportedCache.find(type); + if (it != capacitySupportedCache.end()) { + return it->second; + } + } + + std::unique_lock writeLock(cacheMutex); + if (initFlags.find(type) == initFlags.end()) { + initFlags.emplace(type, std::make_unique()); + } + auto it = capacitySupportedCache.find(type); + if (it != capacitySupportedCache.end()) { + return it->second; + } + + bool isSupported = false; + std::call_once(*initFlags[type], [&]() { + int32_t ret = IsCapacitySupport(static_cast(type), isSupported); + if (ret != ErrorCode::NO_ERROR) { + IMSA_HILOGE("failed for capacity type:%{public}d, ret:%{public}d", static_cast(type), ret); + isSupported = false; + } + capacitySupportedCache[type] = isSupported; + IMSA_HILOGE("capacity type:%{public}d supported:%{public}d", static_cast(type), isSupported); + }); + + return capacitySupportedCache[type]; +} } // namespace MiscServices } // namespace OHOS \ No newline at end of file diff --git a/frameworks/native/inputmethod_ability/src/input_method_panel.cpp b/frameworks/native/inputmethod_ability/src/input_method_panel.cpp index 2a2567675bdd72bbd996593d047517950ca08bd6..85cb0dcc2c84be7500f60d809fa54c150bebc33f 100644 --- a/frameworks/native/inputmethod_ability/src/input_method_panel.cpp +++ b/frameworks/native/inputmethod_ability/src/input_method_panel.cpp @@ -2091,32 +2091,6 @@ int32_t InputMethodPanel::IsValidParam(const ImmersiveEffect &effect) return ErrorCode::NO_ERROR; } -bool InputMethodPanel::IsImmersiveEffectSupported() -{ - static int32_t isSupport = 0; - static std::mutex isSupportMutex; - if (isSupport != 0) { - return isSupport == 1 ? true : false; - } - - std::lock_guard lock(isSupportMutex); - bool isSupportTemp = false; - int32_t ret = InputMethodAbility::GetInstance().IsCapacitySupport( - static_cast(CapacityType::IMMERSIVE_EFFECT), isSupportTemp); - if (ret != ErrorCode::NO_ERROR) { - IMSA_HILOGE("IsCapacitySupport failed, ret:%{public}d", ret); - return false; - } - - if (isSupportTemp) { - isSupport = 1; - } else { - isSupport = -1; - } - IMSA_HILOGI("isSupportTemp:%{public}d", isSupportTemp); - return isSupportTemp; -} - KeyboardEffectOption InputMethodPanel::ConvertToWmEffect(ImmersiveMode mode, const ImmersiveEffect &effect) { KeyboardEffectOption option; @@ -2155,7 +2129,7 @@ void InputMethodPanel::UpdateImmersiveHotArea() int32_t InputMethodPanel::SetImmersiveEffect(const ImmersiveEffect &effect) { - if (!IsImmersiveEffectSupported()) { + if (!InputMethodAbility::GetInstance().IsCapacityTypeSupported(CapacityType::IMMERSIVE_EFFECT)) { IMSA_HILOGE("immersive effect is not supported"); return ErrorCode::ERROR_DEVICE_UNSUPPORTED; } diff --git a/frameworks/native/inputmethod_controller/include/input_method_utils.h b/frameworks/native/inputmethod_controller/include/input_method_utils.h index b991c47384805322ee7293645b58db9134651bfe..999423f46edcdcdce9eb47ff8c950306a7c40228 100644 --- a/frameworks/native/inputmethod_controller/include/input_method_utils.h +++ b/frameworks/native/inputmethod_controller/include/input_method_utils.h @@ -18,6 +18,7 @@ #include #include +#include #include "global.h" #include "input_attribute.h" @@ -87,10 +88,17 @@ enum class ExtendAction { }; enum class CapacityType: int32_t { + START, IMMERSIVE_EFFECT, + REQUEST_KEYBOARD_REASON, END, }; +inline std::map CapacityTypeToName = { + {static_cast(CapacityType::IMMERSIVE_EFFECT), "immersive_effect"}, + {static_cast(CapacityType::REQUEST_KEYBOARD_REASON), "request_keyboard_reason"} +}; + class Configuration { public: EnterKeyType GetEnterKeyType() const diff --git a/services/include/input_method_system_ability.h b/services/include/input_method_system_ability.h index 88d3184107533e2507d0a3e2af3c34df6da9bdcc..6a0ef9e71e0b191ba9e24cbc4766e0886917d90e 100644 --- a/services/include/input_method_system_ability.h +++ b/services/include/input_method_system_ability.h @@ -211,6 +211,7 @@ private: void ChangeToDefaultImeForHiCar(int32_t userId, InputClientInfo &inputClientInfo); bool IsDefaultImeScreen(uint64_t displayId); + bool IsCapacityType(int32_t capacity); }; } // namespace MiscServices } // namespace OHOS diff --git a/services/src/input_method_system_ability.cpp b/services/src/input_method_system_ability.cpp index 685f09b7e8081bf9c9a983bab9d8f2f44989a348..df2364e38b2bac3e8b6e626084c3f27d92a76bb7 100644 --- a/services/src/input_method_system_ability.cpp +++ b/services/src/input_method_system_ability.cpp @@ -1071,16 +1071,21 @@ ErrCode InputMethodSystemAbility::IsSystemApp(bool& resultValue) return ERR_OK; } +bool InputMethodSystemAbility::IsCapacityType(int32_t capacity) +{ + return capacity > static_cast(CapacityType::START) && capacity < static_cast(CapacityType::END); +} + ErrCode InputMethodSystemAbility::IsCapacitySupport(int32_t capacity, bool &isSupport) { IMSA_HILOGI("capacity:%{public}d", capacity); - if (capacity != static_cast(CapacityType::IMMERSIVE_EFFECT)) { + if (!IsCapacityType(capacity)) { IMSA_HILOGE("capacity is invalid!"); return ErrorCode::ERROR_PARAMETER_CHECK_FAILED; } const auto &supportedCapacityList = ImeInfoInquirer::GetInstance().GetSystemConfig().supportedCapacityList; - if (supportedCapacityList.find("immersive_effect") != supportedCapacityList.end()) { + if (supportedCapacityList.find(CapacityTypeToName[capacity]) != supportedCapacityList.end()) { isSupport = true; } return ERR_OK; diff --git a/test/unittest/cpp_test/src/input_method_ability_test.cpp b/test/unittest/cpp_test/src/input_method_ability_test.cpp index 2da4b174c65bae50d4c725fcb93223b08ad2939f..865c7cec6f450e11adb9502a0f7784eb3e265b3f 100644 --- a/test/unittest/cpp_test/src/input_method_ability_test.cpp +++ b/test/unittest/cpp_test/src/input_method_ability_test.cpp @@ -2000,5 +2000,33 @@ HWTEST_F(InputMethodAbilityTest, testHandleUnconsumedKey_011, TestSize.Level0) EXPECT_FALSE(InputMethodAbility::GetInstance().HandleUnconsumedKey(keyEvent)); InputMethodAbilityTest::GetIMCDetachIMA(); } + +/** + * @tc.name: testIsCapacityTypeSupported_01 + * @tc.desc: Checkout capacity type is not supported. + * @tc.type: FUNC + */ +HWTEST_F(InputMethodAbilityTest, testIsCapacityTypeSupported_01, TestSize.Level0) +{ + IMSA_HILOGI("InputMethodAbilityTest testIsCapacityTypeSupported_01 START"); + bool ret = InputMethodAbilityTest::inputMethodAbility_.IsCapacityTypeSupported(CapacityType::START); + EXPECT_EQ(ret, false); +} + +/** + * @tc.name: testIsCapacityTypeSupported_02 + * @tc.desc: Checkout capacity type is supported. + * @tc.type: FUNC + */ +HWTEST_F(InputMethodAbilityTest, testIsCapacityTypeSupported_02, TestSize.Level0) +{ + IMSA_HILOGI("InputMethodAbilityTest testIsCapacityTypeSupported_02 START"); + auto supportedCapacityList = ImeInfoInquirer::GetInstance().GetSystemConfig().supportedCapacityList; + supportedCapacityList.insert("immersive_effect"); + ImeInfoInquirer::GetInstance().systemConfig_.supportedCapacityList = supportedCapacityList; + + bool ret = InputMethodAbilityTest::inputMethodAbility_.IsCapacityTypeSupported(CapacityType::IMMERSIVE_EFFECT); + EXPECT_EQ(ret, true); +} } // namespace MiscServices } // namespace OHOS