mirror of
https://gitee.com/openharmony/inputmethod_imf
synced 2025-02-26 01:47:30 +00:00
Merge branch 'master' of gitee.com:openharmony/inputmethod_imf into master
Signed-off-by: 赵凌岚 <zhaolinglan@huawei.com>
This commit is contained in:
commit
52672a1c30
286
frameworks/common/concurrent_map.h
Normal file
286
frameworks/common/concurrent_map.h
Normal file
@ -0,0 +1,286 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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 OHOS_INPUTMETHOD_IMF_FRAMEWORKS_COMMON_CONCURRENT_MAP_H
|
||||
#define OHOS_INPUTMETHOD_IMF_FRAMEWORKS_COMMON_CONCURRENT_MAP_H
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
namespace OHOS {
|
||||
template<typename _Key, typename _Tp>
|
||||
class ConcurrentMap {
|
||||
template<typename _First, typename... _Rest>
|
||||
static _First First();
|
||||
|
||||
public:
|
||||
using map_type = typename std::map<_Key, _Tp>;
|
||||
using filter_type = typename std::function<bool(map_type &)>;
|
||||
using key_type = typename std::map<_Key, _Tp>::key_type;
|
||||
using mapped_type = typename std::map<_Key, _Tp>::mapped_type;
|
||||
using value_type = typename std::map<_Key, _Tp>::value_type;
|
||||
using size_type = typename std::map<_Key, _Tp>::size_type;
|
||||
using reference = typename std::map<_Key, _Tp>::reference;
|
||||
using const_reference = typename std::map<_Key, _Tp>::const_reference;
|
||||
|
||||
ConcurrentMap() = default;
|
||||
~ConcurrentMap()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
ConcurrentMap(const ConcurrentMap &other)
|
||||
{
|
||||
operator=(std::move(other));
|
||||
}
|
||||
|
||||
ConcurrentMap &operator=(const ConcurrentMap &other) noexcept
|
||||
{
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
auto tmp = other.Clone();
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
entries_ = std::move(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ConcurrentMap(ConcurrentMap &&other) noexcept
|
||||
{
|
||||
operator=(std::move(other));
|
||||
}
|
||||
|
||||
ConcurrentMap &operator=(ConcurrentMap &&other) noexcept
|
||||
{
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
auto tmp = other.Steal();
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
entries_ = std::move(tmp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Emplace() noexcept
|
||||
{
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
auto it = entries_.emplace();
|
||||
return it.second;
|
||||
}
|
||||
|
||||
template<typename... _Args>
|
||||
typename std::enable_if<!std::is_convertible_v<decltype(First<_Args...>()), filter_type>, bool>::type
|
||||
Emplace(_Args &&...__args) noexcept
|
||||
{
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
auto it = entries_.emplace(std::forward<_Args>(__args)...);
|
||||
return it.second;
|
||||
}
|
||||
|
||||
template<typename _Filter, typename... _Args>
|
||||
typename std::enable_if<std::is_convertible_v<_Filter, filter_type>, bool>::type
|
||||
Emplace(const _Filter &filter, _Args &&...__args) noexcept
|
||||
{
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
if (!filter(entries_)) {
|
||||
return false;
|
||||
}
|
||||
auto it = entries_.emplace(std::forward<_Args>(__args)...);
|
||||
return it.second;
|
||||
}
|
||||
|
||||
std::pair<bool, mapped_type> Find(const key_type &key) const noexcept
|
||||
{
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
auto it = entries_.find(key);
|
||||
if (it == entries_.end()) {
|
||||
return std::pair { false, mapped_type() };
|
||||
}
|
||||
|
||||
return std::pair { true, it->second };
|
||||
}
|
||||
|
||||
bool Contains(const key_type &key) const noexcept
|
||||
{
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
return (entries_.find(key) != entries_.end());
|
||||
}
|
||||
|
||||
template <typename _Obj>
|
||||
bool InsertOrAssign(const key_type &key, _Obj &&obj) noexcept
|
||||
{
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
auto it = entries_.insert_or_assign(key, std::forward<_Obj>(obj));
|
||||
return it.second;
|
||||
}
|
||||
|
||||
bool Insert(const key_type &key, const mapped_type &value) noexcept
|
||||
{
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
auto it = entries_.insert(value_type { key, value });
|
||||
return it.second;
|
||||
}
|
||||
|
||||
size_type Erase(const key_type &key) noexcept
|
||||
{
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
return entries_.erase(key);
|
||||
}
|
||||
|
||||
void Clear() noexcept
|
||||
{
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
return entries_.clear();
|
||||
}
|
||||
|
||||
bool Empty() const noexcept
|
||||
{
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
return entries_.empty();
|
||||
}
|
||||
|
||||
size_type Size() const noexcept
|
||||
{
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
return entries_.size();
|
||||
}
|
||||
|
||||
// The action`s return true means meeting the erase condition
|
||||
// The action`s return false means not meeting the erase condition
|
||||
size_type EraseIf(const std::function<bool(const key_type &key, mapped_type &value)> &action) noexcept
|
||||
{
|
||||
if (action == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
#if __cplusplus > 201703L
|
||||
auto count = std::erase_if(entries_,
|
||||
[&action](value_type &value) -> bool { return action(value.first, value.second); });
|
||||
#else
|
||||
auto count = entries_.size();
|
||||
for (auto it = entries_.begin(); it != entries_.end();) {
|
||||
if (action((*it).first, (*it).second)) {
|
||||
it = entries_.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
count -= entries_.size();
|
||||
#endif
|
||||
return count;
|
||||
}
|
||||
|
||||
mapped_type &operator[](const key_type &key) noexcept
|
||||
{
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
return entries_[key];
|
||||
}
|
||||
|
||||
void ForEach(const std::function<bool(const key_type &, mapped_type &)> &action)
|
||||
{
|
||||
if (action == nullptr) {
|
||||
return;
|
||||
}
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
for (auto &[key, value] : entries_) {
|
||||
if (action(key, value)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ForEachCopies(const std::function<bool(const key_type &, mapped_type &)> &action)
|
||||
{
|
||||
if (action == nullptr) {
|
||||
return;
|
||||
}
|
||||
auto entries = Clone();
|
||||
for (auto &[key, value] : entries) {
|
||||
if (action(key, value)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The action's return value means that the element is keep in map or not; true means keeping, false means removing.
|
||||
bool Compute(const key_type &key, const std::function<bool(const key_type &, mapped_type &)> &action)
|
||||
{
|
||||
if (action == nullptr) {
|
||||
return false;
|
||||
}
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
auto it = entries_.find(key);
|
||||
if (it == entries_.end()) {
|
||||
auto result = entries_.emplace(key, mapped_type());
|
||||
it = result.second ? result.first : entries_.end();
|
||||
}
|
||||
if (it == entries_.end()) {
|
||||
return false;
|
||||
}
|
||||
if (!action(it->first, it->second)) {
|
||||
entries_.erase(key);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// The action's return value means that the element is keep in map or not; true means keeping, false means removing.
|
||||
bool ComputeIfPresent(const key_type &key, const std::function<bool(const key_type &, mapped_type &)> &action)
|
||||
{
|
||||
if (action == nullptr) {
|
||||
return false;
|
||||
}
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
auto it = entries_.find(key);
|
||||
if (it == entries_.end()) {
|
||||
return false;
|
||||
}
|
||||
if (!action(key, it->second)) {
|
||||
entries_.erase(key);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ComputeIfAbsent(const key_type &key, const std::function<mapped_type(const key_type &)> &action)
|
||||
{
|
||||
if (action == nullptr) {
|
||||
return false;
|
||||
}
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
auto it = entries_.find(key);
|
||||
if (it != entries_.end()) {
|
||||
return false;
|
||||
}
|
||||
entries_.emplace(key, action(key));
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<_Key, _Tp> Steal() noexcept
|
||||
{
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
return std::move(entries_);
|
||||
}
|
||||
|
||||
std::map<_Key, _Tp> Clone() const noexcept
|
||||
{
|
||||
std::lock_guard<decltype(mutex_)> lock(mutex_);
|
||||
return entries_;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::recursive_mutex mutex_;
|
||||
std::map<_Key, _Tp> entries_;
|
||||
};
|
||||
} // namespace OHOS
|
||||
#endif // OHOS_INPUTMETHOD_IMF_FRAMEWORKS_COMMON_CONCURRENT_MAP_H
|
@ -18,6 +18,7 @@ config("inputmethodengine_native_config") {
|
||||
visibility = [ ":*" ]
|
||||
include_dirs = [
|
||||
"include",
|
||||
"${inputmethod_path}/frameworks/common",
|
||||
"${inputmethod_path}/frameworks/native/inputmethod_ability/include",
|
||||
"${inputmethod_path}/frameworks/native/inputmethod_controller/include",
|
||||
"${inputmethod_path}/interfaces/inner_api/inputmethod_controller/include",
|
||||
@ -34,6 +35,7 @@ config("inputmethodengine_native_public_config") {
|
||||
visibility = []
|
||||
include_dirs = [
|
||||
"include",
|
||||
"${inputmethod_path}/frameworks/common",
|
||||
"${inputmethod_path}/frameworks/js/napi/inputmethodclient",
|
||||
"${inputmethod_path}/frameworks/js/napi/inputmethodability",
|
||||
]
|
||||
@ -49,7 +51,9 @@ ohos_shared_library("inputmethodengine") {
|
||||
"js_input_method_engine_setting.cpp",
|
||||
"js_keyboard_controller_engine.cpp",
|
||||
"js_keyboard_delegate_setting.cpp",
|
||||
"js_panel.cpp",
|
||||
"js_text_input_client_engine.cpp",
|
||||
"panel_listener_impl.cpp",
|
||||
]
|
||||
|
||||
configs = [ ":inputmethodengine_native_config" ]
|
||||
@ -62,6 +66,7 @@ ohos_shared_library("inputmethodengine") {
|
||||
"hiviewdfx_hilog_native:libhilog",
|
||||
"input:libmmi-client",
|
||||
"ipc:ipc_core",
|
||||
"napi:ace_napi",
|
||||
]
|
||||
|
||||
public_configs = [ ":inputmethodengine_native_public_config" ]
|
||||
|
@ -21,8 +21,8 @@
|
||||
#include "input_method_property.h"
|
||||
#include "input_method_utils.h"
|
||||
#include "js_keyboard_controller_engine.h"
|
||||
#include "js_runtime_utils.h"
|
||||
#include "js_text_input_client_engine.h"
|
||||
#include "js_utils.h"
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_node_api.h"
|
||||
|
||||
@ -79,6 +79,8 @@ napi_value JsInputMethodEngineSetting::Init(napi_env env, napi_value exports)
|
||||
napi_property_descriptor properties[] = {
|
||||
DECLARE_NAPI_FUNCTION("on", Subscribe),
|
||||
DECLARE_NAPI_FUNCTION("off", UnSubscribe),
|
||||
DECLARE_NAPI_FUNCTION("createPanel", CreatePanel),
|
||||
DECLARE_NAPI_FUNCTION("destroyPanel", DestroyPanel),
|
||||
};
|
||||
napi_value cons = nullptr;
|
||||
NAPI_CALL(env, napi_define_class(env, IMES_CLASS_NAME.c_str(), IMES_CLASS_NAME.size(), JsConstructor, nullptr,
|
||||
@ -165,11 +167,6 @@ napi_value JsInputMethodEngineSetting::GetIMEInstance(napi_env env, napi_callbac
|
||||
napi_value argv[ARGC_MAX] = { nullptr };
|
||||
|
||||
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
|
||||
if (argc != ARGC_ZERO) {
|
||||
JsUtils::ThrowException(
|
||||
env, IMFErrorCode::EXCEPTION_PARAMCHECK, "Wrong number of arguments, requires 0", TypeCode::TYPE_NONE);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (napi_get_reference_value(env, IMESRef_, &cons) != napi_ok) {
|
||||
@ -190,13 +187,9 @@ napi_value JsInputMethodEngineSetting::MoveCursor(napi_env env, napi_callback_in
|
||||
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
|
||||
NAPI_ASSERT(env, argc == 1, "Wrong number of arguments, requires 1");
|
||||
|
||||
napi_valuetype valuetype;
|
||||
NAPI_CALL(env, napi_typeof(env, argv[ARGC_ZERO], &valuetype));
|
||||
NAPI_ASSERT(env, valuetype == napi_number, "type is not a number");
|
||||
|
||||
int32_t number;
|
||||
if (napi_get_value_int32(env, argv[ARGC_ZERO], &number) != napi_ok) {
|
||||
IMSA_HILOGE("GetNumberProperty error");
|
||||
int32_t number = 0;
|
||||
if (JsUtils::GetValue(env, argv[ARGC_ZERO], number) != napi_ok) {
|
||||
IMSA_HILOGE("Get number error");
|
||||
}
|
||||
|
||||
InputMethodAbility::GetInstance()->MoveCursor(number);
|
||||
@ -206,17 +199,6 @@ napi_value JsInputMethodEngineSetting::MoveCursor(napi_env env, napi_callback_in
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string JsInputMethodEngineSetting::GetStringProperty(napi_env env, napi_value jsString)
|
||||
{
|
||||
char propValue[MAX_VALUE_LEN] = { 0 };
|
||||
size_t propLen;
|
||||
if (napi_get_value_string_utf8(env, jsString, propValue, MAX_VALUE_LEN, &propLen) != napi_ok) {
|
||||
IMSA_HILOGE("GetStringProperty error");
|
||||
return "";
|
||||
}
|
||||
return std::string(propValue);
|
||||
}
|
||||
|
||||
void JsInputMethodEngineSetting::RegisterListener(
|
||||
napi_value callback, std::string type, std::shared_ptr<JSCallbackObject> callbackObj)
|
||||
{
|
||||
@ -227,7 +209,7 @@ void JsInputMethodEngineSetting::RegisterListener(
|
||||
}
|
||||
auto callbacks = jsCbMap_[type];
|
||||
bool ret = std::any_of(callbacks.begin(), callbacks.end(), [&callback](std::shared_ptr<JSCallbackObject> cb) {
|
||||
return Equals(cb->env_, callback, cb->callback_, cb->threadId_);
|
||||
return JsUtils::Equals(cb->env_, callback, cb->callback_, cb->threadId_);
|
||||
});
|
||||
if (ret) {
|
||||
IMSA_HILOGE("JsInputMethodEngineListener::RegisterListener callback already registered!");
|
||||
@ -254,7 +236,7 @@ void JsInputMethodEngineSetting::UnRegisterListener(napi_value callback, std::st
|
||||
}
|
||||
|
||||
for (auto item = jsCbMap_[type].begin(); item != jsCbMap_[type].end(); item++) {
|
||||
if (Equals((*item)->env_, callback, (*item)->callback_, (*item)->threadId_)) {
|
||||
if (JsUtils::Equals((*item)->env_, callback, (*item)->callback_, (*item)->threadId_)) {
|
||||
jsCbMap_[type].erase(item);
|
||||
break;
|
||||
}
|
||||
@ -265,24 +247,6 @@ void JsInputMethodEngineSetting::UnRegisterListener(napi_value callback, std::st
|
||||
}
|
||||
}
|
||||
|
||||
JsInputMethodEngineSetting *JsInputMethodEngineSetting::GetNative(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = ARGC_MAX;
|
||||
void *native = nullptr;
|
||||
napi_value self = nullptr;
|
||||
napi_value argv[ARGC_MAX] = { nullptr };
|
||||
napi_status status = napi_invalid_arg;
|
||||
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr));
|
||||
if (self == nullptr && argc >= ARGC_MAX) {
|
||||
IMSA_HILOGE("napi_get_cb_info failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
status = napi_unwrap(env, self, &native);
|
||||
NAPI_ASSERT(env, (status == napi_ok && native != nullptr), "napi_unwrap failed!");
|
||||
return reinterpret_cast<JsInputMethodEngineSetting *>(native);
|
||||
}
|
||||
|
||||
napi_value JsInputMethodEngineSetting::Subscribe(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = ARGC_TWO;
|
||||
@ -290,29 +254,18 @@ napi_value JsInputMethodEngineSetting::Subscribe(napi_env env, napi_callback_inf
|
||||
napi_value thisVar = nullptr;
|
||||
void *data = nullptr;
|
||||
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
|
||||
if (argc != ARGC_TWO) {
|
||||
JsUtils::ThrowException(
|
||||
env, IMFErrorCode::EXCEPTION_PARAMCHECK, "Wrong number of arguments, requires 2", TypeCode::TYPE_NONE);
|
||||
return nullptr;
|
||||
}
|
||||
PARAM_CHECK_RETURN(env, argc >= ARGC_TWO, "Wrong number of arguments, requires 2", TYPE_NONE, nullptr);
|
||||
|
||||
napi_valuetype valuetype;
|
||||
NAPI_CALL(env, napi_typeof(env, argv[ARGC_ZERO], &valuetype));
|
||||
if (valuetype != napi_string) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "'type'", TypeCode::TYPE_STRING);
|
||||
return nullptr;
|
||||
}
|
||||
std::string type = GetStringProperty(env, argv[ARGC_ZERO]);
|
||||
std::string type = "";
|
||||
napi_status status = JsUtils::GetValue(env, argv[ARGC_ZERO], type);
|
||||
NAPI_ASSERT_BASE(env, status == napi_ok, "get type failed!", nullptr);
|
||||
IMSA_HILOGE("event type is: %{public}s", type.c_str());
|
||||
|
||||
valuetype = napi_undefined;
|
||||
napi_typeof(env, argv[ARGC_ONE], &valuetype);
|
||||
if (valuetype != napi_function) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "'callback'", TypeCode::TYPE_FUNCTION);
|
||||
return nullptr;
|
||||
}
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_typeof(env, argv[ARGC_ONE], &valueType);
|
||||
PARAM_CHECK_RETURN(env, valueType == napi_function, "'callback'", TYPE_FUNCTION, nullptr);
|
||||
|
||||
auto engine = GetNative(env, info);
|
||||
auto engine = reinterpret_cast<JsInputMethodEngineSetting *>(JsUtils::GetNativeSelf(env, info));
|
||||
if (engine == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -325,6 +278,117 @@ napi_value JsInputMethodEngineSetting::Subscribe(napi_env env, napi_callback_inf
|
||||
return result;
|
||||
}
|
||||
|
||||
napi_value JsInputMethodEngineSetting::CreatePanel(napi_env env, napi_callback_info info)
|
||||
{
|
||||
auto ctxt = std::make_shared<PanelContext>();
|
||||
auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
|
||||
PARAM_CHECK_RETURN(env, argc >= 2, "should has 2 or 3 parameters!", TYPE_NONE, napi_invalid_arg);
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_typeof(env, argv[ARGC_ZERO], &valueType);
|
||||
PARAM_CHECK_RETURN(env, valueType == napi_object, " ctx: ", TYPE_OBJECT, napi_invalid_arg);
|
||||
|
||||
void *contextPtr = nullptr;
|
||||
NativeValue *value = reinterpret_cast<NativeValue *>(argv[ARGC_ZERO]);
|
||||
GetNativeContext(env, value, contextPtr);
|
||||
ctxt->contextPtr = contextPtr;
|
||||
|
||||
napi_typeof(env, argv[ARGC_ONE], &valueType);
|
||||
PARAM_CHECK_RETURN(env, valueType == napi_object, " panelInfo: ", TYPE_OBJECT, napi_invalid_arg);
|
||||
napi_value napiValue = nullptr;
|
||||
napi_status status = napi_get_named_property(env, argv[ARGC_ONE], "type", &napiValue);
|
||||
PARAM_CHECK_RETURN(env, status == napi_ok, " missing info parameter.", TYPE_NONE, status);
|
||||
status = JsUtils::GetValue(env, napiValue, ctxt->panelType);
|
||||
NAPI_ASSERT_BASE(env, status == napi_ok, "Get panelType error!", status);
|
||||
|
||||
status = napi_get_named_property(env, argv[ARGC_ONE], "flag", &napiValue);
|
||||
PARAM_CHECK_RETURN(env, status == napi_ok, " missing info parameter.", TYPE_NONE, status);
|
||||
status = JsUtils::GetValue(env, napiValue, ctxt->panelFlag);
|
||||
NAPI_ASSERT_BASE(env, status == napi_ok, "Get panelFlag error!", status);
|
||||
ctxt->ref = NewWithRef(env, 0, nullptr, reinterpret_cast<void **>(&ctxt->jsPanel), JsPanel::Constructor(env));
|
||||
return status;
|
||||
};
|
||||
auto exec = [ctxt](AsyncCall::Context *ctx) {
|
||||
std::shared_ptr<InputMethodPanel> panel = nullptr;
|
||||
PanelInfo panelInfo = { .panelType = PanelType(ctxt->panelType), .panelFlag = PanelFlag(ctxt->panelFlag) };
|
||||
auto context = static_cast<std::weak_ptr<AbilityRuntime::Context> *>(ctxt->contextPtr);
|
||||
CHECK_RETURN_VOID(ctxt->jsPanel != nullptr, "napi_create_reference failed");
|
||||
auto ret = InputMethodAbility::GetInstance()->CreatePanel(context->lock(), panelInfo, panel);
|
||||
ctxt->SetErrorCode(ret);
|
||||
CHECK_RETURN_VOID(ret == ErrorCode::NO_ERROR, "JsInputMethodEngineSetting CreatePanel failed!");
|
||||
ctxt->jsPanel->SetNative(panel);
|
||||
ctxt->SetState(napi_ok);
|
||||
};
|
||||
auto output = [ctxt](napi_env env, napi_value *result) -> napi_status {
|
||||
NAPI_ASSERT_BASE(env, ctxt->ref != nullptr, "ctxt->ref == nullptr!", napi_generic_failure);
|
||||
auto status = napi_get_reference_value(env, ctxt->ref, result);
|
||||
NAPI_ASSERT_BASE(env, (status == napi_ok || result != nullptr), "Get ref error!", napi_generic_failure);
|
||||
napi_delete_reference(env, ctxt->ref);
|
||||
return napi_ok;
|
||||
};
|
||||
|
||||
ctxt->SetAction(std::move(input), std::move(output));
|
||||
AsyncCall asyncCall(env, info, ctxt, ARGC_TWO);
|
||||
return asyncCall.Call(env, exec);
|
||||
}
|
||||
|
||||
void JsInputMethodEngineSetting::GetNativeContext(napi_env env, NativeValue *nativeContext, void *&contextPtr)
|
||||
{
|
||||
if (nativeContext != nullptr) {
|
||||
auto objContext = AbilityRuntime::ConvertNativeValueTo<NativeObject>(nativeContext);
|
||||
if (objContext == nullptr) {
|
||||
IMSA_HILOGE("Get context object failed.");
|
||||
return;
|
||||
}
|
||||
contextPtr = objContext->GetNativePointer();
|
||||
}
|
||||
}
|
||||
|
||||
napi_value JsInputMethodEngineSetting::DestroyPanel(napi_env env, napi_callback_info info)
|
||||
{
|
||||
auto ctxt = std::make_shared<PanelContext>();
|
||||
auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
|
||||
PARAM_CHECK_RETURN(env, argc >= 1, "should has 1 parameters!", TYPE_NONE, napi_invalid_arg);
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_typeof(env, argv[0], &valueType);
|
||||
PARAM_CHECK_RETURN(env, valueType == napi_object, " target: ", TYPE_OBJECT, napi_invalid_arg);
|
||||
bool result = false;
|
||||
napi_status status = napi_instanceof(env, argv[0], JsPanel::Constructor(env), &result);
|
||||
NAPI_ASSERT_BASE(env, status == napi_ok, "run napi_instanceof failed!", status);
|
||||
JsPanel *panel = nullptr;
|
||||
status = napi_unwrap(env, argv[0], (void **)(&panel));
|
||||
NAPI_ASSERT_BASE(env, (status == napi_ok) && (panel != nullptr), "can not unwrap to JsPanel!", status);
|
||||
ctxt->jsPanel = panel;
|
||||
return status;
|
||||
};
|
||||
|
||||
auto exec = [ctxt](AsyncCall::Context *ctx) {
|
||||
CHECK_RETURN_VOID(ctxt->jsPanel != nullptr, "JsPanel is nullptr!");
|
||||
auto status = InputMethodAbility::GetInstance()->DestroyPanel(ctxt->jsPanel->GetNative());
|
||||
ctxt->SetErrorCode(status);
|
||||
CHECK_RETURN_VOID(status == ErrorCode::NO_ERROR, "DestroyPanel return error!");
|
||||
ctxt->SetState(napi_ok);
|
||||
};
|
||||
ctxt->SetAction(std::move(input));
|
||||
AsyncCall asyncCall(env, info, ctxt, 1);
|
||||
return asyncCall.Call(env, exec);
|
||||
}
|
||||
|
||||
napi_ref JsInputMethodEngineSetting::NewWithRef(
|
||||
napi_env env, size_t argc, napi_value *argv, void **out, napi_value constructor)
|
||||
{
|
||||
napi_value object = nullptr;
|
||||
napi_status status = napi_new_instance(env, constructor, argc, argv, &object);
|
||||
NAPI_ASSERT(env, (status == napi_ok) && (object != nullptr), "napi_new_instance failed!");
|
||||
|
||||
status = napi_unwrap(env, object, out);
|
||||
NAPI_ASSERT(env, (status == napi_ok) && (out != nullptr), "napi_unwrap failed");
|
||||
|
||||
napi_ref ref = nullptr;
|
||||
status = napi_create_reference(env, object, 1, &ref);
|
||||
NAPI_ASSERT(env, (status == napi_ok) && (ref != nullptr), "napi_create_reference failed");
|
||||
return ref;
|
||||
}
|
||||
|
||||
napi_value JsInputMethodEngineSetting::UnSubscribe(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = ARGC_TWO;
|
||||
@ -332,60 +396,26 @@ napi_value JsInputMethodEngineSetting::UnSubscribe(napi_env env, napi_callback_i
|
||||
napi_value thisVar = nullptr;
|
||||
void *data = nullptr;
|
||||
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
|
||||
if (argc != ARGC_ONE && argc != ARGC_TWO) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "Wrong number of arguments, requires 1 or 2",
|
||||
TypeCode::TYPE_NONE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
napi_valuetype valuetype;
|
||||
NAPI_CALL(env, napi_typeof(env, argv[ARGC_ZERO], &valuetype));
|
||||
if (valuetype != napi_string) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "'type'", TypeCode::TYPE_STRING);
|
||||
return nullptr;
|
||||
}
|
||||
std::string type = GetStringProperty(env, argv[ARGC_ZERO]);
|
||||
IMSA_HILOGE("event type is: %{public}s", type.c_str());
|
||||
|
||||
auto engine = GetNative(env, info);
|
||||
if (engine == nullptr) {
|
||||
PARAM_CHECK_RETURN(env, argc >= 1, "Wrong number of arguments, requires 1 or 2", TYPE_NONE, nullptr);
|
||||
std::string type = "";
|
||||
JsUtils::GetValue(env, argv[ARGC_ZERO], type);
|
||||
IMSA_HILOGD("event type is: %{public}s", type.c_str());
|
||||
auto setting = reinterpret_cast<JsInputMethodEngineSetting *>(JsUtils::GetNativeSelf(env, info));
|
||||
if (setting == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (argc == ARGC_TWO) {
|
||||
valuetype = napi_undefined;
|
||||
napi_typeof(env, argv[ARGC_ONE], &valuetype);
|
||||
if (valuetype != napi_function) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "'callback'", TypeCode::TYPE_FUNCTION);
|
||||
return nullptr;
|
||||
}
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_typeof(env, argv[ARGC_ONE], &valueType);
|
||||
PARAM_CHECK_RETURN(env, valueType == napi_function, " 'callback' ", TYPE_FUNCTION, nullptr);
|
||||
}
|
||||
engine->UnRegisterListener(argv[ARGC_ONE], type);
|
||||
setting->UnRegisterListener(argv[ARGC_ONE], type);
|
||||
napi_value result = nullptr;
|
||||
napi_get_null(env, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool JsInputMethodEngineSetting::Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId)
|
||||
{
|
||||
if (copy == nullptr) {
|
||||
return (value == nullptr);
|
||||
}
|
||||
|
||||
if (threadId != std::this_thread::get_id()) {
|
||||
IMSA_HILOGD("napi_value can not be compared");
|
||||
return false;
|
||||
}
|
||||
|
||||
napi_value copyValue = nullptr;
|
||||
napi_get_reference_value(env, copy, ©Value);
|
||||
|
||||
bool isEquals = false;
|
||||
napi_strict_equals(env, value, copyValue, &isEquals);
|
||||
IMSA_HILOGD("value compare result: %{public}d", isEquals);
|
||||
return isEquals;
|
||||
}
|
||||
|
||||
napi_value JsInputMethodEngineSetting::GetResultOnSetSubtype(napi_env env, const SubProperty &property)
|
||||
{
|
||||
napi_value subType = nullptr;
|
||||
|
@ -27,7 +27,9 @@
|
||||
#include "input_method_engine_listener.h"
|
||||
#include "input_method_property.h"
|
||||
#include "js_callback_object.h"
|
||||
#include "js_panel.h"
|
||||
#include "napi/native_api.h"
|
||||
#include "input_method_panel.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
@ -41,6 +43,8 @@ public:
|
||||
static napi_value Subscribe(napi_env env, napi_callback_info info);
|
||||
static napi_value UnSubscribe(napi_env env, napi_callback_info info);
|
||||
static napi_value MoveCursor(napi_env env, napi_callback_info info);
|
||||
static napi_value CreatePanel(napi_env env, napi_callback_info info);
|
||||
static napi_value DestroyPanel(napi_env env, napi_callback_info info);
|
||||
void OnInputStart() override;
|
||||
void OnKeyboardStatus(bool isShow) override;
|
||||
void OnInputStop(const std::string &imeId) override;
|
||||
@ -48,18 +52,40 @@ public:
|
||||
void OnSetSubtype(const SubProperty &property) override;
|
||||
|
||||
private:
|
||||
struct PanelContext : public AsyncCall::Context {
|
||||
int32_t panelType = -1;
|
||||
int32_t panelFlag = 0;
|
||||
JsPanel *jsPanel = nullptr;
|
||||
void *contextPtr = nullptr;
|
||||
napi_ref ref = nullptr;
|
||||
PanelContext() : Context(nullptr, nullptr){};
|
||||
PanelContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
|
||||
|
||||
napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
|
||||
{
|
||||
NAPI_ASSERT_BASE(env, self != nullptr, "self is nullptr", napi_invalid_arg);
|
||||
return Context::operator()(env, argc, argv, self);
|
||||
}
|
||||
napi_status operator()(napi_env env, napi_value *result) override
|
||||
{
|
||||
if (status_ != napi_ok) {
|
||||
output_ = nullptr;
|
||||
return status_;
|
||||
}
|
||||
return Context::operator()(env, result);
|
||||
}
|
||||
};
|
||||
|
||||
static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo);
|
||||
static JsInputMethodEngineSetting *GetNative(napi_env env, napi_callback_info info);
|
||||
static std::shared_ptr<JsInputMethodEngineSetting> GetInputMethodEngineSetting();
|
||||
static bool Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId);
|
||||
static napi_value GetJsConstProperty(napi_env env, uint32_t num);
|
||||
static napi_value GetIntJsConstProperty(napi_env env, int32_t num);
|
||||
static napi_value GetIMEInstance(napi_env env, napi_callback_info info, int flag);
|
||||
void RegisterListener(napi_value callback, std::string type, std::shared_ptr<JSCallbackObject> callbackObj);
|
||||
void UnRegisterListener(napi_value callback, std::string type);
|
||||
static napi_value GetResultOnSetSubtype(napi_env env, const SubProperty &property);
|
||||
static std::string GetStringProperty(napi_env env, napi_value jsString);
|
||||
static constexpr int32_t MAX_VALUE_LEN = 1024;
|
||||
static napi_ref NewWithRef(napi_env env, size_t argc, napi_value *argv, void **out, napi_value constructor);
|
||||
static void GetNativeContext(napi_env env, NativeValue *nativeContext, void *&contextPtr);
|
||||
static const std::string IMES_CLASS_NAME;
|
||||
static thread_local napi_ref IMESRef_;
|
||||
struct UvEntry {
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "js_keyboard_controller_engine.h"
|
||||
|
||||
#include "input_method_ability.h"
|
||||
#include "js_utils.h"
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_node_api.h"
|
||||
|
||||
|
@ -31,6 +31,7 @@ constexpr size_t ARGC_THREE = 3;
|
||||
constexpr size_t ARGC_FOUR = 4;
|
||||
constexpr int32_t V9_FLAG = 1;
|
||||
constexpr int32_t ORIGINAL_FLAG = 2;
|
||||
constexpr size_t ARGC_MAX = 6;
|
||||
const std::string JsKeyboardDelegateSetting::KDS_CLASS_NAME = "KeyboardDelegate";
|
||||
thread_local napi_ref JsKeyboardDelegateSetting::KDSRef_ = nullptr;
|
||||
|
||||
@ -140,14 +141,10 @@ napi_value JsKeyboardDelegateSetting::GetKDInstance(napi_env env, napi_callback_
|
||||
napi_value instance = nullptr;
|
||||
napi_value cons = nullptr;
|
||||
if (flag == V9_FLAG) {
|
||||
size_t argc = AsyncCall::ARGC_MAX;
|
||||
napi_value argv[AsyncCall::ARGC_MAX] = { nullptr };
|
||||
size_t argc = ARGC_MAX;
|
||||
napi_value argv[ARGC_MAX] = { nullptr };
|
||||
|
||||
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
|
||||
if (argc != ARGC_ZERO) {
|
||||
JsUtils::ThrowException(
|
||||
env, IMFErrorCode::EXCEPTION_PARAMCHECK, "Wrong number of arguments, requires 0", TypeCode::TYPE_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
if (napi_get_reference_value(env, KDSRef_, &cons) != napi_ok) {
|
||||
@ -162,17 +159,6 @@ napi_value JsKeyboardDelegateSetting::GetKDInstance(napi_env env, napi_callback_
|
||||
return instance;
|
||||
}
|
||||
|
||||
std::string JsKeyboardDelegateSetting::GetStringProperty(napi_env env, napi_value jsString)
|
||||
{
|
||||
char propValue[MAX_VALUE_LEN] = { 0 };
|
||||
size_t propLen;
|
||||
if (napi_get_value_string_utf8(env, jsString, propValue, MAX_VALUE_LEN, &propLen) != napi_ok) {
|
||||
IMSA_HILOGE("GetStringProperty error");
|
||||
return "";
|
||||
}
|
||||
return std::string(propValue);
|
||||
}
|
||||
|
||||
void JsKeyboardDelegateSetting::RegisterListener(
|
||||
napi_value callback, std::string type, std::shared_ptr<JSCallbackObject> callbackObj)
|
||||
{
|
||||
@ -183,7 +169,7 @@ void JsKeyboardDelegateSetting::RegisterListener(
|
||||
}
|
||||
auto callbacks = jsCbMap_[type];
|
||||
bool ret = std::any_of(callbacks.begin(), callbacks.end(), [&callback](std::shared_ptr<JSCallbackObject> cb) {
|
||||
return Equals(cb->env_, callback, cb->callback_, cb->threadId_);
|
||||
return JsUtils::Equals(cb->env_, callback, cb->callback_, cb->threadId_);
|
||||
});
|
||||
if (ret) {
|
||||
IMSA_HILOGE("JsKeyboardDelegateSetting::RegisterListener callback already registered!");
|
||||
@ -210,7 +196,8 @@ void JsKeyboardDelegateSetting::UnRegisterListener(napi_value callback, std::str
|
||||
}
|
||||
|
||||
for (auto item = jsCbMap_[type].begin(); item != jsCbMap_[type].end(); item++) {
|
||||
if ((callback != nullptr) && (Equals((*item)->env_, callback, (*item)->callback_, (*item)->threadId_))) {
|
||||
if ((callback != nullptr) &&
|
||||
(JsUtils::Equals((*item)->env_, callback, (*item)->callback_, (*item)->threadId_))) {
|
||||
jsCbMap_[type].erase(item);
|
||||
break;
|
||||
}
|
||||
@ -220,24 +207,6 @@ void JsKeyboardDelegateSetting::UnRegisterListener(napi_value callback, std::str
|
||||
}
|
||||
}
|
||||
|
||||
JsKeyboardDelegateSetting *JsKeyboardDelegateSetting::GetNative(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = AsyncCall::ARGC_MAX;
|
||||
void *native = nullptr;
|
||||
napi_value self = nullptr;
|
||||
napi_value argv[AsyncCall::ARGC_MAX] = { nullptr };
|
||||
napi_status status = napi_invalid_arg;
|
||||
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr));
|
||||
if (self == nullptr && argc >= AsyncCall::ARGC_MAX) {
|
||||
IMSA_HILOGE("napi_get_cb_info failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
status = napi_unwrap(env, self, &native);
|
||||
NAPI_ASSERT(env, (status == napi_ok && native != nullptr), "napi_unwrap failed!");
|
||||
return reinterpret_cast<JsKeyboardDelegateSetting *>(native);
|
||||
}
|
||||
|
||||
napi_value JsKeyboardDelegateSetting::Subscribe(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = ARGC_TWO;
|
||||
@ -245,28 +214,16 @@ napi_value JsKeyboardDelegateSetting::Subscribe(napi_env env, napi_callback_info
|
||||
napi_value thisVar = nullptr;
|
||||
void *data = nullptr;
|
||||
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
|
||||
if (argc != ARGC_TWO) {
|
||||
JsUtils::ThrowException(
|
||||
env, IMFErrorCode::EXCEPTION_PARAMCHECK, "Wrong number of arguments, requires 2", TypeCode::TYPE_NONE);
|
||||
}
|
||||
|
||||
napi_valuetype valuetype;
|
||||
NAPI_CALL(env, napi_typeof(env, argv[ARGC_ZERO], &valuetype));
|
||||
if (valuetype != napi_string) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "'type'", TypeCode::TYPE_STRING);
|
||||
return nullptr;
|
||||
}
|
||||
std::string type = GetStringProperty(env, argv[ARGC_ZERO]);
|
||||
PARAM_CHECK_RETURN(env, argc >= ARGC_TWO, "Wrong number of arguments, requires 2", TYPE_NONE, nullptr);
|
||||
std::string type = "";
|
||||
JsUtils::GetValue(env, argv[ARGC_ZERO], type);
|
||||
IMSA_HILOGE("event type is: %{public}s", type.c_str());
|
||||
|
||||
valuetype = napi_undefined;
|
||||
napi_typeof(env, argv[ARGC_ONE], &valuetype);
|
||||
if (valuetype != napi_function) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "'callback'", TypeCode::TYPE_FUNCTION);
|
||||
return nullptr;
|
||||
}
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_typeof(env, argv[ARGC_ONE], &valueType);
|
||||
PARAM_CHECK_RETURN(env, valueType == napi_function, "callback", TYPE_FUNCTION, nullptr);
|
||||
|
||||
auto engine = GetNative(env, info);
|
||||
auto engine = reinterpret_cast<JsKeyboardDelegateSetting *>(JsUtils::GetNativeSelf(env, info));
|
||||
if (engine == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -286,32 +243,20 @@ napi_value JsKeyboardDelegateSetting::UnSubscribe(napi_env env, napi_callback_in
|
||||
napi_value thisVar = nullptr;
|
||||
void *data = nullptr;
|
||||
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
|
||||
if (argc != ARGC_ONE && argc != ARGC_TWO) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "Wrong number of arguments, requires 1 or 2",
|
||||
TypeCode::TYPE_NONE);
|
||||
return nullptr;
|
||||
}
|
||||
PARAM_CHECK_RETURN(env, argc > 0, "should 1 or 2 parameters!", TYPE_NONE, nullptr);
|
||||
|
||||
napi_valuetype valuetype;
|
||||
NAPI_CALL(env, napi_typeof(env, argv[ARGC_ZERO], &valuetype));
|
||||
if (valuetype != napi_string) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "'type'", TypeCode::TYPE_STRING);
|
||||
return nullptr;
|
||||
}
|
||||
std::string type = GetStringProperty(env, argv[ARGC_ZERO]);
|
||||
std::string type = "";
|
||||
JsUtils::GetValue(env, argv[ARGC_ZERO], type);
|
||||
|
||||
auto delegate = GetNative(env, info);
|
||||
auto delegate = reinterpret_cast<JsKeyboardDelegateSetting *>(JsUtils::GetNativeSelf(env, info));
|
||||
if (delegate == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (argc == ARGC_TWO) {
|
||||
valuetype = napi_undefined;
|
||||
napi_typeof(env, argv[ARGC_ONE], &valuetype);
|
||||
if (valuetype != napi_function) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "'callback'", TypeCode::TYPE_FUNCTION);
|
||||
return nullptr;
|
||||
}
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_typeof(env, argv[ARGC_ONE], &valueType);
|
||||
PARAM_CHECK_RETURN(env, valueType == napi_function, "callback", TYPE_FUNCTION, nullptr);
|
||||
}
|
||||
delegate->UnRegisterListener(argv[ARGC_ONE], type);
|
||||
napi_value result = nullptr;
|
||||
@ -319,26 +264,6 @@ napi_value JsKeyboardDelegateSetting::UnSubscribe(napi_env env, napi_callback_in
|
||||
return result;
|
||||
}
|
||||
|
||||
bool JsKeyboardDelegateSetting::Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId)
|
||||
{
|
||||
if (copy == nullptr) {
|
||||
return (value == nullptr);
|
||||
}
|
||||
|
||||
if (threadId != std::this_thread::get_id()) {
|
||||
IMSA_HILOGD("napi_value can not be compared");
|
||||
return false;
|
||||
}
|
||||
|
||||
napi_value copyValue = nullptr;
|
||||
napi_get_reference_value(env, copy, ©Value);
|
||||
|
||||
bool isEquals = false;
|
||||
napi_strict_equals(env, value, copyValue, &isEquals);
|
||||
IMSA_HILOGD("value compare result: %{public}d", isEquals);
|
||||
return isEquals;
|
||||
}
|
||||
|
||||
napi_value JsKeyboardDelegateSetting::GetResultOnKeyEvent(napi_env env, int32_t keyCode, int32_t keyStatus)
|
||||
{
|
||||
napi_value KeyboardDelegate = nullptr;
|
||||
|
@ -92,14 +92,9 @@ private:
|
||||
static napi_value GetKDInstance(napi_env env, napi_callback_info info, int flag);
|
||||
static std::shared_ptr<JsKeyboardDelegateSetting> GetKeyboardDelegateSetting();
|
||||
static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo);
|
||||
static JsKeyboardDelegateSetting *GetNative(napi_env env, napi_callback_info info);
|
||||
static bool Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId);
|
||||
void RegisterListener(napi_value callback, std::string type, std::shared_ptr<JSCallbackObject> callbackObj);
|
||||
void UnRegisterListener(napi_value callback, std::string type);
|
||||
|
||||
static std::string GetStringProperty(napi_env env, napi_value jsString);
|
||||
static constexpr int32_t MAX_VALUE_LEN = 1024;
|
||||
static constexpr int32_t MAX_TIMEOUT = 100;
|
||||
static constexpr int32_t MAX_TIMEOUT = 5;
|
||||
static const std::string KDS_CLASS_NAME;
|
||||
static thread_local napi_ref KDSRef_;
|
||||
struct CursorPara {
|
||||
|
292
frameworks/js/napi/inputmethodability/js_panel.cpp
Normal file
292
frameworks/js/napi/inputmethodability/js_panel.cpp
Normal file
@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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 "js_panel.h"
|
||||
|
||||
#include "input_method_ability.h"
|
||||
#include "js_utils.h"
|
||||
#include "napi/native_common.h"
|
||||
#include "panel_listener_impl.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
constexpr size_t ARGC_ZERO = 0;
|
||||
constexpr size_t ARGC_ONE = 1;
|
||||
constexpr size_t ARGC_TWO = 2;
|
||||
const std::string JsPanel::CLASS_NAME = "Panel";
|
||||
|
||||
napi_value JsPanel::Constructor(napi_env env)
|
||||
{
|
||||
IMSA_HILOGI("JsPanel in.");
|
||||
const napi_property_descriptor properties[] = {
|
||||
DECLARE_NAPI_FUNCTION("setUiContent", SetUiContent),
|
||||
DECLARE_NAPI_FUNCTION("resize", Resize),
|
||||
DECLARE_NAPI_FUNCTION("moveTo", MoveTo),
|
||||
DECLARE_NAPI_FUNCTION("show", Show),
|
||||
DECLARE_NAPI_FUNCTION("hide", Hide),
|
||||
DECLARE_NAPI_FUNCTION("changeFlag", ChangeFlag),
|
||||
DECLARE_NAPI_FUNCTION("on", Subscribe),
|
||||
DECLARE_NAPI_FUNCTION("off", UnSubscribe),
|
||||
};
|
||||
napi_value constructor = nullptr;
|
||||
NAPI_CALL(env, napi_define_class(env, CLASS_NAME.c_str(), CLASS_NAME.size(), JsNew, nullptr,
|
||||
sizeof(properties) / sizeof(napi_property_descriptor), properties, &constructor));
|
||||
NAPI_ASSERT(env, constructor != nullptr, "napi_define_class failed!");
|
||||
return constructor;
|
||||
}
|
||||
|
||||
napi_value JsPanel::JsNew(napi_env env, napi_callback_info info)
|
||||
{
|
||||
IMSA_HILOGD("JsPanel, create panel instance in.");
|
||||
JsPanel *panel = new (std::nothrow) JsPanel();
|
||||
NAPI_ASSERT(env, panel != nullptr, "no memory for JsPanel");
|
||||
auto finalize = [](napi_env env, void *data, void *hint) {
|
||||
IMSA_HILOGI("jsPanel finalize.");
|
||||
auto *jsPanel = reinterpret_cast<JsPanel *>(data);
|
||||
NAPI_ASSERT_RETURN_VOID(env, jsPanel != nullptr, "finalize null!");
|
||||
delete jsPanel;
|
||||
};
|
||||
napi_value thisVar = nullptr;
|
||||
NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
|
||||
napi_status status = napi_wrap(env, thisVar, panel, finalize, nullptr, nullptr);
|
||||
if (status != napi_ok) {
|
||||
IMSA_HILOGE("JsPanel napi_wrap failed: %{public}d", status);
|
||||
return nullptr;
|
||||
}
|
||||
return thisVar;
|
||||
}
|
||||
|
||||
JsPanel::~JsPanel()
|
||||
{
|
||||
inputMethodPanel_ = nullptr;
|
||||
}
|
||||
|
||||
void JsPanel::SetNative(const std::shared_ptr<InputMethodPanel> &panel)
|
||||
{
|
||||
inputMethodPanel_ = panel;
|
||||
}
|
||||
|
||||
std::shared_ptr<InputMethodPanel> &JsPanel::GetNative()
|
||||
{
|
||||
return inputMethodPanel_;
|
||||
}
|
||||
|
||||
napi_value JsPanel::SetUiContent(napi_env env, napi_callback_info info)
|
||||
{
|
||||
IMSA_HILOGI("JsPanel in.");
|
||||
auto ctxt = std::make_shared<PanelContentContext>(env, info);
|
||||
auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
|
||||
napi_status status = napi_generic_failure;
|
||||
PARAM_CHECK_RETURN(env, argc >= 1, "should 1 or 2 parameters!", TYPE_NONE, status);
|
||||
status = JsUtils::GetValue(env, argv[ARGC_ZERO], ctxt->path);
|
||||
NAPI_ASSERT_BASE(env, status == napi_ok, "get path failed!", status);
|
||||
// if type of argv[1] is object, we will get value of 'storage' from it.
|
||||
if (argc >= 2) {
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_status status = napi_typeof(env, argv[1], &valueType);
|
||||
NAPI_ASSERT_BASE(env, status == napi_ok, "get valueType failed!", status);
|
||||
if (valueType == napi_object) {
|
||||
NativeValue *storage = nullptr;
|
||||
storage = reinterpret_cast<NativeValue *>(argv[1]);
|
||||
auto contentStorage = (storage == nullptr)
|
||||
? nullptr
|
||||
: std::shared_ptr<NativeReference>(
|
||||
reinterpret_cast<NativeEngine *>(env)->CreateReference(storage, 1));
|
||||
ctxt->contentStorage = contentStorage;
|
||||
}
|
||||
}
|
||||
return napi_ok;
|
||||
};
|
||||
|
||||
auto exec = [ctxt, env](AsyncCall::Context *ctx) {
|
||||
auto &inputMethodPanel = reinterpret_cast<JsPanel *>(ctxt->native)->GetNative();
|
||||
CHECK_RETURN_VOID(inputMethodPanel != nullptr, "inputMethodPanel_ is nullptr.");
|
||||
NativeValue *nativeStorage = (ctxt->contentStorage == nullptr) ? nullptr : ctxt->contentStorage->Get();
|
||||
auto code = inputMethodPanel->SetUiContent(ctxt->path, reinterpret_cast<NativeEngine *>(env), nativeStorage);
|
||||
if (code == ErrorCode::NO_ERROR) {
|
||||
ctxt->SetState(napi_ok);
|
||||
return;
|
||||
}
|
||||
ctxt->SetErrorCode(code);
|
||||
};
|
||||
ctxt->SetAction(std::move(input));
|
||||
AsyncCall asyncCall(env, info, ctxt, 1);
|
||||
return asyncCall.Call(env, exec);
|
||||
}
|
||||
|
||||
napi_value JsPanel::Resize(napi_env env, napi_callback_info info)
|
||||
{
|
||||
auto ctxt = std::make_shared<PanelContentContext>(env, info);
|
||||
auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
|
||||
napi_status status = napi_generic_failure;
|
||||
PARAM_CHECK_RETURN(env, argc > 1, "should 2 or 3 parameters!", TYPE_NONE, status);
|
||||
status = JsUtils::GetValue(env, argv[ARGC_ZERO], ctxt->width);
|
||||
NAPI_ASSERT_BASE(env, status == napi_ok, "get width failed!", status);
|
||||
status = JsUtils::GetValue(env, argv[ARGC_ONE], ctxt->height);
|
||||
NAPI_ASSERT_BASE(env, status == napi_ok, "get height failed!", status);
|
||||
return napi_ok;
|
||||
};
|
||||
|
||||
auto exec = [ctxt](AsyncCall::Context *ctx) {
|
||||
auto &inputMethodPanel = reinterpret_cast<JsPanel *>(ctxt->native)->GetNative();
|
||||
CHECK_RETURN_VOID(inputMethodPanel != nullptr, "inputMethodPanel_ is nullptr.");
|
||||
auto code = inputMethodPanel->Resize(ctxt->width, ctxt->height);
|
||||
if (code == ErrorCode::NO_ERROR) {
|
||||
ctxt->SetState(napi_ok);
|
||||
return;
|
||||
}
|
||||
ctxt->SetErrorCode(code);
|
||||
};
|
||||
ctxt->SetAction(std::move(input));
|
||||
AsyncCall asyncCall(env, info, ctxt, ARGC_TWO);
|
||||
return asyncCall.Call(env, exec);
|
||||
}
|
||||
|
||||
napi_value JsPanel::MoveTo(napi_env env, napi_callback_info info)
|
||||
{
|
||||
auto ctxt = std::make_shared<PanelContentContext>(env, info);
|
||||
auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
|
||||
napi_status status = napi_generic_failure;
|
||||
PARAM_CHECK_RETURN(env, argc > 1, " should 2 or 3 parameters! ", TYPE_NONE, status);
|
||||
status = JsUtils::GetValue(env, argv[ARGC_ZERO], ctxt->width);
|
||||
NAPI_ASSERT_BASE(env, status == napi_ok, "get width failed!", status);
|
||||
status = JsUtils::GetValue(env, argv[ARGC_ONE], ctxt->height);
|
||||
NAPI_ASSERT_BASE(env, status == napi_ok, "get height failed!", status);
|
||||
return napi_ok;
|
||||
};
|
||||
|
||||
auto exec = [ctxt](AsyncCall::Context *ctx) {
|
||||
auto &inputMethodPanel = reinterpret_cast<JsPanel *>(ctxt->native)->GetNative();
|
||||
CHECK_RETURN_VOID(inputMethodPanel != nullptr, "inputMethodPanel_ is nullptr.");
|
||||
auto code = inputMethodPanel->MoveTo(ctxt->width, ctxt->height);
|
||||
if (code == ErrorCode::NO_ERROR) {
|
||||
ctxt->SetState(napi_ok);
|
||||
return;
|
||||
}
|
||||
ctxt->SetErrorCode(code);
|
||||
};
|
||||
ctxt->SetAction(std::move(input));
|
||||
AsyncCall asyncCall(env, info, ctxt, ARGC_TWO);
|
||||
return asyncCall.Call(env, exec);
|
||||
}
|
||||
|
||||
napi_value JsPanel::Show(napi_env env, napi_callback_info info)
|
||||
{
|
||||
auto ctxt = std::make_shared<PanelContentContext>(env, info);
|
||||
auto exec = [ctxt](AsyncCall::Context *ctx) {
|
||||
auto &inputMethodPanel = reinterpret_cast<JsPanel *>(ctxt->native)->GetNative();
|
||||
CHECK_RETURN_VOID(inputMethodPanel != nullptr, "inputMethodPanel_ is nullptr.");
|
||||
auto code = inputMethodPanel->ShowPanel();
|
||||
if (code == ErrorCode::NO_ERROR) {
|
||||
ctxt->SetState(napi_ok);
|
||||
return;
|
||||
}
|
||||
ctxt->SetErrorCode(code);
|
||||
};
|
||||
AsyncCall asyncCall(env, info, ctxt, 0);
|
||||
return asyncCall.Call(env, exec);
|
||||
}
|
||||
|
||||
napi_value JsPanel::Hide(napi_env env, napi_callback_info info)
|
||||
{
|
||||
auto ctxt = std::make_shared<PanelContentContext>(env, info);
|
||||
auto exec = [ctxt](AsyncCall::Context *ctx) {
|
||||
auto &inputMethodPanel = reinterpret_cast<JsPanel *>(ctxt->native)->GetNative();
|
||||
CHECK_RETURN_VOID(inputMethodPanel != nullptr, "inputMethodPanel_ is nullptr.");
|
||||
auto code = inputMethodPanel->HidePanel();
|
||||
if (code == ErrorCode::NO_ERROR) {
|
||||
ctxt->SetState(napi_ok);
|
||||
return;
|
||||
}
|
||||
ctxt->SetErrorCode(code);
|
||||
};
|
||||
AsyncCall asyncCall(env, info, ctxt, 0);
|
||||
return asyncCall.Call(env, exec);
|
||||
}
|
||||
|
||||
napi_value JsPanel::ChangeFlag(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = ARGC_MAX;
|
||||
napi_value argv[ARGC_MAX] = { nullptr };
|
||||
napi_value thisVar = nullptr;
|
||||
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
|
||||
PARAM_CHECK_RETURN(env, argc > 0, " should 1 parameter! ", TYPE_NONE, nullptr);
|
||||
int32_t panelFlag = 0;
|
||||
napi_status status = JsUtils::GetValue(env, argv[ARGC_ZERO], panelFlag);
|
||||
NAPI_ASSERT(env, status == napi_ok, "get panelFlag failed!");
|
||||
auto inputMethodPanel = UnwrapPanel(env, thisVar);
|
||||
auto ret = inputMethodPanel->ChangePanelFlag(PanelFlag(panelFlag));
|
||||
NAPI_ASSERT(env, ret == ErrorCode::NO_ERROR, "ChangePanelFlag failed!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
napi_value JsPanel::Subscribe(napi_env env, napi_callback_info info)
|
||||
{
|
||||
IMSA_HILOGD("JsPanel in");
|
||||
size_t argc = ARGC_MAX;
|
||||
napi_value argv[ARGC_MAX] = { nullptr };
|
||||
napi_value thisVar = nullptr;
|
||||
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
|
||||
NAPI_ASSERT(env, (argc >= ARGC_ONE) && (argc <= ARGC_MAX), "err number of argument!");
|
||||
std::string type = "";
|
||||
JsUtils::GetValue(env, argv[ARGC_ZERO], type);
|
||||
IMSA_HILOGD("on event type is: %{public}s", type.c_str());
|
||||
|
||||
napi_valuetype valuetype = napi_undefined;
|
||||
napi_typeof(env, argv[1], &valuetype);
|
||||
NAPI_ASSERT(env, valuetype == napi_function, "callback is not a function");
|
||||
std::shared_ptr<PanelListenerImpl> observer = PanelListenerImpl::GetInstance();
|
||||
auto inputMethodPanel = UnwrapPanel(env, thisVar);
|
||||
observer->SaveInfo(env, type, argv[ARGC_ONE], inputMethodPanel->windowId_);
|
||||
inputMethodPanel->SetPanelStatusListener(observer);
|
||||
napi_value result = nullptr;
|
||||
napi_get_undefined(env, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
napi_value JsPanel::UnSubscribe(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = ARGC_MAX;
|
||||
napi_value argv[ARGC_MAX] = { nullptr };
|
||||
napi_value thisVar = nullptr;
|
||||
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
|
||||
NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments, requires 1 or 2");
|
||||
std::string type = "";
|
||||
JsUtils::GetValue(env, argv[ARGC_ZERO], type);
|
||||
IMSA_HILOGI("event type is: %{public}s", type.c_str());
|
||||
std::shared_ptr<PanelListenerImpl> observer = PanelListenerImpl::GetInstance();
|
||||
auto inputMethodPanel = UnwrapPanel(env, thisVar);
|
||||
observer->RemoveInfo(type, inputMethodPanel->windowId_);
|
||||
inputMethodPanel->RemovePanelListener(type);
|
||||
napi_value result = nullptr;
|
||||
napi_get_null(env, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::shared_ptr<InputMethodPanel> JsPanel::UnwrapPanel(napi_env env, napi_value thisVar)
|
||||
{
|
||||
void *native = nullptr;
|
||||
napi_status status = napi_unwrap(env, thisVar, &native);
|
||||
NAPI_ASSERT_BASE(env, (status == napi_ok && native != nullptr), "napi_unwrap failed!", nullptr);
|
||||
auto jsPanel = reinterpret_cast<JsPanel *>(native);
|
||||
if (jsPanel == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
auto &inputMethodPanel = jsPanel->GetNative();
|
||||
NAPI_ASSERT_BASE(env, inputMethodPanel != nullptr, "inputMethodPanel is nullptr", nullptr);
|
||||
return inputMethodPanel;
|
||||
}
|
||||
} // namespace MiscServices
|
||||
} // namespace OHOS
|
84
frameworks/js/napi/inputmethodability/js_panel.h
Normal file
84
frameworks/js/napi/inputmethodability/js_panel.h
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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_JSPANEL_H
|
||||
#define INPUTMETHOD_IMF_JSPANEL_H
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
#include "async_call.h"
|
||||
#include "input_method_panel.h"
|
||||
#include "js_callback_object.h"
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_common.h"
|
||||
#include "napi/native_node_api.h"
|
||||
#include "native_engine/native_engine.h"
|
||||
#include "native_engine/native_value.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
class JsPanel {
|
||||
public:
|
||||
JsPanel() = default;
|
||||
~JsPanel();
|
||||
static napi_value Constructor(napi_env env);
|
||||
static napi_value SetUiContent(napi_env env, napi_callback_info info);
|
||||
static napi_value Resize(napi_env env, napi_callback_info info);
|
||||
static napi_value MoveTo(napi_env env, napi_callback_info info);
|
||||
static napi_value Show(napi_env env, napi_callback_info info);
|
||||
static napi_value Hide(napi_env env, napi_callback_info info);
|
||||
static napi_value ChangeFlag(napi_env env, napi_callback_info info);
|
||||
static napi_value Subscribe(napi_env env, napi_callback_info info);
|
||||
static napi_value UnSubscribe(napi_env env, napi_callback_info info);
|
||||
void SetNative(const std::shared_ptr<InputMethodPanel> &panel);
|
||||
std::shared_ptr<InputMethodPanel> &GetNative();
|
||||
private:
|
||||
struct PanelContentContext : public AsyncCall::Context {
|
||||
std::string path = "";
|
||||
uint32_t width = 0;
|
||||
uint32_t height = 0;
|
||||
void *native = nullptr;
|
||||
std::shared_ptr<NativeReference> contentStorage = nullptr;
|
||||
PanelContentContext(napi_env env, napi_callback_info info) : Context(nullptr, nullptr)
|
||||
{
|
||||
napi_value self = nullptr;
|
||||
napi_status status = napi_get_cb_info(env, info, 0, nullptr, &self, nullptr);
|
||||
status = napi_unwrap(env, self, &native);
|
||||
};
|
||||
PanelContentContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)){};
|
||||
napi_status operator()(napi_env env, size_t argc, napi_value *argv, napi_value self) override
|
||||
{
|
||||
NAPI_ASSERT_BASE(env, self != nullptr, "self is nullptr", napi_invalid_arg);
|
||||
return Context::operator()(env, argc, argv, self);
|
||||
}
|
||||
napi_status operator()(napi_env env, napi_value *result) override
|
||||
{
|
||||
if (status_ != napi_ok) {
|
||||
output_ = nullptr;
|
||||
return status_;
|
||||
}
|
||||
return Context::operator()(env, result);
|
||||
}
|
||||
};
|
||||
static napi_value JsNew(napi_env env, napi_callback_info info);
|
||||
static std::shared_ptr<InputMethodPanel> UnwrapPanel(napi_env env, napi_value thisVar);
|
||||
static const std::string CLASS_NAME;
|
||||
static constexpr size_t ARGC_MAX = 6;
|
||||
std::shared_ptr<InputMethodPanel> inputMethodPanel_ = nullptr;
|
||||
};
|
||||
} // namespace MiscServices
|
||||
} // namespace OHOS
|
||||
|
||||
#endif //INPUTMETHOD_IMF_JSPANEL_H
|
@ -55,20 +55,8 @@ napi_value JsTextInputClientEngine::MoveCursor(napi_env env, napi_callback_info
|
||||
{
|
||||
auto ctxt = std::make_shared<MoveCursorContext>();
|
||||
auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
|
||||
napi_status status = napi_generic_failure;
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_typeof(env, argv[0], &valueType);
|
||||
if (argc < 1) {
|
||||
JsUtils::ThrowException(
|
||||
env, IMFErrorCode::EXCEPTION_PARAMCHECK, " should 1 or 2 parameters!", TypeCode::TYPE_NONE);
|
||||
return status;
|
||||
}
|
||||
if (valueType != napi_number) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, " direction", TypeCode::TYPE_NUMBER);
|
||||
return status;
|
||||
}
|
||||
status = GetMoveCursorParam(env, argv[0], ctxt);
|
||||
return status;
|
||||
PARAM_CHECK_RETURN(env, argc > 0, " should 1 or 2 parameters! ", TYPE_NONE, napi_generic_failure);
|
||||
return JsUtils::GetValue(env, argv[0], ctxt->num);
|
||||
};
|
||||
auto exec = [ctxt](AsyncCall::Context *ctx) {
|
||||
int32_t code = InputMethodAbility::GetInstance()->MoveCursor(ctxt->num);
|
||||
@ -127,26 +115,6 @@ napi_value JsTextInputClientEngine::GetTextInputClientInstance(napi_env env)
|
||||
return instance;
|
||||
}
|
||||
|
||||
int32_t JsTextInputClientEngine::GetNumberProperty(napi_env env, napi_value jsNumber)
|
||||
{
|
||||
int32_t number;
|
||||
if (napi_get_value_int32(env, jsNumber, &number) != napi_ok) {
|
||||
IMSA_HILOGE("GetNumberProperty error");
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
std::string JsTextInputClientEngine::GetStringProperty(napi_env env, napi_value jsString)
|
||||
{
|
||||
char propValue[MAX_VALUE_LEN] = { 0 };
|
||||
size_t propLen;
|
||||
if (napi_get_value_string_utf8(env, jsString, propValue, MAX_VALUE_LEN, &propLen) != napi_ok) {
|
||||
IMSA_HILOGE("GetStringProperty error");
|
||||
return "";
|
||||
}
|
||||
return std::string(propValue);
|
||||
}
|
||||
|
||||
napi_value JsTextInputClientEngine::GetResult(napi_env env, std::string &text)
|
||||
{
|
||||
napi_value jsText = nullptr;
|
||||
@ -171,112 +139,18 @@ napi_value JsTextInputClientEngine::GetResultEditorAttribute(
|
||||
return editorAttribute;
|
||||
}
|
||||
|
||||
napi_status JsTextInputClientEngine::GetAction(
|
||||
napi_env env, napi_value argv, std::shared_ptr<SendKeyFunctionContext> ctxt)
|
||||
{
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_status status = napi_generic_failure;
|
||||
status = napi_typeof(env, argv, &valueType);
|
||||
if (valueType == napi_number) {
|
||||
ctxt->action = GetNumberProperty(env, argv);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
napi_status JsTextInputClientEngine::GetDeleteForwardLength(
|
||||
napi_env env, napi_value argv, std::shared_ptr<DeleteForwardContext> ctxt)
|
||||
{
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_status status = napi_generic_failure;
|
||||
status = napi_typeof(env, argv, &valueType);
|
||||
if (valueType == napi_number) {
|
||||
ctxt->length = GetNumberProperty(env, argv);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
napi_status JsTextInputClientEngine::GetMoveCursorParam(
|
||||
napi_env env, napi_value argv, std::shared_ptr<MoveCursorContext> ctxt)
|
||||
{
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_status status = napi_generic_failure;
|
||||
status = napi_typeof(env, argv, &valueType);
|
||||
if (valueType == napi_number) {
|
||||
ctxt->num = GetNumberProperty(env, argv);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
napi_status JsTextInputClientEngine::GetDeleteBackwardLength(
|
||||
napi_env env, napi_value argv, std::shared_ptr<DeleteBackwardContext> ctxt)
|
||||
{
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_status status = napi_generic_failure;
|
||||
status = napi_typeof(env, argv, &valueType);
|
||||
if (valueType == napi_number) {
|
||||
ctxt->length = GetNumberProperty(env, argv);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
napi_status JsTextInputClientEngine::GetInsertText(
|
||||
napi_env env, napi_value argv, std::shared_ptr<InsertTextContext> ctxt)
|
||||
{
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_status status = napi_generic_failure;
|
||||
status = napi_typeof(env, argv, &valueType);
|
||||
if (valueType == napi_string) {
|
||||
ctxt->text = GetStringProperty(env, argv);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
napi_status JsTextInputClientEngine::GetForwardLength(
|
||||
napi_env env, napi_value argv, std::shared_ptr<GetForwardContext> ctxt)
|
||||
{
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_status status = napi_generic_failure;
|
||||
status = napi_typeof(env, argv, &valueType);
|
||||
if (valueType == napi_number) {
|
||||
ctxt->length = GetNumberProperty(env, argv);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
napi_status JsTextInputClientEngine::GetBackwardLength(
|
||||
napi_env env, napi_value argv, std::shared_ptr<GetBackwardContext> ctxt)
|
||||
{
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_status status = napi_generic_failure;
|
||||
status = napi_typeof(env, argv, &valueType);
|
||||
if (valueType == napi_number) {
|
||||
ctxt->length = GetNumberProperty(env, argv);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
napi_status JsTextInputClientEngine::GetSelectRange(napi_env env, napi_value argv, std::shared_ptr<SelectContext> ctxt)
|
||||
{
|
||||
napi_status status = napi_generic_failure;
|
||||
napi_value napiValue = nullptr;
|
||||
status = napi_get_named_property(env, argv, "start", &napiValue);
|
||||
if (status != napi_ok) {
|
||||
JsUtils::ThrowException(
|
||||
env, IMFErrorCode::EXCEPTION_PARAMCHECK, "missing start parameter.", TypeCode::TYPE_NONE);
|
||||
return status;
|
||||
}
|
||||
status = napi_get_value_int32(env, napiValue, &ctxt->start);
|
||||
if (status != napi_ok) {
|
||||
IMSA_HILOGE("failed to get start value");
|
||||
return status;
|
||||
}
|
||||
PARAM_CHECK_RETURN(env, status == napi_ok, "missing start parameter.", TYPE_NONE, status);
|
||||
status = JsUtils::GetValue(env, napiValue, ctxt->start);
|
||||
NAPI_ASSERT_BASE(env, status == napi_ok, "failed to get start value", status);
|
||||
|
||||
status = napi_get_named_property(env, argv, "end", &napiValue);
|
||||
if (status != napi_ok) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "missing end parameter.", TypeCode::TYPE_NONE);
|
||||
return status;
|
||||
}
|
||||
status = napi_get_value_int32(env, napiValue, &ctxt->end);
|
||||
PARAM_CHECK_RETURN(env, status == napi_ok, "missing end parameter.", TYPE_NONE, status);
|
||||
status = JsUtils::GetValue(env, napiValue, ctxt->end);
|
||||
if (status != napi_ok) {
|
||||
IMSA_HILOGE("failed to get end value");
|
||||
}
|
||||
@ -289,12 +163,8 @@ napi_status JsTextInputClientEngine::GetSelectMovement(
|
||||
napi_status status = napi_generic_failure;
|
||||
napi_value napiValue = nullptr;
|
||||
status = napi_get_named_property(env, argv, "direction", &napiValue);
|
||||
if (status != napi_ok) {
|
||||
JsUtils::ThrowException(
|
||||
env, IMFErrorCode::EXCEPTION_PARAMCHECK, "missing direction parameter.", TypeCode::TYPE_NONE);
|
||||
return status;
|
||||
}
|
||||
status = napi_get_value_int32(env, napiValue, &ctxt->direction);
|
||||
PARAM_CHECK_RETURN(env, status == napi_ok, "missing direction parameter.", TYPE_NONE, status);
|
||||
status = JsUtils::GetValue(env, napiValue, ctxt->direction);
|
||||
if (status != napi_ok) {
|
||||
IMSA_HILOGE("failed to get direction value");
|
||||
}
|
||||
@ -305,20 +175,8 @@ napi_value JsTextInputClientEngine::SendKeyFunction(napi_env env, napi_callback_
|
||||
{
|
||||
auto ctxt = std::make_shared<SendKeyFunctionContext>();
|
||||
auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
|
||||
napi_status status = napi_generic_failure;
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_typeof(env, argv[0], &valueType);
|
||||
if (argc < 1) {
|
||||
JsUtils::ThrowException(
|
||||
env, IMFErrorCode::EXCEPTION_PARAMCHECK, " should 1 or 2 parameters!", TypeCode::TYPE_NONE);
|
||||
return status;
|
||||
}
|
||||
if (valueType != napi_number) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, " 'action'", TypeCode::TYPE_NUMBER);
|
||||
return status;
|
||||
}
|
||||
status = GetAction(env, argv[0], ctxt);
|
||||
return status;
|
||||
PARAM_CHECK_RETURN(env, argc > 0, "should 1 or 2 parameters!", TYPE_NONE, napi_generic_failure);
|
||||
return JsUtils::GetValue(env, argv[0], ctxt->action);
|
||||
};
|
||||
auto output = [ctxt](napi_env env, napi_value *result) -> napi_status {
|
||||
napi_status status = napi_get_boolean(env, ctxt->isSendKeyFunction, result);
|
||||
@ -343,20 +201,8 @@ napi_value JsTextInputClientEngine::DeleteForward(napi_env env, napi_callback_in
|
||||
{
|
||||
auto ctxt = std::make_shared<DeleteForwardContext>();
|
||||
auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
|
||||
napi_status status = napi_generic_failure;
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_typeof(env, argv[0], &valueType);
|
||||
if (argc < 1) {
|
||||
JsUtils::ThrowException(
|
||||
env, IMFErrorCode::EXCEPTION_PARAMCHECK, " should 1 or 2 parameters!", TypeCode::TYPE_NONE);
|
||||
return status;
|
||||
}
|
||||
if (valueType != napi_number) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, " 'length'", TypeCode::TYPE_NUMBER);
|
||||
return status;
|
||||
}
|
||||
status = GetDeleteForwardLength(env, argv[0], ctxt);
|
||||
return status;
|
||||
PARAM_CHECK_RETURN(env, argc > 0, "should 1 or 2 parameters!", TYPE_NONE, napi_generic_failure);
|
||||
return JsUtils::GetValue(env, argv[0], ctxt->length);
|
||||
};
|
||||
auto output = [ctxt](napi_env env, napi_value *result) -> napi_status {
|
||||
napi_status status = napi_get_boolean(env, ctxt->isDeleteForward, result);
|
||||
@ -381,20 +227,8 @@ napi_value JsTextInputClientEngine::DeleteBackward(napi_env env, napi_callback_i
|
||||
{
|
||||
auto ctxt = std::make_shared<DeleteBackwardContext>();
|
||||
auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
|
||||
napi_status status = napi_generic_failure;
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_typeof(env, argv[0], &valueType);
|
||||
if (argc < 1) {
|
||||
JsUtils::ThrowException(
|
||||
env, IMFErrorCode::EXCEPTION_PARAMCHECK, " should 1 or 2 parameters!", TypeCode::TYPE_NONE);
|
||||
return status;
|
||||
}
|
||||
if (valueType != napi_number) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, " 'length", TypeCode::TYPE_NUMBER);
|
||||
return status;
|
||||
}
|
||||
status = GetDeleteBackwardLength(env, argv[0], ctxt);
|
||||
return status;
|
||||
PARAM_CHECK_RETURN(env, argc > 0, "should 1 or 2 parameters!", TYPE_NONE, napi_generic_failure);
|
||||
return JsUtils::GetValue(env, argv[0], ctxt->length);
|
||||
};
|
||||
auto output = [ctxt](napi_env env, napi_value *result) -> napi_status {
|
||||
napi_status status = napi_get_boolean(env, ctxt->isDeleteBackward, result);
|
||||
@ -419,20 +253,8 @@ napi_value JsTextInputClientEngine::InsertText(napi_env env, napi_callback_info
|
||||
{
|
||||
auto ctxt = std::make_shared<InsertTextContext>();
|
||||
auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
|
||||
napi_status status = napi_generic_failure;
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_typeof(env, argv[0], &valueType);
|
||||
if (argc < 1) {
|
||||
JsUtils::ThrowException(
|
||||
env, IMFErrorCode::EXCEPTION_PARAMCHECK, " should 1 or 2 parameters!", TypeCode::TYPE_NONE);
|
||||
return status;
|
||||
}
|
||||
if (valueType != napi_string) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, " 'text'", TypeCode::TYPE_STRING);
|
||||
return status;
|
||||
}
|
||||
status = GetInsertText(env, argv[0], ctxt);
|
||||
return status;
|
||||
PARAM_CHECK_RETURN(env, argc > 0, "should 1 or 2 parameters!", TYPE_NONE, napi_generic_failure);
|
||||
return JsUtils::GetValue(env, argv[0], ctxt->text);
|
||||
};
|
||||
auto output = [ctxt](napi_env env, napi_value *result) -> napi_status {
|
||||
napi_status status = napi_get_boolean(env, ctxt->isInsertText, result);
|
||||
@ -457,20 +279,8 @@ napi_value JsTextInputClientEngine::GetForward(napi_env env, napi_callback_info
|
||||
{
|
||||
auto ctxt = std::make_shared<GetForwardContext>();
|
||||
auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
|
||||
napi_status status = napi_generic_failure;
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_typeof(env, argv[0], &valueType);
|
||||
if (argc < 1) {
|
||||
JsUtils::ThrowException(
|
||||
env, IMFErrorCode::EXCEPTION_PARAMCHECK, " should 1 or 2 parameters!", TypeCode::TYPE_NONE);
|
||||
return status;
|
||||
}
|
||||
if (valueType != napi_number) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, " 'length'", TypeCode::TYPE_NUMBER);
|
||||
return status;
|
||||
}
|
||||
status = GetForwardLength(env, argv[0], ctxt);
|
||||
return status;
|
||||
PARAM_CHECK_RETURN(env, argc > 0, "should 1 or 2 parameters!", TYPE_NONE, napi_generic_failure);
|
||||
return JsUtils::GetValue(env, argv[0], ctxt->length);
|
||||
};
|
||||
auto output = [ctxt](napi_env env, napi_value *result) -> napi_status {
|
||||
napi_value data = GetResult(env, ctxt->text);
|
||||
@ -497,20 +307,8 @@ napi_value JsTextInputClientEngine::GetBackward(napi_env env, napi_callback_info
|
||||
{
|
||||
auto ctxt = std::make_shared<GetBackwardContext>();
|
||||
auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
|
||||
napi_status status = napi_generic_failure;
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
if (argc < 1) {
|
||||
JsUtils::ThrowException(
|
||||
env, IMFErrorCode::EXCEPTION_PARAMCHECK, " should 1 or 2 parameters!", TypeCode::TYPE_NONE);
|
||||
return status;
|
||||
}
|
||||
napi_typeof(env, argv[0], &valueType);
|
||||
if (valueType != napi_number) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, " 'length'", TypeCode::TYPE_NUMBER);
|
||||
return status;
|
||||
}
|
||||
status = GetBackwardLength(env, argv[0], ctxt);
|
||||
return status;
|
||||
PARAM_CHECK_RETURN(env, argc > 0, "should 1 or 2 parameters!", TYPE_NONE, napi_generic_failure);
|
||||
return JsUtils::GetValue(env, argv[0], ctxt->length);
|
||||
};
|
||||
auto output = [ctxt](napi_env env, napi_value *result) -> napi_status {
|
||||
napi_value data = GetResult(env, ctxt->text);
|
||||
@ -563,17 +361,10 @@ napi_value JsTextInputClientEngine::SelectByRange(napi_env env, napi_callback_in
|
||||
IMSA_HILOGD("run in");
|
||||
auto ctxt = std::make_shared<SelectContext>();
|
||||
auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
|
||||
if (argc < 1) {
|
||||
JsUtils::ThrowException(
|
||||
env, IMFErrorCode::EXCEPTION_PARAMCHECK, " should 1 or 2 parameters!", TypeCode::TYPE_NONE);
|
||||
return napi_generic_failure;
|
||||
}
|
||||
PARAM_CHECK_RETURN(env, argc > 0, "should 1 or 2 parameters!", TYPE_NONE, napi_generic_failure);
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_typeof(env, argv[0], &valueType);
|
||||
if (valueType != napi_object) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "range", TypeCode::TYPE_OBJECT);
|
||||
return napi_generic_failure;
|
||||
}
|
||||
PARAM_CHECK_RETURN(env, valueType == napi_object, "range", TYPE_OBJECT, napi_generic_failure);
|
||||
return GetSelectRange(env, argv[0], ctxt);
|
||||
};
|
||||
auto output = [ctxt](napi_env env, napi_value *result) -> napi_status { return napi_ok; };
|
||||
@ -596,17 +387,10 @@ napi_value JsTextInputClientEngine::SelectByMovement(napi_env env, napi_callback
|
||||
IMSA_HILOGD("run in");
|
||||
auto ctxt = std::make_shared<SelectContext>();
|
||||
auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
|
||||
if (argc < 1) {
|
||||
JsUtils::ThrowException(
|
||||
env, IMFErrorCode::EXCEPTION_PARAMCHECK, " should 1 or 2 parameters!", TypeCode::TYPE_NONE);
|
||||
return napi_generic_failure;
|
||||
}
|
||||
PARAM_CHECK_RETURN(env, argc > 0, "should 1 or 2 parameters!", TYPE_NONE, napi_generic_failure);
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_typeof(env, argv[0], &valueType);
|
||||
if (valueType != napi_object) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "movement", TypeCode::TYPE_OBJECT);
|
||||
return napi_generic_failure;
|
||||
}
|
||||
PARAM_CHECK_RETURN(env, valueType == napi_object, "movement", TYPE_NUMBER, napi_generic_failure);
|
||||
return GetSelectMovement(env, argv[0], ctxt);
|
||||
};
|
||||
auto output = [ctxt](napi_env env, napi_value *result) -> napi_status { return napi_ok; };
|
||||
|
@ -253,21 +253,10 @@ public:
|
||||
static napi_value SelectByMovement(napi_env env, napi_callback_info info);
|
||||
|
||||
private:
|
||||
static napi_status GetAction(napi_env env, napi_value argv, std::shared_ptr<SendKeyFunctionContext> ctxt);
|
||||
static napi_status GetDeleteForwardLength(
|
||||
napi_env env, napi_value argv, std::shared_ptr<DeleteForwardContext> ctxt);
|
||||
static napi_status GetDeleteBackwardLength(
|
||||
napi_env env, napi_value argv, std::shared_ptr<DeleteBackwardContext> ctxt);
|
||||
static napi_status GetMoveCursorParam(napi_env env, napi_value argv, std::shared_ptr<MoveCursorContext> ctxt);
|
||||
static napi_status GetInsertText(napi_env env, napi_value argv, std::shared_ptr<InsertTextContext> ctxt);
|
||||
static napi_status GetForwardLength(napi_env env, napi_value argv, std::shared_ptr<GetForwardContext> ctxt);
|
||||
static napi_status GetBackwardLength(napi_env env, napi_value argv, std::shared_ptr<GetBackwardContext> ctxt);
|
||||
static napi_status GetSelectRange(napi_env env, napi_value argv, std::shared_ptr<SelectContext> ctxt);
|
||||
static napi_status GetSelectMovement(napi_env env, napi_value argv, std::shared_ptr<SelectContext> ctxt);
|
||||
|
||||
static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo);
|
||||
static int32_t GetNumberProperty(napi_env env, napi_value jsNumber);
|
||||
static std::string GetStringProperty(napi_env env, napi_value jsString);
|
||||
static napi_value GetResult(napi_env env, std::string &text);
|
||||
static napi_value GetResultEditorAttribute(
|
||||
napi_env env, std::shared_ptr<GetEditorAttributeContext> getEditorAttribute);
|
||||
|
121
frameworks/js/napi/inputmethodability/panel_listener_impl.cpp
Normal file
121
frameworks/js/napi/inputmethodability/panel_listener_impl.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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 "panel_listener_impl.h"
|
||||
|
||||
#include "js_utils.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
std::shared_ptr<PanelListenerImpl> PanelListenerImpl::instance_{ nullptr };
|
||||
std::mutex PanelListenerImpl::listenerMutex_;
|
||||
std::shared_ptr<PanelListenerImpl> PanelListenerImpl::GetInstance()
|
||||
{
|
||||
if (instance_ == nullptr) {
|
||||
std::lock_guard<std::mutex> lock(listenerMutex_);
|
||||
if (instance_ == nullptr) {
|
||||
auto engine = std::make_shared<PanelListenerImpl>();
|
||||
if (engine == nullptr) {
|
||||
IMSA_HILOGE("input method engine nullptr");
|
||||
return nullptr;
|
||||
}
|
||||
instance_ = engine;
|
||||
}
|
||||
}
|
||||
return instance_;
|
||||
}
|
||||
|
||||
PanelListenerImpl::~PanelListenerImpl()
|
||||
{
|
||||
env_ = nullptr;
|
||||
}
|
||||
|
||||
void PanelListenerImpl::SaveInfo(napi_env env, const std::string &type, napi_value callback, uint32_t windowId)
|
||||
{
|
||||
env_ = env;
|
||||
std::shared_ptr<JSCallbackObject> cbObject =
|
||||
std::make_shared<JSCallbackObject>(env, callback, std::this_thread::get_id());
|
||||
auto result = callbacks_.Find(windowId);
|
||||
if (!result.first) {
|
||||
ConcurrentMap<std::string, std::shared_ptr<JSCallbackObject>> cbs{};
|
||||
cbs.Insert(type, cbObject);
|
||||
callbacks_.Insert(windowId, cbs);
|
||||
} else {
|
||||
auto res = result.second.Find(type);
|
||||
if (!res.first) {
|
||||
result.second.Insert(type, cbObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PanelListenerImpl::RemoveInfo(const std::string &type, uint32_t windowId)
|
||||
{
|
||||
auto result = callbacks_.Find(windowId);
|
||||
if (result.first) {
|
||||
result.second.Erase(type);
|
||||
if (result.second.Empty()) {
|
||||
callbacks_.Erase(windowId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PanelListenerImpl::OnPanelStatus(uint32_t windowId, bool isShow)
|
||||
{
|
||||
IMSA_HILOGI("PanelListenerImpl, run in");
|
||||
std::string type = isShow ? "show" : "hide";
|
||||
uv_work_t *work = new (std::nothrow) uv_work_t;
|
||||
if (work == nullptr) {
|
||||
IMSA_HILOGE("uv_work_t is nullptr!");
|
||||
return;
|
||||
}
|
||||
auto result = callbacks_.Find(windowId);
|
||||
if (!result.first) {
|
||||
IMSA_HILOGE("no callback of windowId = %{public}d!", windowId);
|
||||
return;
|
||||
}
|
||||
auto callback = result.second.Find(type);
|
||||
if (!callback.first) {
|
||||
IMSA_HILOGE("no callback in map!");
|
||||
return;
|
||||
}
|
||||
work->data = new (std::nothrow) UvEntry(callback.second);
|
||||
uv_loop_s *loop = nullptr;
|
||||
napi_get_uv_event_loop(env_, &loop);
|
||||
uv_queue_work(
|
||||
loop, work, [](uv_work_t *work) {},
|
||||
[](uv_work_t *work, int status) {
|
||||
napi_value callback = nullptr;
|
||||
std::shared_ptr<UvEntry> entry(static_cast<UvEntry *>(work->data), [work](UvEntry *data) {
|
||||
delete data;
|
||||
delete work;
|
||||
});
|
||||
CHECK_RETURN_VOID(entry != nullptr, "OnInputStart:: entry is null.");
|
||||
napi_handle_scope scope = nullptr;
|
||||
napi_open_handle_scope(entry->cbCopy->env_, &scope);
|
||||
napi_get_reference_value(entry->cbCopy->env_, entry->cbCopy->callback_, &callback);
|
||||
if (callback != nullptr) {
|
||||
napi_value global = nullptr;
|
||||
napi_get_global(entry->cbCopy->env_, &global);
|
||||
napi_value result = nullptr;
|
||||
napi_status callStatus = napi_call_function(entry->cbCopy->env_, global, callback, 0, nullptr, &result);
|
||||
if (callStatus != napi_ok) {
|
||||
IMSA_HILOGE("notify data change failed callStatus:%{public}d", callStatus);
|
||||
}
|
||||
}
|
||||
napi_close_handle_scope(entry->cbCopy->env_, scope);
|
||||
});
|
||||
}
|
||||
} // namespace MiscServices
|
||||
} // namespace OHOS
|
51
frameworks/js/napi/inputmethodability/panel_listener_impl.h
Normal file
51
frameworks/js/napi/inputmethodability/panel_listener_impl.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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_PANEL_LISTENER_IMPL_H
|
||||
#define INPUTMETHOD_IMF_PANEL_LISTENER_IMPL_H
|
||||
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <uv.h>
|
||||
|
||||
#include "concurrent_map.h"
|
||||
#include "js_callback_object.h"
|
||||
#include "panel_status_listener.h"
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_node_api.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
class PanelListenerImpl : public PanelStatusListener {
|
||||
public:
|
||||
static std::shared_ptr<PanelListenerImpl> GetInstance();
|
||||
~PanelListenerImpl();
|
||||
void OnPanelStatus(uint32_t windowId, bool isShow) override;
|
||||
void SaveInfo(napi_env env, const std::string &type, napi_value callback, uint32_t windowId);
|
||||
void RemoveInfo(const std::string &type, uint32_t windowId);
|
||||
|
||||
struct UvEntry {
|
||||
std::shared_ptr<JSCallbackObject> cbCopy;
|
||||
explicit UvEntry(const std::shared_ptr<JSCallbackObject> &cb) : cbCopy(cb) {}
|
||||
};
|
||||
napi_env env_ = nullptr;
|
||||
ConcurrentMap<uint32_t, ConcurrentMap<std::string, std::shared_ptr<JSCallbackObject>>> callbacks_;
|
||||
static std::mutex listenerMutex_;
|
||||
static std::shared_ptr<PanelListenerImpl> instance_;
|
||||
};
|
||||
} // namespace MiscServices
|
||||
} // namespace OHOS
|
||||
|
||||
#endif //INPUTMETHOD_IMF_PANEL_LISTENER_IMPL_H
|
@ -20,6 +20,7 @@
|
||||
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
constexpr size_t ARGC_MAX = 6;
|
||||
AsyncCall::AsyncCall(napi_env env, napi_callback_info info, std::shared_ptr<Context> context, size_t pos) : env_(env)
|
||||
{
|
||||
context_ = new AsyncContext();
|
||||
@ -111,10 +112,10 @@ void AsyncCall::OnComplete(napi_env env, napi_status status, void *data)
|
||||
if (status == napi_ok && runStatus == napi_ok) {
|
||||
napi_get_undefined(env, &result[ARG_ERROR]);
|
||||
if (output != nullptr) {
|
||||
IMSA_HILOGE("AsyncCall::OnComplete output != nullptr");
|
||||
IMSA_HILOGI("AsyncCall::OnComplete output != nullptr");
|
||||
result[ARG_DATA] = output;
|
||||
} else {
|
||||
IMSA_HILOGE("AsyncCall::OnComplete output == nullptr");
|
||||
IMSA_HILOGI("AsyncCall::OnComplete output == nullptr");
|
||||
napi_get_undefined(env, &result[ARG_DATA]);
|
||||
}
|
||||
} else {
|
||||
|
@ -16,6 +16,7 @@
|
||||
#define ASYN_CALL_H
|
||||
|
||||
#include "input_method_info.h"
|
||||
#include "global.h"
|
||||
#include "js_utils.h"
|
||||
#include "napi/native_api.h"
|
||||
#include "napi/native_common.h"
|
||||
@ -91,7 +92,6 @@ public:
|
||||
napi_status status_ = napi_generic_failure;
|
||||
int32_t errorCode_ = 0;
|
||||
};
|
||||
static constexpr size_t ARGC_MAX = 6;
|
||||
static constexpr size_t ASYNC_DEFAULT_POS = -1;
|
||||
AsyncCall(napi_env env, napi_callback_info info, std::shared_ptr<Context> context, size_t pos = ASYNC_DEFAULT_POS);
|
||||
~AsyncCall();
|
||||
|
@ -26,7 +26,6 @@ namespace MiscServices {
|
||||
constexpr size_t ARGC_ZERO = 0;
|
||||
constexpr size_t ARGC_ONE = 1;
|
||||
constexpr size_t ARGC_TWO = 2;
|
||||
constexpr size_t ARGC_MAX = 6;
|
||||
const std::set<std::string> EVENT_TYPE{
|
||||
"selectByRange",
|
||||
"selectByMovement",
|
||||
@ -132,44 +131,6 @@ std::shared_ptr<JsGetInputMethodController> JsGetInputMethodController::GetInsta
|
||||
return controller_;
|
||||
}
|
||||
|
||||
JsGetInputMethodController *JsGetInputMethodController::GetNative(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = ARGC_MAX;
|
||||
void *native = nullptr;
|
||||
napi_value self = nullptr;
|
||||
napi_value argv[ARGC_MAX] = { nullptr };
|
||||
napi_status status = napi_invalid_arg;
|
||||
napi_get_cb_info(env, info, &argc, argv, &self, nullptr);
|
||||
if (self == nullptr && argc >= ARGC_MAX) {
|
||||
IMSA_HILOGE("napi_get_cb_info failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
status = napi_unwrap(env, self, &native);
|
||||
NAPI_ASSERT(env, (status == napi_ok && native != nullptr), "napi_unwrap failed!");
|
||||
return reinterpret_cast<JsGetInputMethodController *>(native);
|
||||
}
|
||||
|
||||
bool JsGetInputMethodController::Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId)
|
||||
{
|
||||
if (copy == nullptr) {
|
||||
return (value == nullptr);
|
||||
}
|
||||
|
||||
if (threadId != std::this_thread::get_id()) {
|
||||
IMSA_HILOGD("napi_value can not be compared");
|
||||
return false;
|
||||
}
|
||||
|
||||
napi_value copyValue = nullptr;
|
||||
napi_get_reference_value(env, copy, ©Value);
|
||||
|
||||
bool isEquals = false;
|
||||
napi_strict_equals(env, value, copyValue, &isEquals);
|
||||
IMSA_HILOGD("value compare result: %{public}d", isEquals);
|
||||
return isEquals;
|
||||
}
|
||||
|
||||
void JsGetInputMethodController::RegisterListener(
|
||||
napi_value callback, std::string type, std::shared_ptr<JSCallbackObject> callbackObj)
|
||||
{
|
||||
@ -181,7 +142,7 @@ void JsGetInputMethodController::RegisterListener(
|
||||
|
||||
auto callbacks = jsCbMap_[type];
|
||||
bool ret = std::any_of(callbacks.begin(), callbacks.end(), [&callback](std::shared_ptr<JSCallbackObject> cb) {
|
||||
return Equals(cb->env_, callback, cb->callback_, cb->threadId_);
|
||||
return JsUtils::Equals(cb->env_, callback, cb->callback_, cb->threadId_);
|
||||
});
|
||||
if (ret) {
|
||||
IMSA_HILOGE("JsGetInputMethodController callback already registered!");
|
||||
@ -210,31 +171,13 @@ napi_value JsGetInputMethodController::Subscribe(napi_env env, napi_callback_inf
|
||||
napi_value thisVar = nullptr;
|
||||
void *data = nullptr;
|
||||
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
|
||||
if (argc < ARGC_TWO) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, " should 2 parameters!", TypeCode::TYPE_NONE);
|
||||
return nullptr;
|
||||
}
|
||||
PARAM_CHECK_RETURN(env, argc > 1, "should 2 parameters!", TYPE_NONE, nullptr);
|
||||
|
||||
napi_valuetype valuetype = napi_undefined;
|
||||
napi_typeof(env, argv[ARGC_ZERO], &valuetype);
|
||||
if (valuetype != napi_string) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "type", TypeCode::TYPE_STRING);
|
||||
return nullptr;
|
||||
}
|
||||
std::string type = "";
|
||||
napi_status status = JsUtils::GetValue(env, argv[ARGC_ZERO], type);
|
||||
PARAM_CHECK_RETURN(env, status == napi_ok, "callback", TYPE_FUNCTION, nullptr);
|
||||
|
||||
std::string type = JsInputMethod::GetStringProperty(env, argv[ARGC_ZERO]);
|
||||
if (EVENT_TYPE.find(type) == EVENT_TYPE.end()) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "unkown type", TypeCode::TYPE_NONE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
napi_typeof(env, argv[ARGC_ONE], &valuetype);
|
||||
if (valuetype != napi_function) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "callback", TypeCode::TYPE_FUNCTION);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto engine = GetNative(env, info);
|
||||
auto engine = reinterpret_cast<JsGetInputMethodController *>(JsUtils::GetNativeSelf(env, info));
|
||||
if (engine == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -254,25 +197,12 @@ napi_value JsGetInputMethodController::UnSubscribe(napi_env env, napi_callback_i
|
||||
napi_value thisVar = nullptr;
|
||||
void *data = nullptr;
|
||||
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
|
||||
if (argc < ARGC_ONE) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, " should 1 parameters!", TypeCode::TYPE_NONE);
|
||||
return nullptr;
|
||||
}
|
||||
PARAM_CHECK_RETURN(env, argc > 0, "should 1 parameters!", TYPE_NONE, nullptr);
|
||||
|
||||
napi_valuetype valuetype = napi_undefined;
|
||||
napi_typeof(env, argv[ARGC_ZERO], &valuetype);
|
||||
if (valuetype != napi_string) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "type", TypeCode::TYPE_STRING);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string type = JsInputMethod::GetStringProperty(env, argv[ARGC_ZERO]);
|
||||
if (EVENT_TYPE.find(type) == EVENT_TYPE.end()) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "unkown type", TypeCode::TYPE_NONE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto engine = GetNative(env, info);
|
||||
std::string type = "";
|
||||
JsUtils::GetValue(env, argv[ARGC_ZERO], type);
|
||||
PARAM_CHECK_RETURN(env, EVENT_TYPE.find(type) != EVENT_TYPE.end(), "unkown type", TYPE_NONE, nullptr);
|
||||
auto engine = reinterpret_cast<JsGetInputMethodController *>(JsUtils::GetNativeSelf(env, info));
|
||||
if (engine == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -68,8 +68,6 @@ private:
|
||||
static napi_value GetIMController(napi_env env, napi_callback_info cbInfo, bool needThrowException);
|
||||
static napi_value CreateSelectRange(napi_env env, int32_t start, int32_t end);
|
||||
static napi_value CreateSelectMovement(napi_env env, int32_t direction);
|
||||
static JsGetInputMethodController *GetNative(napi_env env, napi_callback_info info);
|
||||
static bool Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId);
|
||||
void RegisterListener(napi_value callback, std::string type, std::shared_ptr<JSCallbackObject> callbackObj);
|
||||
void UnRegisterListener(std::string type);
|
||||
struct UvEntry {
|
||||
|
@ -29,7 +29,6 @@ int32_t MAX_TYPE_NUM = 128;
|
||||
constexpr size_t ARGC_ZERO = 0;
|
||||
constexpr size_t ARGC_ONE = 1;
|
||||
constexpr size_t ARGC_TWO = 2;
|
||||
constexpr size_t ARGC_MAX = 6;
|
||||
thread_local napi_ref JsGetInputMethodSetting::IMSRef_ = nullptr;
|
||||
const std::string JsGetInputMethodSetting::IMS_CLASS_NAME = "InputMethodSetting";
|
||||
|
||||
@ -150,44 +149,41 @@ napi_status JsGetInputMethodSetting::GetInputMethodProperty(
|
||||
napi_env env, napi_value argv, std::shared_ptr<ListInputContext> ctxt)
|
||||
{
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_status status = napi_generic_failure;
|
||||
status = napi_typeof(env, argv, &valueType);
|
||||
napi_status status = napi_typeof(env, argv, &valueType);
|
||||
if (valueType == napi_object) {
|
||||
napi_value result = nullptr;
|
||||
napi_get_named_property(env, argv, "name", &result);
|
||||
ctxt->property.name = JsInputMethod::GetStringProperty(env, result);
|
||||
JsUtils::GetValue(env, result, ctxt->property.name);
|
||||
|
||||
result = nullptr;
|
||||
napi_get_named_property(env, argv, "id", &result);
|
||||
ctxt->property.id = JsInputMethod::GetStringProperty(env, result);
|
||||
JsUtils::GetValue(env, result, ctxt->property.id);
|
||||
|
||||
if (ctxt->property.name.empty() || ctxt->property.id.empty()) {
|
||||
result = nullptr;
|
||||
napi_get_named_property(env, argv, "packageName", &result);
|
||||
ctxt->property.name = JsInputMethod::GetStringProperty(env, result);
|
||||
JsUtils::GetValue(env, result, ctxt->property.name);
|
||||
|
||||
result = nullptr;
|
||||
napi_get_named_property(env, argv, "methodId", &result);
|
||||
ctxt->property.id = JsInputMethod::GetStringProperty(env, result);
|
||||
}
|
||||
if (ctxt->property.name.empty() || ctxt->property.id.empty()) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "Parameter error.", TYPE_NONE);
|
||||
return napi_invalid_arg;
|
||||
JsUtils::GetValue(env, result, ctxt->property.id);
|
||||
}
|
||||
PARAM_CHECK_RETURN(env, (!ctxt->property.name.empty() && !ctxt->property.id.empty()), "Parameter error.",
|
||||
TYPE_NONE, napi_invalid_arg);
|
||||
|
||||
result = nullptr;
|
||||
napi_get_named_property(env, argv, "label", &result);
|
||||
ctxt->property.label = JsInputMethod::GetStringProperty(env, result);
|
||||
JsUtils::GetValue(env, result, ctxt->property.label);
|
||||
|
||||
result = nullptr;
|
||||
napi_get_named_property(env, argv, "icon", &result);
|
||||
ctxt->property.icon = JsInputMethod::GetStringProperty(env, result);
|
||||
JsUtils::GetValue(env, result, ctxt->property.icon);
|
||||
|
||||
result = nullptr;
|
||||
napi_get_named_property(env, argv, "iconId", &result);
|
||||
ctxt->property.iconId = JsInputMethod::GetNumberProperty(env, result);
|
||||
IMSA_HILOGD("methodId:%{public}s, packageName:%{public}s", ctxt->property.id.c_str(),
|
||||
ctxt->property.name.c_str());
|
||||
status = JsUtils::GetValue(env, result, ctxt->property.iconId);
|
||||
IMSA_HILOGD(
|
||||
"methodId:%{public}s, packageName:%{public}s", ctxt->property.id.c_str(), ctxt->property.name.c_str());
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@ -224,20 +220,12 @@ napi_value JsGetInputMethodSetting::GetInputMethods(napi_env env, napi_callback_
|
||||
IMSA_HILOGI("run in GetInputMethods");
|
||||
auto ctxt = std::make_shared<ListInputContext>();
|
||||
auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
|
||||
if (argc < 1) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "should has one parameter.", TYPE_NONE);
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_typeof(env, argv[0], &valueType);
|
||||
if (valueType == napi_boolean) {
|
||||
bool enable = false;
|
||||
napi_get_value_bool(env, argv[0], &enable);
|
||||
ctxt->inputMethodStatus = enable ? InputMethodStatus::ENABLE : InputMethodStatus::DISABLE;
|
||||
return napi_ok;
|
||||
}
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, " parameter's type is wrong.", TYPE_BOOLEAN);
|
||||
return napi_generic_failure;
|
||||
PARAM_CHECK_RETURN(env, argc > 0, "should has one parameter.", TYPE_NONE, napi_invalid_arg);
|
||||
bool enable = false;
|
||||
napi_status status = JsUtils::GetValue(env, argv[ARGC_ZERO], enable);
|
||||
PARAM_CHECK_RETURN(env, status == napi_ok, "enable.", TYPE_NUMBER, napi_invalid_arg);
|
||||
ctxt->inputMethodStatus = enable ? InputMethodStatus::ENABLE : InputMethodStatus::DISABLE;
|
||||
return napi_ok;
|
||||
};
|
||||
auto output = [ctxt](napi_env env, napi_value *result) -> napi_status {
|
||||
*result = JsInputMethod::GetJSInputMethodProperties(env, ctxt->properties);
|
||||
@ -312,16 +300,10 @@ napi_value JsGetInputMethodSetting::ListInputMethodSubtype(napi_env env, napi_ca
|
||||
IMSA_HILOGI("run in ListInputMethodSubtype");
|
||||
auto ctxt = std::make_shared<ListInputContext>();
|
||||
auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
|
||||
if (argc < 1) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "should has one parameter.", TYPE_NONE);
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
PARAM_CHECK_RETURN(env, argc > 0, "should has one parameter.", TYPE_NONE, napi_invalid_arg);
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_typeof(env, argv[0], &valueType);
|
||||
if (valueType != napi_object) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, " inputMethodProperty: ", TYPE_OBJECT);
|
||||
return napi_object_expected;
|
||||
}
|
||||
PARAM_CHECK_RETURN(env, valueType == napi_object, "inputMethodProperty", TYPE_OBJECT, napi_invalid_arg);
|
||||
napi_status status = JsGetInputMethodSetting::GetInputMethodProperty(env, argv[0], ctxt);
|
||||
return status;
|
||||
};
|
||||
@ -370,44 +352,6 @@ napi_value JsGetInputMethodSetting::ListCurrentInputMethodSubtype(napi_env env,
|
||||
return asyncCall.Call(env, exec);
|
||||
}
|
||||
|
||||
JsGetInputMethodSetting *JsGetInputMethodSetting::GetNative(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = ARGC_MAX;
|
||||
void *native = nullptr;
|
||||
napi_value self = nullptr;
|
||||
napi_value argv[ARGC_MAX] = { nullptr };
|
||||
napi_status status = napi_invalid_arg;
|
||||
napi_get_cb_info(env, info, &argc, argv, &self, nullptr);
|
||||
if (self == nullptr && argc >= ARGC_MAX) {
|
||||
IMSA_HILOGE("napi_get_cb_info failed");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
status = napi_unwrap(env, self, &native);
|
||||
NAPI_ASSERT(env, (status == napi_ok && native != nullptr), "napi_unwrap failed!");
|
||||
return reinterpret_cast<JsGetInputMethodSetting *>(native);
|
||||
}
|
||||
|
||||
bool JsGetInputMethodSetting::Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId)
|
||||
{
|
||||
if (copy == nullptr) {
|
||||
return (value == nullptr);
|
||||
}
|
||||
|
||||
if (threadId != std::this_thread::get_id()) {
|
||||
IMSA_HILOGD("napi_value can not be compared");
|
||||
return false;
|
||||
}
|
||||
|
||||
napi_value copyValue = nullptr;
|
||||
napi_get_reference_value(env, copy, ©Value);
|
||||
|
||||
bool isEquals = false;
|
||||
napi_strict_equals(env, value, copyValue, &isEquals);
|
||||
IMSA_HILOGD("value compare result: %{public}d", isEquals);
|
||||
return isEquals;
|
||||
}
|
||||
|
||||
void JsGetInputMethodSetting::RegisterListener(
|
||||
napi_value callback, std::string type, std::shared_ptr<JSCallbackObject> callbackObj)
|
||||
{
|
||||
@ -419,7 +363,7 @@ void JsGetInputMethodSetting::RegisterListener(
|
||||
|
||||
auto callbacks = jsCbMap_[type];
|
||||
bool ret = std::any_of(callbacks.begin(), callbacks.end(), [&callback](std::shared_ptr<JSCallbackObject> cb) {
|
||||
return Equals(cb->env_, callback, cb->callback_, cb->threadId_);
|
||||
return JsUtils::Equals(cb->env_, callback, cb->callback_, cb->threadId_);
|
||||
});
|
||||
if (ret) {
|
||||
IMSA_HILOGE("JsGetInputMethodSetting::RegisterListener callback already registered!");
|
||||
@ -439,17 +383,15 @@ napi_value JsGetInputMethodSetting::Subscribe(napi_env env, napi_callback_info i
|
||||
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
|
||||
NAPI_ASSERT(env, argc == ARGC_TWO, "Wrong number of arguments, requires 2");
|
||||
|
||||
napi_valuetype valuetype;
|
||||
NAPI_CALL(env, napi_typeof(env, argv[ARGC_ZERO], &valuetype));
|
||||
NAPI_ASSERT(env, valuetype == napi_string, "type is not a string");
|
||||
std::string type = JsInputMethod::GetStringProperty(env, argv[ARGC_ZERO]);
|
||||
std::string type = "";
|
||||
JsUtils::GetValue(env, argv[ARGC_ZERO], type);
|
||||
IMSA_HILOGE("event type is: %{public}s", type.c_str());
|
||||
|
||||
valuetype = napi_undefined;
|
||||
napi_valuetype valuetype = napi_undefined;
|
||||
napi_typeof(env, argv[ARGC_ONE], &valuetype);
|
||||
NAPI_ASSERT(env, valuetype == napi_function, "callback is not a function");
|
||||
|
||||
auto engine = GetNative(env, info);
|
||||
auto engine = reinterpret_cast<JsGetInputMethodSetting *>(JsUtils::GetNativeSelf(env, info));
|
||||
if (engine == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -478,7 +420,7 @@ void JsGetInputMethodSetting::UnRegisterListener(napi_value callback, std::strin
|
||||
}
|
||||
|
||||
for (auto item = jsCbMap_[type].begin(); item != jsCbMap_[type].end(); item++) {
|
||||
if (Equals((*item)->env_, callback, (*item)->callback_, (*item)->threadId_)) {
|
||||
if (JsUtils::Equals((*item)->env_, callback, (*item)->callback_, (*item)->threadId_)) {
|
||||
jsCbMap_[type].erase(item);
|
||||
break;
|
||||
}
|
||||
@ -498,19 +440,16 @@ napi_value JsGetInputMethodSetting::UnSubscribe(napi_env env, napi_callback_info
|
||||
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
|
||||
NAPI_ASSERT(env, argc == ARGC_ONE || argc == ARGC_TWO, "Wrong number of arguments, requires 1 or 2");
|
||||
|
||||
napi_valuetype valuetype;
|
||||
NAPI_CALL(env, napi_typeof(env, argv[ARGC_ZERO], &valuetype));
|
||||
NAPI_ASSERT(env, valuetype == napi_string, "type is not a string");
|
||||
std::string type = JsInputMethod::GetStringProperty(env, argv[ARGC_ZERO]);
|
||||
std::string type = "";
|
||||
JsUtils::GetValue(env, argv[ARGC_ZERO], type);
|
||||
IMSA_HILOGE("event type is: %{public}s", type.c_str());
|
||||
|
||||
auto engine = GetNative(env, info);
|
||||
auto engine = reinterpret_cast<JsGetInputMethodSetting *>(JsUtils::GetNativeSelf(env, info));
|
||||
if (engine == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (argc == ARGC_TWO) {
|
||||
valuetype = napi_undefined;
|
||||
napi_valuetype valuetype = napi_undefined;
|
||||
napi_typeof(env, argv[ARGC_ONE], &valuetype);
|
||||
NAPI_ASSERT(env, valuetype == napi_function, "callback is not a function");
|
||||
}
|
||||
|
@ -113,11 +113,9 @@ public:
|
||||
|
||||
private:
|
||||
static napi_status GetInputMethodProperty(napi_env env, napi_value argv, std::shared_ptr<ListInputContext> ctxt);
|
||||
static JsGetInputMethodSetting *GetNative(napi_env env, napi_callback_info info);
|
||||
static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo);
|
||||
static napi_value GetJsConstProperty(napi_env env, uint32_t num);
|
||||
static napi_value GetIMSetting(napi_env env, napi_callback_info info, bool needThrowException);
|
||||
static bool Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId);
|
||||
void RegisterListener(napi_value callback, std::string type, std::shared_ptr<JSCallbackObject> callbackObj);
|
||||
void UnRegisterListener(napi_value callback, std::string type);
|
||||
struct UvEntry {
|
||||
|
@ -39,25 +39,6 @@ napi_value JsInputMethod::Init(napi_env env, napi_value exports)
|
||||
return exports;
|
||||
};
|
||||
|
||||
std::string JsInputMethod::GetStringProperty(napi_env env, napi_value obj)
|
||||
{
|
||||
char propValue[MAX_VALUE_LEN] = { 0 };
|
||||
size_t propLen;
|
||||
if (napi_get_value_string_utf8(env, obj, propValue, MAX_VALUE_LEN, &propLen) != napi_ok) {
|
||||
IMSA_HILOGE("GetStringProperty error");
|
||||
}
|
||||
return std::string(propValue);
|
||||
}
|
||||
|
||||
int32_t JsInputMethod::GetNumberProperty(napi_env env, napi_value obj)
|
||||
{
|
||||
int32_t out;
|
||||
if (napi_get_value_int32(env, obj, &out) != napi_ok) {
|
||||
IMSA_HILOGE("GetInt32Property error");
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
napi_status JsInputMethod::GetInputMethodProperty(
|
||||
napi_env env, napi_value argv, std::shared_ptr<SwitchInputMethodContext> ctxt)
|
||||
{
|
||||
@ -70,23 +51,25 @@ napi_status JsInputMethod::GetInputMethodProperty(
|
||||
}
|
||||
napi_value result = nullptr;
|
||||
napi_get_named_property(env, argv, "name", &result);
|
||||
ctxt->packageName = JsInputMethod::GetStringProperty(env, result);
|
||||
status = JsUtils::GetValue(env, result, ctxt->packageName);
|
||||
NAPI_ASSERT_BASE(env, status == napi_ok, "get ctxt->packageName failed!", status);
|
||||
result = nullptr;
|
||||
napi_get_named_property(env, argv, "id", &result);
|
||||
ctxt->methodId = JsInputMethod::GetStringProperty(env, result);
|
||||
status = JsUtils::GetValue(env, result, ctxt->methodId);
|
||||
NAPI_ASSERT_BASE(env, status == napi_ok, "get ctxt->methodId failed!", status);
|
||||
if (ctxt->packageName.empty() || ctxt->methodId.empty()) {
|
||||
result = nullptr;
|
||||
napi_get_named_property(env, argv, "packageName", &result);
|
||||
ctxt->packageName = JsInputMethod::GetStringProperty(env, result);
|
||||
status = JsUtils::GetValue(env, result, ctxt->packageName);
|
||||
NAPI_ASSERT_BASE(env, status == napi_ok, "get ctxt->packageName failed!", status);
|
||||
|
||||
result = nullptr;
|
||||
napi_get_named_property(env, argv, "methodId", &result);
|
||||
ctxt->methodId = JsInputMethod::GetStringProperty(env, result);
|
||||
}
|
||||
if (ctxt->packageName.empty() || ctxt->methodId.empty()) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "Parameter error.", TYPE_NONE);
|
||||
return status;
|
||||
status = JsUtils::GetValue(env, result, ctxt->methodId);
|
||||
NAPI_ASSERT_BASE(env, status == napi_ok, "get ctxt->methodId failed!", status);
|
||||
}
|
||||
PARAM_CHECK_RETURN(env, (!ctxt->packageName.empty() && !ctxt->methodId.empty()), "JsInputMethod, Parameter error.",
|
||||
TYPE_NONE, napi_invalid_arg);
|
||||
IMSA_HILOGI("methodId:%{public}s and packageName:%{public}s", ctxt->methodId.c_str(), ctxt->packageName.c_str());
|
||||
return napi_ok;
|
||||
}
|
||||
@ -100,18 +83,14 @@ napi_status JsInputMethod::GetInputMethodSubProperty(
|
||||
if (valueType == napi_object) {
|
||||
napi_value result = nullptr;
|
||||
status = napi_get_named_property(env, argv, "name", &result);
|
||||
if (status != napi_ok) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "missing name parameter.", TYPE_STRING);
|
||||
return status;
|
||||
}
|
||||
ctxt->name = GetStringProperty(env, result);
|
||||
PARAM_CHECK_RETURN(env, status == napi_ok, " name ", TYPE_STRING, status);
|
||||
status = JsUtils::GetValue(env, result, ctxt->name);
|
||||
NAPI_ASSERT_BASE(env, status == napi_ok, "get ctxt->name failed!", status);
|
||||
result = nullptr;
|
||||
status = napi_get_named_property(env, argv, "id", &result);
|
||||
if (status != napi_ok) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "missing id parameter.", TYPE_STRING);
|
||||
return status;
|
||||
}
|
||||
ctxt->id = GetStringProperty(env, result);
|
||||
PARAM_CHECK_RETURN(env, status == napi_ok, " id ", TYPE_STRING, status);
|
||||
status = JsUtils::GetValue(env, result, ctxt->id);
|
||||
NAPI_ASSERT_BASE(env, status == napi_ok, "get ctxt->id failed!", status);
|
||||
IMSA_HILOGI("name:%{public}s and id:%{public}s", ctxt->name.c_str(), ctxt->id.c_str());
|
||||
}
|
||||
return status;
|
||||
@ -125,16 +104,12 @@ napi_value JsInputMethod::GetJsInputMethodProperty(napi_env env, const Property
|
||||
napi_value packageName = nullptr;
|
||||
napi_create_string_utf8(env, property.name.c_str(), NAPI_AUTO_LENGTH, &packageName);
|
||||
napi_set_named_property(env, prop, "packageName", packageName);
|
||||
if (packageName == nullptr) {
|
||||
napi_set_named_property(env, prop, "name", packageName);
|
||||
}
|
||||
napi_set_named_property(env, prop, "name", packageName);
|
||||
|
||||
napi_value methodId = nullptr;
|
||||
napi_create_string_utf8(env, property.id.c_str(), NAPI_AUTO_LENGTH, &methodId);
|
||||
napi_set_named_property(env, prop, "methodId", methodId);
|
||||
if (methodId == nullptr) {
|
||||
napi_set_named_property(env, prop, "id", methodId);
|
||||
}
|
||||
napi_set_named_property(env, prop, "id", methodId);
|
||||
|
||||
return prop;
|
||||
}
|
||||
@ -216,16 +191,10 @@ napi_value JsInputMethod::SwitchInputMethod(napi_env env, napi_callback_info inf
|
||||
{
|
||||
auto ctxt = std::make_shared<SwitchInputMethodContext>();
|
||||
auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
|
||||
if (argc < 1) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "should has 1 parameters!", TYPE_NONE);
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
PARAM_CHECK_RETURN(env, argc > 0, "should has 1 parameters!", TYPE_NONE, napi_invalid_arg);
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_typeof(env, argv[0], &valueType);
|
||||
if (valueType != napi_object) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, " target: ", TYPE_OBJECT);
|
||||
return napi_ok;
|
||||
}
|
||||
PARAM_CHECK_RETURN(env, valueType == napi_object, " target: ", TYPE_OBJECT, napi_invalid_arg);
|
||||
napi_status status = GetInputMethodProperty(env, argv[0], ctxt);
|
||||
return status;
|
||||
};
|
||||
@ -283,16 +252,10 @@ napi_value JsInputMethod::SwitchCurrentInputMethodSubtype(napi_env env, napi_cal
|
||||
{
|
||||
auto ctxt = std::make_shared<SwitchInputMethodContext>();
|
||||
auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
|
||||
if (argc < 1) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "should has one parameter.", TYPE_NONE);
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
PARAM_CHECK_RETURN(env, argc > 0, "should has one parameter. ", TYPE_NONE, napi_invalid_arg);
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_typeof(env, argv[0], &valueType);
|
||||
if (valueType != napi_object) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, " inputMethodSubtype: ", TYPE_OBJECT);
|
||||
return napi_object_expected;
|
||||
}
|
||||
PARAM_CHECK_RETURN(env, valueType == napi_object, "inputMethodSubtype: ", TYPE_OBJECT, napi_object_expected);
|
||||
napi_status status = GetInputMethodSubProperty(env, argv[0], ctxt);
|
||||
return status;
|
||||
};
|
||||
@ -326,21 +289,12 @@ napi_value JsInputMethod::SwitchCurrentInputMethodAndSubtype(napi_env env, napi_
|
||||
{
|
||||
auto ctxt = std::make_shared<SwitchInputMethodContext>();
|
||||
auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
|
||||
if (argc < 2) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, "should has two parameter.", TYPE_NONE);
|
||||
return napi_invalid_arg;
|
||||
}
|
||||
PARAM_CHECK_RETURN(env, argc > 1, "should has two parameter.", TYPE_NONE, napi_invalid_arg);
|
||||
napi_valuetype valueType = napi_undefined;
|
||||
napi_typeof(env, argv[0], &valueType);
|
||||
if (valueType != napi_object) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, " inputMethodProperty: ", TYPE_OBJECT);
|
||||
return napi_object_expected;
|
||||
}
|
||||
PARAM_CHECK_RETURN(env, valueType == napi_object, "inputMethodProperty: ", TYPE_OBJECT, napi_object_expected);
|
||||
napi_typeof(env, argv[1], &valueType);
|
||||
if (valueType != napi_object) {
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, " inputMethodSubtype: ", TYPE_OBJECT);
|
||||
return napi_object_expected;
|
||||
}
|
||||
PARAM_CHECK_RETURN(env, valueType == napi_object, "inputMethodSubtype: ", TYPE_OBJECT, napi_object_expected);
|
||||
napi_status status = GetInputMethodSubProperty(env, argv[1], ctxt);
|
||||
return status;
|
||||
};
|
||||
|
@ -58,11 +58,9 @@ public:
|
||||
static napi_value SwitchCurrentInputMethodAndSubtype(napi_env env, napi_callback_info info);
|
||||
static napi_value GetCurrentInputMethodSubtype(napi_env env, napi_callback_info info);
|
||||
static napi_value GetCurrentInputMethod(napi_env env, napi_callback_info info);
|
||||
static int32_t GetNumberProperty(napi_env env, napi_value obj);
|
||||
static napi_value GetJsInputMethodProperty(napi_env env, const Property &property);
|
||||
static napi_value GetJSInputMethodSubProperties(napi_env env, const std::vector<SubProperty> &subProperties);
|
||||
static napi_value GetJSInputMethodProperties(napi_env env, const std::vector<Property> &properties);
|
||||
static std::string GetStringProperty(napi_env env, napi_value obj);
|
||||
static napi_value GetJsInputMethodSubProperty(napi_env env, const SubProperty &subProperty);
|
||||
|
||||
private:
|
||||
|
@ -17,8 +17,11 @@
|
||||
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
constexpr int32_t STR_MAX_LENGTH = 4096;
|
||||
constexpr size_t STR_TAIL_LENGTH = 1;
|
||||
constexpr size_t ARGC_MAX = 6;
|
||||
const std::map<int32_t, int32_t> JsUtils::ERROR_CODE_MAP = {
|
||||
{ ErrorCode::ERROR_CONTROLLER_INVOKING_FAILED, EXCEPTION_CONTROLLER},
|
||||
{ ErrorCode::ERROR_CONTROLLER_INVOKING_FAILED, EXCEPTION_CONTROLLER },
|
||||
{ ErrorCode::ERROR_STATUS_PERMISSION_DENIED, EXCEPTION_PERMISSION },
|
||||
{ ErrorCode::ERROR_REMOTE_CLIENT_DIED, EXCEPTION_IMCLIENT },
|
||||
{ ErrorCode::ERROR_CLIENT_NOT_FOUND, EXCEPTION_IMCLIENT },
|
||||
@ -128,8 +131,8 @@ const std::string JsUtils::ToMessage(int32_t code)
|
||||
return "error is out of definition.";
|
||||
}
|
||||
|
||||
bool JsUtils::TraverseCallback(const std::vector<std::shared_ptr<JSCallbackObject>> &vecCopy, size_t paramNum,
|
||||
ArgsProvider argsProvider)
|
||||
bool JsUtils::TraverseCallback(
|
||||
const std::vector<std::shared_ptr<JSCallbackObject>> &vecCopy, size_t paramNum, ArgsProvider argsProvider)
|
||||
{
|
||||
bool isResult = false;
|
||||
bool isOnKeyEvent = false;
|
||||
@ -164,7 +167,7 @@ bool JsUtils::TraverseCallback(const std::vector<std::shared_ptr<JSCallbackObjec
|
||||
if (valueType != napi_boolean) {
|
||||
continue;
|
||||
}
|
||||
napi_get_value_bool(item->env_, result, &isResult);
|
||||
GetValue(item->env_, result, isResult);
|
||||
if (isResult) {
|
||||
isOnKeyEvent = true;
|
||||
}
|
||||
@ -173,5 +176,94 @@ bool JsUtils::TraverseCallback(const std::vector<std::shared_ptr<JSCallbackObjec
|
||||
}
|
||||
return isOnKeyEvent;
|
||||
}
|
||||
|
||||
bool JsUtils::Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId)
|
||||
{
|
||||
if (copy == nullptr) {
|
||||
return value == nullptr;
|
||||
}
|
||||
|
||||
if (threadId != std::this_thread::get_id()) {
|
||||
IMSA_HILOGD("napi_value can not be compared");
|
||||
return false;
|
||||
}
|
||||
|
||||
napi_value copyValue = nullptr;
|
||||
napi_get_reference_value(env, copy, ©Value);
|
||||
|
||||
bool isEquals = false;
|
||||
napi_strict_equals(env, value, copyValue, &isEquals);
|
||||
IMSA_HILOGD("value compare result: %{public}d", isEquals);
|
||||
return isEquals;
|
||||
}
|
||||
|
||||
void *JsUtils::GetNativeSelf(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = ARGC_MAX;
|
||||
void *native = nullptr;
|
||||
napi_value self = nullptr;
|
||||
napi_value argv[ARGC_MAX] = { nullptr };
|
||||
napi_status status = napi_invalid_arg;
|
||||
napi_get_cb_info(env, info, &argc, argv, &self, nullptr);
|
||||
NAPI_ASSERT(env, (self != nullptr && argc <= ARGC_MAX), "napi_get_cb_info failed!");
|
||||
|
||||
status = napi_unwrap(env, self, &native);
|
||||
NAPI_ASSERT(env, (status == napi_ok && native != nullptr), "napi_unwrap failed!");
|
||||
return native;
|
||||
}
|
||||
|
||||
napi_status JsUtils::GetValue(napi_env env, napi_value in, int32_t &out)
|
||||
{
|
||||
napi_valuetype type = napi_undefined;
|
||||
napi_status status = napi_typeof(env, in, &type);
|
||||
NAPI_ASSERT_BASE(env, (status == napi_ok) && (type == napi_number), "invalid type", status);
|
||||
return napi_get_value_int32(env, in, &out);
|
||||
}
|
||||
|
||||
/* napi_value <-> uint32_t */
|
||||
napi_status JsUtils::GetValue(napi_env env, napi_value in, uint32_t &out)
|
||||
{
|
||||
napi_valuetype type = napi_undefined;
|
||||
napi_status status = napi_typeof(env, in, &type);
|
||||
NAPI_ASSERT_BASE(env, (status == napi_ok) && (type == napi_number), "invalid type", status);
|
||||
return napi_get_value_uint32(env, in, &out);
|
||||
}
|
||||
|
||||
napi_status JsUtils::GetValue(napi_env env, napi_value in, bool &out)
|
||||
{
|
||||
napi_valuetype type = napi_undefined;
|
||||
napi_status status = napi_typeof(env, in, &type);
|
||||
NAPI_ASSERT_BASE(env, (status == napi_ok) && (type == napi_boolean), "invalid type", status);
|
||||
return napi_get_value_bool(env, in, &out);
|
||||
}
|
||||
|
||||
/* napi_value <-> std::string */
|
||||
napi_status JsUtils::GetValue(napi_env env, napi_value in, std::string &out)
|
||||
{
|
||||
IMSA_HILOGD("JsUtils get string value in.");
|
||||
napi_valuetype type = napi_undefined;
|
||||
napi_status status = napi_typeof(env, in, &type);
|
||||
NAPI_ASSERT_BASE(env, (status == napi_ok) && (type == napi_string), "invalid type", status);
|
||||
|
||||
size_t maxLen = STR_MAX_LENGTH;
|
||||
status = napi_get_value_string_utf8(env, in, NULL, 0, &maxLen);
|
||||
if (maxLen <= 0) {
|
||||
return status;
|
||||
}
|
||||
IMSA_HILOGD("napi_value -> std::string get length %{public}d", maxLen);
|
||||
char *buf = new (std::nothrow) char[maxLen + STR_TAIL_LENGTH];
|
||||
if (buf != nullptr) {
|
||||
size_t len = 0;
|
||||
status = napi_get_value_string_utf8(env, in, buf, maxLen + STR_TAIL_LENGTH, &len);
|
||||
if (status == napi_ok) {
|
||||
buf[len] = 0;
|
||||
out = std::string(buf);
|
||||
}
|
||||
delete[] buf;
|
||||
} else {
|
||||
status = napi_generic_failure;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
} // namespace MiscServices
|
||||
} // namespace OHOS
|
@ -24,7 +24,9 @@
|
||||
#include "napi/native_node_api.h"
|
||||
#include "string_ex.h"
|
||||
#include "js_callback_object.h"
|
||||
#include "ability.h"
|
||||
|
||||
using Ability = OHOS::AppExecFwk::Ability;
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
enum IMFErrorCode : int32_t {
|
||||
@ -55,6 +57,24 @@ enum TypeCode : int32_t {
|
||||
TYPE_BIGINT,
|
||||
};
|
||||
|
||||
/* check condition, return and logging if condition not true. */
|
||||
#define PARAM_CHECK_RETURN(env, condition, message, typeCode, retVal) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
JsUtils::ThrowException(env, IMFErrorCode::EXCEPTION_PARAMCHECK, message, typeCode); \
|
||||
return retVal; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* check condition, return and logging. */
|
||||
#define CHECK_RETURN_VOID(condition, message) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
IMSA_HILOGE("test (" #condition ") failed: " message); \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
class JsUtils {
|
||||
public:
|
||||
using ArgsProvider = std::function<bool(napi_value args[], uint8_t argc, std::shared_ptr<JSCallbackObject>)>;
|
||||
@ -64,8 +84,16 @@ public:
|
||||
static napi_value ToError(napi_env env, int32_t code);
|
||||
|
||||
static bool TraverseCallback(const std::vector<std::shared_ptr<JSCallbackObject>> &vecCopy, size_t paramNum,
|
||||
ArgsProvider argsProvider);
|
||||
ArgsProvider argsProvider);
|
||||
|
||||
static bool Equals(napi_env env, napi_value value, napi_ref copy, std::thread::id threadId);
|
||||
|
||||
static void *GetNativeSelf(napi_env env, napi_callback_info info);
|
||||
|
||||
static napi_status GetValue(napi_env env, napi_value in, int32_t &out);
|
||||
static napi_status GetValue(napi_env env, napi_value in, uint32_t &out);
|
||||
static napi_status GetValue(napi_env env, napi_value in, bool &out);
|
||||
static napi_status GetValue(napi_env env, napi_value in, std::string &out);
|
||||
private:
|
||||
static int32_t Convert(int32_t code);
|
||||
|
||||
|
@ -19,14 +19,20 @@ config("inputmethod_ability_native_config") {
|
||||
include_dirs = [
|
||||
"include",
|
||||
"${inputmethod_path}/frameworks/native/inputmethod_controller/include",
|
||||
"${inputmethod_path}/frameworks/common",
|
||||
"${inputmethod_path}/services/include",
|
||||
"${windowmanager_path}/interfaces/innerkits/dm",
|
||||
"${windowmanager_path}/interfaces/innerkits/wm",
|
||||
]
|
||||
}
|
||||
config("inputmethod_ability_native_public_config") {
|
||||
visibility = []
|
||||
include_dirs = [
|
||||
"include",
|
||||
"${inputmethod_path}/frameworks/common",
|
||||
"${inputmethod_path}/services/include",
|
||||
"${windowmanager_path}/interfaces/innerkits/dm",
|
||||
"${windowmanager_path}/interfaces/innerkits/wm",
|
||||
]
|
||||
}
|
||||
|
||||
@ -45,17 +51,23 @@ ohos_shared_library("inputmethod_ability") {
|
||||
"src/input_method_agent_stub.cpp",
|
||||
"src/input_method_core_proxy.cpp",
|
||||
"src/input_method_core_stub.cpp",
|
||||
"src/input_method_panel.cpp",
|
||||
]
|
||||
|
||||
configs = [ ":inputmethod_ability_native_config" ]
|
||||
|
||||
external_deps = [
|
||||
"ability_runtime:ability_context_native",
|
||||
"c_utils:utils",
|
||||
"hiviewdfx_hilog_native:libhilog",
|
||||
"ipc:ipc_single",
|
||||
"samgr:samgr_proxy",
|
||||
"window_manager:libdm",
|
||||
"window_manager:libwm",
|
||||
]
|
||||
|
||||
deps = [ "${graphic_path}/render_service_client:librender_service_client" ]
|
||||
|
||||
public_configs = [ ":inputmethod_ability_native_public_config" ]
|
||||
|
||||
subsystem_name = "inputmethod"
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include <thread>
|
||||
|
||||
#include "concurrent_map.h"
|
||||
#include "i_input_control_channel.h"
|
||||
#include "i_input_data_channel.h"
|
||||
#include "i_input_method_agent.h"
|
||||
@ -28,6 +29,7 @@
|
||||
#include "input_data_channel_proxy.h"
|
||||
#include "input_method_core_stub.h"
|
||||
#include "input_method_engine_listener.h"
|
||||
#include "input_method_panel.h"
|
||||
#include "input_method_system_ability_proxy.h"
|
||||
#include "iremote_object.h"
|
||||
#include "keyboard_listener.h"
|
||||
@ -35,6 +37,10 @@
|
||||
#include "message_handler.h"
|
||||
#include "utils.h"
|
||||
|
||||
namespace OHOS::AbilityRuntime {
|
||||
class Context;
|
||||
}
|
||||
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
struct InputStartNotifier {
|
||||
@ -66,6 +72,9 @@ public:
|
||||
int32_t GetInputPattern(int32_t &inputPattern);
|
||||
int32_t GetTextIndexAtCursor(int32_t &index);
|
||||
void OnImeReady();
|
||||
int32_t CreatePanel(const std::shared_ptr<AbilityRuntime::Context> &context, const PanelInfo &panelInfo,
|
||||
std::shared_ptr<InputMethodPanel> &inputMethodPanel);
|
||||
int32_t DestroyPanel(const std::shared_ptr<InputMethodPanel> &inputMethodPanel);
|
||||
|
||||
private:
|
||||
std::thread workThreadHandler;
|
||||
@ -117,6 +126,7 @@ private:
|
||||
void DismissInputWindow();
|
||||
bool isImeReady_{ false };
|
||||
InputStartNotifier notifier_;
|
||||
ConcurrentMap<PanelType, std::shared_ptr<InputMethodPanel>> panels_{};
|
||||
};
|
||||
} // namespace MiscServices
|
||||
} // namespace OHOS
|
||||
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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 INPUT_METHOD_PANEL_H
|
||||
#define INPUT_METHOD_PANEL_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "panel_status_listener.h"
|
||||
#include "window.h"
|
||||
#include "window_option.h"
|
||||
#include "wm_common.h"
|
||||
|
||||
class NativeValue;
|
||||
class NativeEngine;
|
||||
namespace OHOS {
|
||||
using namespace OHOS::Rosen;
|
||||
namespace MiscServices {
|
||||
enum PanelType {
|
||||
SOFT_KEYBOARD = 0,
|
||||
STATUS_BAR,
|
||||
};
|
||||
|
||||
enum PanelFlag {
|
||||
FLG_FIXED = 0,
|
||||
FLG_FLOATING,
|
||||
};
|
||||
|
||||
struct PanelInfo {
|
||||
PanelType panelType = SOFT_KEYBOARD;
|
||||
PanelFlag panelFlag = FLG_FIXED;
|
||||
};
|
||||
|
||||
class InputMethodPanel {
|
||||
public:
|
||||
InputMethodPanel() = default;
|
||||
~InputMethodPanel();
|
||||
int32_t SetUiContent(const std::string& contentInfo, NativeEngine* engine, NativeValue* storage);
|
||||
int32_t CreatePanel(const std::shared_ptr<AbilityRuntime::Context> &context, const PanelInfo &panelInfo);
|
||||
int32_t DestroyPanel();
|
||||
|
||||
int32_t Resize(uint32_t width, uint32_t height);
|
||||
int32_t MoveTo(int32_t x, int32_t y);
|
||||
int32_t ChangePanelFlag(PanelFlag panelFlag);
|
||||
PanelType GetPanelType();
|
||||
int32_t ShowPanel();
|
||||
int32_t HidePanel();
|
||||
void SetPanelStatusListener(std::shared_ptr<PanelStatusListener> statusListener);
|
||||
void RemovePanelListener(const std::string &type);
|
||||
uint32_t windowId_ = 0;
|
||||
|
||||
private:
|
||||
bool IsShowing();
|
||||
bool IsHidden();
|
||||
static uint32_t GenerateSequenceId();
|
||||
|
||||
sptr<Window> window_ = nullptr;
|
||||
sptr<WindowOption> winOption_ = nullptr;
|
||||
PanelType panelType_ = PanelType::SOFT_KEYBOARD;
|
||||
PanelFlag panelFlag_ = PanelFlag::FLG_FIXED;
|
||||
bool showRegistered_ = true;
|
||||
bool hideRegistered_ = true;
|
||||
uint32_t invalidGravityPercent = 0;
|
||||
std::shared_ptr<PanelStatusListener> panelStatusListener_ = nullptr;
|
||||
|
||||
static std::atomic<uint32_t> sequenceId_;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif //INPUT_METHOD_PANEL_H
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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_PANEL_STATUS_LISTENER_H
|
||||
#define INPUTMETHOD_IMF_PANEL_STATUS_LISTENER_H
|
||||
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
class PanelStatusListener {
|
||||
public:
|
||||
virtual ~PanelStatusListener(){};
|
||||
virtual void OnPanelStatus(uint32_t windowId, bool isShow) = 0;
|
||||
};
|
||||
} // namespace MiscServices
|
||||
} // namespace OHOS
|
||||
|
||||
#endif //INPUTMETHOD_IMF_PANEL_STATUS_LISTENER_H
|
@ -27,8 +27,8 @@
|
||||
#include "itypes_util.h"
|
||||
#include "message_parcel.h"
|
||||
#include "string_ex.h"
|
||||
#include "system_ability_definition.h"
|
||||
#include "sys/prctl.h"
|
||||
#include "system_ability_definition.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
@ -359,6 +359,16 @@ void InputMethodAbility::ShowInputWindow(bool isShowKeyboard, const SubProperty
|
||||
return;
|
||||
}
|
||||
channel->SendKeyboardStatus(KEYBOARD_SHOW);
|
||||
auto result = panels_.Find(SOFT_KEYBOARD);
|
||||
if (!result.first) {
|
||||
IMSA_HILOGE("Not find SOFT_KEYBOARD panel.");
|
||||
return;
|
||||
}
|
||||
auto ret = result.second->ShowPanel();
|
||||
if (ret != NO_ERROR) {
|
||||
IMSA_HILOGE("Show panel failed, ret = %{public}d.", ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void InputMethodAbility::DismissInputWindow()
|
||||
@ -375,6 +385,16 @@ void InputMethodAbility::DismissInputWindow()
|
||||
return;
|
||||
}
|
||||
channel->SendKeyboardStatus(KEYBOARD_HIDE);
|
||||
auto result = panels_.Find(SOFT_KEYBOARD);
|
||||
if (!result.first) {
|
||||
IMSA_HILOGE("Not find SOFT_KEYBOARD panel.");
|
||||
return;
|
||||
}
|
||||
auto ret = result.second->HidePanel();
|
||||
if (ret != NO_ERROR) {
|
||||
IMSA_HILOGE("Show panel failed, ret = %{public}d.", ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t InputMethodAbility::InsertText(const std::string text)
|
||||
@ -566,5 +586,44 @@ void InputMethodAbility::QuitWorkThread()
|
||||
workThreadHandler.join();
|
||||
}
|
||||
}
|
||||
|
||||
int32_t InputMethodAbility::CreatePanel(const std::shared_ptr<AbilityRuntime::Context> &context,
|
||||
const PanelInfo &panelInfo, std::shared_ptr<InputMethodPanel> &inputMethodPanel)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodAbility::CreatePanel start.");
|
||||
auto result = panels_.Find(panelInfo.panelType);
|
||||
if (result.first) {
|
||||
IMSA_HILOGE(" type of %{public}d panel already created, can not create another", panelInfo.panelType);
|
||||
return ErrorCode::ERROR_OPERATE_PANEL;
|
||||
}
|
||||
inputMethodPanel = std::make_shared<InputMethodPanel>();
|
||||
if (inputMethodPanel == nullptr) {
|
||||
return ErrorCode::ERROR_BAD_PARAMETERS;
|
||||
}
|
||||
auto ret = inputMethodPanel->CreatePanel(context, panelInfo);
|
||||
if (ret != ErrorCode::NO_ERROR) {
|
||||
IMSA_HILOGE("CreatePanel failed, ret = %{public}d", ret);
|
||||
return ret;
|
||||
}
|
||||
IMSA_HILOGI("InputMethodAbility::CreatePanel ret = 0, success.");
|
||||
if (!panels_.Insert(panelInfo.panelType, inputMethodPanel)) {
|
||||
IMSA_HILOGE("insert inputMethodPanel fail.");
|
||||
return ErrorCode::ERROR_OPERATE_PANEL;
|
||||
}
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
|
||||
int32_t InputMethodAbility::DestroyPanel(const std::shared_ptr<InputMethodPanel> &inputMethodPanel)
|
||||
{
|
||||
if (inputMethodPanel == nullptr) {
|
||||
return ErrorCode::ERROR_BAD_PARAMETERS;
|
||||
}
|
||||
PanelType panelType = inputMethodPanel->GetPanelType();
|
||||
auto ret = inputMethodPanel->DestroyPanel();
|
||||
if (ret == ErrorCode::NO_ERROR) {
|
||||
panels_.Erase(panelType);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
} // namespace MiscServices
|
||||
} // namespace OHOS
|
||||
|
263
frameworks/native/inputmethod_ability/src/input_method_panel.cpp
Normal file
263
frameworks/native/inputmethod_ability/src/input_method_panel.cpp
Normal file
@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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 "input_method_panel.h"
|
||||
|
||||
#include "display_manager.h"
|
||||
#include "global.h"
|
||||
#include "window.h"
|
||||
#include "wm_common.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
using WMError = OHOS::Rosen::WMError;
|
||||
using WindowGravity = OHOS::Rosen::WindowGravity;
|
||||
using WindowState = OHOS::Rosen::WindowState;
|
||||
std::atomic<uint32_t> InputMethodPanel::sequenceId_{ 0 };
|
||||
InputMethodPanel::~InputMethodPanel() = default;
|
||||
|
||||
int32_t InputMethodPanel::CreatePanel(
|
||||
const std::shared_ptr<AbilityRuntime::Context> &context, const PanelInfo &panelInfo)
|
||||
{
|
||||
IMSA_HILOGD("InputMethodPanel start to create panel.");
|
||||
panelType_ = panelInfo.panelType;
|
||||
panelFlag_ = panelInfo.panelFlag;
|
||||
winOption_ = new (std::nothrow) OHOS::Rosen::WindowOption();
|
||||
if (winOption_ == nullptr) {
|
||||
return ErrorCode::ERROR_NULL_POINTER;
|
||||
}
|
||||
winOption_->SetWindowType(OHOS::Rosen::WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
|
||||
WMError wmError = WMError::WM_OK;
|
||||
WindowGravity gravity = WindowGravity::WINDOW_GRAVITY_FLOAT;
|
||||
if (panelType_ == SOFT_KEYBOARD && panelFlag_ == FLG_FIXED) {
|
||||
gravity = WindowGravity::WINDOW_GRAVITY_BOTTOM;
|
||||
}
|
||||
uint32_t sequenceId = GenerateSequenceId();
|
||||
std::string windowName = panelType_ == SOFT_KEYBOARD ? "softKeyboard" + std::to_string(sequenceId)
|
||||
: "statusBar" + std::to_string(sequenceId);
|
||||
IMSA_HILOGD("InputMethodPanel, windowName = %{public}s", windowName.c_str());
|
||||
window_ = OHOS::Rosen::Window::Create(windowName, winOption_, context, wmError);
|
||||
if (wmError == WMError::WM_ERROR_INVALID_PERMISSION) {
|
||||
return ErrorCode::ERROR_STATUS_PERMISSION_DENIED;
|
||||
}
|
||||
if (window_ == nullptr || wmError != WMError::WM_OK) {
|
||||
return ErrorCode::ERROR_OPERATE_PANEL;
|
||||
}
|
||||
windowId_ = window_->GetWindowId();
|
||||
IMSA_HILOGD("GetWindowId, windowId = %{public}u", windowId_);
|
||||
wmError = window_->SetWindowGravity(gravity, invalidGravityPercent);
|
||||
if (wmError == WMError::WM_OK) {
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
wmError = window_->Destroy();
|
||||
return wmError == WMError::WM_OK ? ErrorCode::NO_ERROR : ErrorCode::ERROR_OPERATE_PANEL;
|
||||
}
|
||||
|
||||
int32_t InputMethodPanel::DestroyPanel()
|
||||
{
|
||||
auto ret = HidePanel();
|
||||
if (ret != ErrorCode::NO_ERROR) {
|
||||
IMSA_HILOGI("InputMethodPanel, hide panel failed, ret = %{public}d.", ret);
|
||||
return ret;
|
||||
}
|
||||
auto result = window_->Destroy();
|
||||
if (result != WMError::WM_OK) {
|
||||
IMSA_HILOGE("InputMethodPanel, destroy panel error, ret = %{public}d", result);
|
||||
return ErrorCode::ERROR_OPERATE_PANEL;
|
||||
}
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
|
||||
int32_t InputMethodPanel::Resize(uint32_t width, uint32_t height)
|
||||
{
|
||||
if (window_ == nullptr) {
|
||||
return ErrorCode::ERROR_NULL_POINTER;
|
||||
}
|
||||
auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
|
||||
if (defaultDisplay == nullptr) {
|
||||
IMSA_HILOGE("GetDefaultDisplay failed.");
|
||||
return ErrorCode::ERROR_NULL_POINTER;
|
||||
}
|
||||
if (width > defaultDisplay->GetWidth() || height > (defaultDisplay->GetHeight()) / 2) {
|
||||
IMSA_HILOGD("GetDefaultDisplay, defaultDisplay->width = %{public}d, defaultDisplay->height = %{public}d, "
|
||||
"width = %{public}u, height = %{public}u",
|
||||
defaultDisplay->GetWidth(), defaultDisplay->GetHeight(), width, height);
|
||||
return ErrorCode::ERROR_BAD_PARAMETERS;
|
||||
}
|
||||
auto ret = window_->Resize(width, height);
|
||||
return ret == WMError::WM_OK ? ErrorCode::NO_ERROR : ErrorCode::ERROR_OPERATE_PANEL;
|
||||
}
|
||||
|
||||
int32_t InputMethodPanel::MoveTo(int32_t x, int32_t y)
|
||||
{
|
||||
if (panelType_ == SOFT_KEYBOARD && panelFlag_ == FLG_FIXED) {
|
||||
IMSA_HILOGE("FLG_FIXED panel can not moveTo.");
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
if (window_ == nullptr) {
|
||||
IMSA_HILOGE("window_ is nullptr.");
|
||||
return ErrorCode::ERROR_NULL_POINTER;
|
||||
}
|
||||
auto ret = window_->MoveTo(x, y);
|
||||
if (ret != WMError::WM_OK) {
|
||||
return ErrorCode::ERROR_OPERATE_PANEL;
|
||||
}
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
|
||||
int32_t InputMethodPanel::ChangePanelFlag(PanelFlag panelFlag)
|
||||
{
|
||||
if (window_ == nullptr) {
|
||||
IMSA_HILOGE("window_ is nullptr.");
|
||||
return ErrorCode::ERROR_NULL_POINTER;
|
||||
}
|
||||
if (panelFlag_ == panelFlag) {
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
if (panelType_ == STATUS_BAR) {
|
||||
IMSA_HILOGE("STATUS_BAR cannot ChangePanelFlag.");
|
||||
return ErrorCode::ERROR_BAD_PARAMETERS;
|
||||
}
|
||||
panelFlag_ = panelFlag;
|
||||
WindowGravity gravity = WindowGravity::WINDOW_GRAVITY_FLOAT;
|
||||
if (panelFlag == FLG_FIXED) {
|
||||
gravity = WindowGravity::WINDOW_GRAVITY_BOTTOM;
|
||||
}
|
||||
auto ret = window_->SetWindowGravity(gravity, invalidGravityPercent);
|
||||
return ret == WMError::WM_OK ? ErrorCode::NO_ERROR : ErrorCode::ERROR_OPERATE_PANEL;
|
||||
}
|
||||
|
||||
PanelType InputMethodPanel::GetPanelType()
|
||||
{
|
||||
return panelType_;
|
||||
}
|
||||
|
||||
int32_t InputMethodPanel::ShowPanel()
|
||||
{
|
||||
if (window_ == nullptr) {
|
||||
IMSA_HILOGE("window_ is nullptr.");
|
||||
return ErrorCode::ERROR_NULL_POINTER;
|
||||
}
|
||||
if (IsShowing()) {
|
||||
IMSA_HILOGE("Panel already shown.");
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
auto ret = window_->Show();
|
||||
if (ret != WMError::WM_OK) {
|
||||
IMSA_HILOGE("ShowPanel error, err = %{public}d, ERROR_SHOW_PANEL", ret);
|
||||
return ErrorCode::ERROR_OPERATE_PANEL;
|
||||
}
|
||||
if (showRegistered_ && panelStatusListener_ != nullptr) {
|
||||
IMSA_HILOGE("InputMethodPanel::ShowPanel panelStatusListener_ is not nullptr");
|
||||
panelStatusListener_->OnPanelStatus(windowId_, true);
|
||||
}
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
|
||||
int32_t InputMethodPanel::HidePanel()
|
||||
{
|
||||
if (window_ == nullptr) {
|
||||
IMSA_HILOGE("window_ is nullptr.");
|
||||
return ErrorCode::ERROR_NULL_POINTER;
|
||||
}
|
||||
if (IsHidden()) {
|
||||
IMSA_HILOGE("Panel already hidden.");
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
auto ret = window_->Hide();
|
||||
if (ret != WMError::WM_OK) {
|
||||
IMSA_HILOGE("HidePanel error, err = %{public}d, ERROR_HIDE_PANEL", ret);
|
||||
return ErrorCode::ERROR_OPERATE_PANEL;
|
||||
}
|
||||
if (hideRegistered_ && panelStatusListener_ != nullptr) {
|
||||
IMSA_HILOGE("InputMethodPanel::HidePanel panelStatusListener_ is not nullptr");
|
||||
panelStatusListener_->OnPanelStatus(windowId_, false);
|
||||
}
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
|
||||
bool InputMethodPanel::IsShowing()
|
||||
{
|
||||
WindowState windowState = window_->GetWindowState();
|
||||
if (windowState == WindowState::STATE_SHOWN) {
|
||||
return true;
|
||||
}
|
||||
IMSA_HILOGD("InputMethodPanel windowState = %{public}d", static_cast<int>(windowState));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InputMethodPanel::IsHidden()
|
||||
{
|
||||
WindowState windowState = window_->GetWindowState();
|
||||
if (windowState == WindowState::STATE_HIDDEN) {
|
||||
return true;
|
||||
}
|
||||
IMSA_HILOGD("InputMethodPanel windowState = %{public}d", static_cast<int>(windowState));
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t InputMethodPanel::SetUiContent(const std::string &contentInfo, NativeEngine *engine, NativeValue *storage)
|
||||
{
|
||||
if (window_ == nullptr) {
|
||||
IMSA_HILOGE("window_ is nullptr, can not SetUiContent.");
|
||||
return ErrorCode::ERROR_NULL_POINTER;
|
||||
}
|
||||
auto ret = window_->SetUIContent(contentInfo, engine, storage);
|
||||
if (ret != WMError::WM_OK) {
|
||||
return ErrorCode::ERROR_OPERATE_PANEL;
|
||||
}
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
|
||||
void InputMethodPanel::SetPanelStatusListener(std::shared_ptr<PanelStatusListener> statusListener)
|
||||
{
|
||||
IMSA_HILOGD("SetPanelStatusListener start.");
|
||||
if (panelStatusListener_ != nullptr) {
|
||||
IMSA_HILOGE("PanelStatusListener already set.");
|
||||
return;
|
||||
}
|
||||
panelStatusListener_ = std::move(statusListener);
|
||||
}
|
||||
|
||||
void InputMethodPanel::RemovePanelListener(const std::string &type)
|
||||
{
|
||||
if (type == "show") {
|
||||
showRegistered_ = false;
|
||||
} else if (type == "hide") {
|
||||
hideRegistered_ = false;
|
||||
} else {
|
||||
IMSA_HILOGE("type error.");
|
||||
return;
|
||||
}
|
||||
if (panelStatusListener_ == nullptr) {
|
||||
IMSA_HILOGE("PanelStatusListener not set, don't need to remove.");
|
||||
return;
|
||||
}
|
||||
if (showRegistered_ || hideRegistered_) {
|
||||
return;
|
||||
}
|
||||
panelStatusListener_ = nullptr;
|
||||
}
|
||||
|
||||
uint32_t InputMethodPanel::GenerateSequenceId()
|
||||
{
|
||||
uint32_t seqId = ++sequenceId_;
|
||||
if (seqId == std::numeric_limits<uint32_t>::max()) {
|
||||
return ++sequenceId_;
|
||||
}
|
||||
return seqId;
|
||||
}
|
||||
} // namespace MiscServices
|
||||
} // namespace OHOS
|
@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
# Copyright (C) 2021-2023 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
|
||||
@ -28,3 +28,7 @@ kits_path = "${inputmethod_path}/interfaces/kits"
|
||||
innerkits_path = "${inputmethod_path}/interfaces/innerkits"
|
||||
|
||||
adapter_path = "${inputmethod_path}/adapter"
|
||||
|
||||
graphic_path = "//foundation/graphic/graphic_2d/rosen/modules"
|
||||
|
||||
windowmanager_path = "//foundation/window/window_manager"
|
||||
|
@ -91,6 +91,7 @@ enum {
|
||||
ERROR_CLIENT_NOT_EDITABLE = 17,
|
||||
ERROR_CLIENT_NOT_FOCUSED = 18,
|
||||
ERROR_CLIENT_ADD_FAILED = 19,
|
||||
ERROR_OPERATE_PANEL = 20,
|
||||
};
|
||||
}; // namespace ErrorCode
|
||||
|
||||
|
@ -22,6 +22,7 @@ group("unittest") {
|
||||
"cpp_test:InputMethodAbilityTest",
|
||||
"cpp_test:InputMethodControllerTest",
|
||||
"cpp_test:InputMethodDfxTest",
|
||||
"cpp_test:InputMethodPanelTest",
|
||||
"cpp_test:InputMethodPrivateMemberTest",
|
||||
"cpp_test:InputMethodServiceTest",
|
||||
"cpp_test:InputMethodSwitchTest",
|
||||
|
@ -38,6 +38,7 @@ ohos_unittest("InputMethodControllerTest") {
|
||||
|
||||
external_deps = [
|
||||
"ability_base:want",
|
||||
"ability_runtime:ability_context_native",
|
||||
"ability_runtime:ability_manager",
|
||||
"access_token:libaccesstoken_sdk",
|
||||
"access_token:libnativetoken",
|
||||
@ -63,7 +64,13 @@ ohos_unittest("InputMethodAbilityTest") {
|
||||
|
||||
configs = [ ":module_private_config" ]
|
||||
|
||||
include_dirs = [
|
||||
"${windowmanager_path}/interfaces/innerkits/dm",
|
||||
"${windowmanager_path}/interfaces/innerkits/wm",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"${graphic_path}/render_service_client:librender_service_client",
|
||||
"${inputmethod_path}/frameworks/native/inputmethod_ability:inputmethod_ability",
|
||||
"${inputmethod_path}/interfaces/inner_api/inputmethod_controller:inputmethod_client_static",
|
||||
"${inputmethod_path}/services:inputmethod_service",
|
||||
@ -72,6 +79,7 @@ ohos_unittest("InputMethodAbilityTest") {
|
||||
|
||||
external_deps = [
|
||||
"ability_base:want",
|
||||
"ability_runtime:ability_context_native",
|
||||
"access_token:libaccesstoken_sdk",
|
||||
"access_token:libnativetoken",
|
||||
"access_token:libtoken_setproc",
|
||||
@ -82,6 +90,8 @@ ohos_unittest("InputMethodAbilityTest") {
|
||||
"napi:ace_napi",
|
||||
"safwk:system_ability_fwk",
|
||||
"samgr:samgr_proxy",
|
||||
"window_manager:libdm",
|
||||
"window_manager:libwm",
|
||||
]
|
||||
}
|
||||
|
||||
@ -95,6 +105,11 @@ ohos_unittest("InputMethodServiceTest") {
|
||||
|
||||
configs = [ ":module_private_config" ]
|
||||
|
||||
include_dirs = [
|
||||
"${windowmanager_path}/interfaces/innerkits/dm",
|
||||
"${windowmanager_path}/interfaces/innerkits/wm",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"${inputmethod_path}/frameworks/native/inputmethod_ability:inputmethod_ability",
|
||||
"${inputmethod_path}/interfaces/inner_api/inputmethod_controller:inputmethod_client_static",
|
||||
@ -104,6 +119,7 @@ ohos_unittest("InputMethodServiceTest") {
|
||||
|
||||
external_deps = [
|
||||
"ability_base:want",
|
||||
"ability_runtime:ability_context_native",
|
||||
"access_token:libaccesstoken_sdk",
|
||||
"access_token:libnativetoken",
|
||||
"c_utils:utils",
|
||||
@ -113,6 +129,8 @@ ohos_unittest("InputMethodServiceTest") {
|
||||
"napi:ace_napi",
|
||||
"safwk:system_ability_fwk",
|
||||
"samgr:samgr_proxy",
|
||||
"window_manager:libdm",
|
||||
"window_manager:libwm",
|
||||
]
|
||||
}
|
||||
|
||||
@ -132,6 +150,35 @@ ohos_unittest("InputMethodDfxTest") {
|
||||
]
|
||||
}
|
||||
|
||||
ohos_unittest("InputMethodPanelTest") {
|
||||
module_out_path = module_output_path
|
||||
|
||||
sources = [ "src/input_method_panel_test.cpp" ]
|
||||
|
||||
configs = [ ":module_private_config" ]
|
||||
|
||||
include_dirs = [
|
||||
"${windowmanager_path}/interfaces/innerkits/dm",
|
||||
"${windowmanager_path}/interfaces/innerkits/wm",
|
||||
]
|
||||
|
||||
deps = [
|
||||
"${graphic_path}/render_service_client:librender_service_client",
|
||||
"${inputmethod_path}/frameworks/native/inputmethod_ability:inputmethod_ability",
|
||||
"${inputmethod_path}/interfaces/inner_api/inputmethod_controller:inputmethod_client_static",
|
||||
"${inputmethod_path}/services:inputmethod_service",
|
||||
"//third_party/googletest:gtest_main",
|
||||
]
|
||||
|
||||
external_deps = [
|
||||
"ability_runtime:ability_context_native",
|
||||
"c_utils:utils",
|
||||
"hiviewdfx_hilog_native:libhilog",
|
||||
"window_manager:libdm",
|
||||
"window_manager:libwm",
|
||||
]
|
||||
}
|
||||
|
||||
ohos_unittest("InputMethodUtilsTest") {
|
||||
module_out_path = module_output_path
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "input_method_controller.h"
|
||||
#include "input_method_core_proxy.h"
|
||||
#include "input_method_core_stub.h"
|
||||
#include "input_method_panel.h"
|
||||
#include "message_handler.h"
|
||||
#include "nativetoken_kit.h"
|
||||
#include "token_setproc.h"
|
||||
@ -718,5 +719,124 @@ HWTEST_F(InputMethodAbilityTest, testGetTextIndexAtCursor_002, TestSize.Level0)
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
EXPECT_EQ(index, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: testCreatePanel001
|
||||
* @tc.desc: It's allowed to create one SOFT_KEYBOARD panel, but two is denied.
|
||||
* @tc.type: FUNC
|
||||
* @tc.require:
|
||||
*/
|
||||
HWTEST_F(InputMethodAbilityTest, testCreatePanel001, TestSize.Level0)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodAbilityTest testCreatePanel001 START. You can not create two SOFT_KEYBOARD panel.");
|
||||
std::shared_ptr<InputMethodPanel> softKeyboardPanel1 = nullptr;
|
||||
PanelInfo panelInfo = { .panelType = SOFT_KEYBOARD, .panelFlag = FLG_FIXED };
|
||||
auto ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo, softKeyboardPanel1);
|
||||
EXPECT_TRUE(softKeyboardPanel1 != nullptr);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
std::shared_ptr<InputMethodPanel> softKeyboardPanel2 = nullptr;
|
||||
ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo, softKeyboardPanel2);
|
||||
EXPECT_TRUE(softKeyboardPanel2 == nullptr);
|
||||
EXPECT_EQ(ret, ErrorCode::ERROR_OPERATE_PANEL);
|
||||
|
||||
ret = inputMethodAbility_->DestroyPanel(softKeyboardPanel1);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
ret = inputMethodAbility_->DestroyPanel(softKeyboardPanel2);
|
||||
EXPECT_EQ(ret, ErrorCode::ERROR_BAD_PARAMETERS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: testCreatePanel002
|
||||
* @tc.desc: It's allowed to create one STATUS_BAR panel, but two is denied.
|
||||
* @tc.type: FUNC
|
||||
* @tc.require:
|
||||
*/
|
||||
HWTEST_F(InputMethodAbilityTest, testCreatePanel002, TestSize.Level0)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodAbilityTest testCreatePanel002 START. You can not create two STATUS_BAR panel.");
|
||||
std::shared_ptr<InputMethodPanel> statusBar1 = nullptr;
|
||||
PanelInfo panelInfo = { .panelType = STATUS_BAR };
|
||||
auto ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo, statusBar1);
|
||||
EXPECT_TRUE(statusBar1 != nullptr);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
std::shared_ptr<InputMethodPanel> statusBar2 = nullptr;
|
||||
ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo, statusBar2);
|
||||
EXPECT_TRUE(statusBar2 == nullptr);
|
||||
EXPECT_EQ(ret, ErrorCode::ERROR_OPERATE_PANEL);
|
||||
|
||||
ret = inputMethodAbility_->DestroyPanel(statusBar1);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
ret = inputMethodAbility_->DestroyPanel(statusBar2);
|
||||
EXPECT_EQ(ret, ErrorCode::ERROR_BAD_PARAMETERS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: testCreatePanel003
|
||||
* @tc.desc: It's allowed to create one STATUS_BAR panel and one SOFT_KEYBOARD panel.
|
||||
* @tc.type: FUNC
|
||||
* @tc.require:
|
||||
*/
|
||||
HWTEST_F(InputMethodAbilityTest, testCreatePanel003, TestSize.Level0)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodAbilityTest testCreatePanel006 START. Allowed to create one SOFT_KEYBOARD panel and "
|
||||
"one STATUS_BAR panel.");
|
||||
std::shared_ptr<InputMethodPanel> softKeyboardPanel = nullptr;
|
||||
PanelInfo panelInfo1 = { .panelType = SOFT_KEYBOARD, .panelFlag = FLG_FIXED };
|
||||
auto ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo1, softKeyboardPanel);
|
||||
EXPECT_TRUE(softKeyboardPanel != nullptr);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
PanelInfo panelInfo2 = { .panelType = STATUS_BAR };
|
||||
std::shared_ptr<InputMethodPanel> statusBar = nullptr;
|
||||
ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo2, statusBar);
|
||||
EXPECT_TRUE(statusBar != nullptr);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
ret = inputMethodAbility_->DestroyPanel(softKeyboardPanel);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
ret = inputMethodAbility_->DestroyPanel(statusBar);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: testCreatePanel004
|
||||
* @tc.desc: It's allowed to create one STATUS_BAR panel and one SOFT_KEYBOARD panel.
|
||||
* @tc.type: FUNC
|
||||
* @tc.require:
|
||||
*/
|
||||
HWTEST_F(InputMethodAbilityTest, testCreatePanel004, TestSize.Level0)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodAbilityTest testCreatePanel006 START. Allowed to create one SOFT_KEYBOARD panel and "
|
||||
"one STATUS_BAR panel.");
|
||||
std::shared_ptr<InputMethodPanel> inputMethodPanel = nullptr;
|
||||
PanelInfo panelInfo1 = { .panelType = SOFT_KEYBOARD, .panelFlag = FLG_FIXED };
|
||||
auto ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo1, inputMethodPanel);
|
||||
EXPECT_TRUE(inputMethodPanel != nullptr);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
ret = inputMethodAbility_->DestroyPanel(inputMethodPanel);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
PanelInfo panelInfo2 = { .panelType = STATUS_BAR };
|
||||
ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo2, inputMethodPanel);
|
||||
EXPECT_TRUE(inputMethodPanel != nullptr);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
ret = inputMethodAbility_->DestroyPanel(inputMethodPanel);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
panelInfo1.panelFlag = FLG_FLOATING;
|
||||
ret = inputMethodAbility_->CreatePanel(nullptr, panelInfo1, inputMethodPanel);
|
||||
EXPECT_TRUE(inputMethodPanel != nullptr);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
ret = inputMethodAbility_->DestroyPanel(inputMethodPanel);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
}
|
||||
} // namespace MiscServices
|
||||
} // namespace OHOS
|
||||
|
321
test/unittest/cpp_test/src/input_method_panel_test.cpp
Normal file
321
test/unittest/cpp_test/src/input_method_panel_test.cpp
Normal file
@ -0,0 +1,321 @@
|
||||
/*
|
||||
* 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 "input_method_panel.h"
|
||||
|
||||
#include <condition_variable>
|
||||
#include <cstdint>
|
||||
#include <gtest/gtest.h>
|
||||
#include <string>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "display_manager.h"
|
||||
#include "global.h"
|
||||
#include "panel_status_listener.h"
|
||||
|
||||
using namespace testing::ext;
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
class InputMethodPanelTest : public testing::Test {
|
||||
public:
|
||||
static void SetUpTestCase(void);
|
||||
static void TearDownTestCase(void);
|
||||
void SetUp();
|
||||
void TearDown();
|
||||
|
||||
class PanelStatusListenerImpl : public PanelStatusListener {
|
||||
public:
|
||||
~PanelStatusListenerImpl() = default;
|
||||
void OnPanelStatus(uint32_t windowId, bool isShow)
|
||||
{
|
||||
showPanel_ = isShow;
|
||||
hidePanel_ = !isShow;
|
||||
InputMethodPanelTest::panelListenerCv_.notify_one();
|
||||
IMSA_HILOGI("PanelStatusListenerImpl OnPanelStatus in, isShow is %{public}s", isShow ? "true" : "false");
|
||||
}
|
||||
};
|
||||
static bool showPanel_;
|
||||
static bool hidePanel_;
|
||||
static std::condition_variable panelListenerCv_;
|
||||
static std::mutex panelListenerLock_;
|
||||
static constexpr uint32_t DEALY_TIME = 1;
|
||||
};
|
||||
|
||||
bool InputMethodPanelTest::showPanel_ = false;
|
||||
bool InputMethodPanelTest::hidePanel_ = false;
|
||||
std::condition_variable InputMethodPanelTest::panelListenerCv_;
|
||||
std::mutex InputMethodPanelTest::panelListenerLock_;
|
||||
void InputMethodPanelTest::SetUpTestCase(void)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodPanelTest::SetUpTestCase");
|
||||
}
|
||||
|
||||
void InputMethodPanelTest::TearDownTestCase(void)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodPanelTest::TearDownTestCase");
|
||||
}
|
||||
|
||||
void InputMethodPanelTest::SetUp(void)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodPanelTest::SetUp");
|
||||
}
|
||||
|
||||
void InputMethodPanelTest::TearDown(void)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodPanelTest::TearDown");
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: testSetUiContent
|
||||
* @tc.desc: Test SetUiContent.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(InputMethodPanelTest, testCreatePanel, TestSize.Level0)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodPanelTest::testCreatePanel start.");
|
||||
auto inputMethodPanel = std::make_shared<InputMethodPanel>();
|
||||
PanelInfo panelInfo = { .panelType = SOFT_KEYBOARD, .panelFlag = FLG_FLOATING };
|
||||
auto ret = inputMethodPanel->CreatePanel(nullptr, panelInfo);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
ret = inputMethodPanel->DestroyPanel();
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: testResizePanel
|
||||
* @tc.desc: Test Resize panel. All panels can be resized.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(InputMethodPanelTest, testResizePanel, TestSize.Level0)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodPanelTest::testResizePanel start.");
|
||||
auto inputMethodPanel = std::make_shared<InputMethodPanel>();
|
||||
PanelInfo panelInfo = { .panelType = SOFT_KEYBOARD, .panelFlag = FLG_FLOATING };
|
||||
auto ret = inputMethodPanel->CreatePanel(nullptr, panelInfo);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
|
||||
EXPECT_TRUE(defaultDisplay != nullptr);
|
||||
int32_t width = defaultDisplay->GetWidth();
|
||||
int32_t height = defaultDisplay->GetHeight();
|
||||
|
||||
ret = inputMethodPanel->Resize(width - 1, height / 2 - 1);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
ret = inputMethodPanel->Resize(width, height / 2);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
ret = inputMethodPanel->Resize(width + 1, height / 2);
|
||||
EXPECT_EQ(ret, ErrorCode::ERROR_BAD_PARAMETERS);
|
||||
|
||||
ret = inputMethodPanel->Resize(width, height / 2 + 1);
|
||||
EXPECT_EQ(ret, ErrorCode::ERROR_BAD_PARAMETERS);
|
||||
ret = inputMethodPanel->DestroyPanel();
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: testMovePanel
|
||||
* @tc.desc: Test Move panel. SOFT_KEYBOARD panel with FLG_FIXED can not be moved.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(InputMethodPanelTest, testMovePanel, TestSize.Level0)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodPanelTest::testMovePanel start.");
|
||||
auto inputMethodPanel = std::make_shared<InputMethodPanel>();
|
||||
PanelInfo panelInfo = { .panelType = SOFT_KEYBOARD, .panelFlag = FLG_FIXED };
|
||||
auto ret = inputMethodPanel->CreatePanel(nullptr, panelInfo);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
ret = inputMethodPanel->MoveTo(10, 100);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
ret = inputMethodPanel->ChangePanelFlag(PanelFlag::FLG_FLOATING);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
ret = inputMethodPanel->MoveTo(10, 100);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
ret = inputMethodPanel->DestroyPanel();
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
panelInfo.panelType = STATUS_BAR;
|
||||
ret = inputMethodPanel->CreatePanel(nullptr, panelInfo);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
ret = inputMethodPanel->MoveTo(10, 100);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
ret = inputMethodPanel->DestroyPanel();
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: testShowPanel
|
||||
* @tc.desc: Test Show panel.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(InputMethodPanelTest, testShowPanel, TestSize.Level0)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodPanelTest::testShowPanel start.");
|
||||
auto inputMethodPanel = std::make_shared<InputMethodPanel>();
|
||||
PanelInfo panelInfo = { .panelType = SOFT_KEYBOARD, .panelFlag = FLG_FIXED };
|
||||
// 0、not create panel, show panel failed.
|
||||
auto ret = inputMethodPanel->ShowPanel();
|
||||
EXPECT_EQ(ret, ErrorCode::ERROR_NULL_POINTER);
|
||||
ret = inputMethodPanel->CreatePanel(nullptr, panelInfo);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
ret = inputMethodPanel->ShowPanel();
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
auto statusListener = std::make_shared<InputMethodPanelTest::PanelStatusListenerImpl>();
|
||||
EXPECT_TRUE(statusListener != nullptr);
|
||||
inputMethodPanel->SetPanelStatusListener(statusListener);
|
||||
ret = inputMethodPanel->ShowPanel();
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
// 2、show floating type panel.
|
||||
ret = inputMethodPanel->ChangePanelFlag(PanelFlag::FLG_FLOATING);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
ret = inputMethodPanel->ShowPanel();
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
ret = inputMethodPanel->DestroyPanel();
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
// 4、show status bar.
|
||||
panelInfo.panelType = STATUS_BAR;
|
||||
ret = inputMethodPanel->CreatePanel(nullptr, panelInfo);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
ret = inputMethodPanel->ShowPanel();
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
ret = inputMethodPanel->HidePanel();
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
ret = inputMethodPanel->DestroyPanel();
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: testSetPanelStatusListener
|
||||
* @tc.desc: Test SetPanelStatusListener.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(InputMethodPanelTest, testSetPanelStatusListener, TestSize.Level0)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodPanelTest::testSetPanelStatusListener start.");
|
||||
auto inputMethodPanel = std::make_shared<InputMethodPanel>();
|
||||
EXPECT_TRUE(inputMethodPanel != nullptr);
|
||||
auto statusListener = std::make_shared<InputMethodPanelTest::PanelStatusListenerImpl>();
|
||||
EXPECT_TRUE(statusListener != nullptr);
|
||||
inputMethodPanel->SetPanelStatusListener(statusListener);
|
||||
|
||||
PanelInfo panelInfo = { .panelType = SOFT_KEYBOARD, .panelFlag = FLG_FIXED };
|
||||
auto ret = inputMethodPanel->CreatePanel(nullptr, panelInfo);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
|
||||
ret = inputMethodPanel->ShowPanel();
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(InputMethodPanelTest::panelListenerLock_);
|
||||
InputMethodPanelTest::panelListenerCv_.wait_for(lock, std::chrono::seconds(InputMethodPanelTest::DEALY_TIME),
|
||||
[] { return InputMethodPanelTest::showPanel_ == true; });
|
||||
}
|
||||
EXPECT_TRUE(InputMethodPanelTest::showPanel_);
|
||||
|
||||
ret = inputMethodPanel->HidePanel();
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(InputMethodPanelTest::panelListenerLock_);
|
||||
InputMethodPanelTest::panelListenerCv_.wait_for(lock, std::chrono::seconds(InputMethodPanelTest::DEALY_TIME),
|
||||
[] { return InputMethodPanelTest::showPanel_ == false; });
|
||||
}
|
||||
EXPECT_TRUE(!InputMethodPanelTest::showPanel_);
|
||||
ret = inputMethodPanel->DestroyPanel();
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: testGetPanelType
|
||||
* @tc.desc: Test GetPanelType.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(InputMethodPanelTest, testGetPanelType, TestSize.Level0)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodPanelTest::testSetUiContent start.");
|
||||
auto inputMethodPanel = std::make_shared<InputMethodPanel>();
|
||||
PanelInfo panelInfo = { .panelType = SOFT_KEYBOARD, .panelFlag = FLG_FLOATING };
|
||||
auto ret = inputMethodPanel->CreatePanel(nullptr, panelInfo);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
auto type = inputMethodPanel->GetPanelType();
|
||||
EXPECT_EQ(type, panelInfo.panelType);
|
||||
ret = inputMethodPanel->DestroyPanel();
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: testRemovePanelListener
|
||||
* @tc.desc: Test RemovePanelListener.
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(InputMethodPanelTest, testRemovePanelListener, TestSize.Level0)
|
||||
{
|
||||
IMSA_HILOGI("InputMethodPanelTest::testRemovePanelListener start.");
|
||||
auto inputMethodPanel = std::make_shared<InputMethodPanel>();
|
||||
PanelInfo panelInfo = { .panelType = SOFT_KEYBOARD, .panelFlag = FLG_FLOATING };
|
||||
auto ret = inputMethodPanel->CreatePanel(nullptr, panelInfo);
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
auto type = inputMethodPanel->GetPanelType();
|
||||
EXPECT_EQ(type, panelInfo.panelType);
|
||||
|
||||
std::string subscribeType = "show";
|
||||
inputMethodPanel->RemovePanelListener(subscribeType);
|
||||
ret = inputMethodPanel->ShowPanel();
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(InputMethodPanelTest::panelListenerLock_);
|
||||
InputMethodPanelTest::panelListenerCv_.wait_for(lock, std::chrono::seconds(InputMethodPanelTest::DEALY_TIME),
|
||||
[] { return InputMethodPanelTest::showPanel_ == false; });
|
||||
}
|
||||
EXPECT_EQ(InputMethodPanelTest::showPanel_, false);
|
||||
ret = inputMethodPanel->HidePanel();
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(InputMethodPanelTest::panelListenerLock_);
|
||||
InputMethodPanelTest::panelListenerCv_.wait_for(lock, std::chrono::seconds(InputMethodPanelTest::DEALY_TIME),
|
||||
[] { return InputMethodPanelTest::hidePanel_ == true; });
|
||||
}
|
||||
EXPECT_EQ(InputMethodPanelTest::hidePanel_, true);
|
||||
InputMethodPanelTest::hidePanel_ = false;
|
||||
|
||||
subscribeType = "hide";
|
||||
inputMethodPanel->RemovePanelListener(subscribeType);
|
||||
ret = inputMethodPanel->ShowPanel();
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(InputMethodPanelTest::panelListenerLock_);
|
||||
InputMethodPanelTest::panelListenerCv_.wait_for(lock, std::chrono::seconds(InputMethodPanelTest::DEALY_TIME),
|
||||
[] { return InputMethodPanelTest::showPanel_ == false; });
|
||||
}
|
||||
EXPECT_EQ(InputMethodPanelTest::showPanel_, false);
|
||||
ret = inputMethodPanel->HidePanel();
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(InputMethodPanelTest::panelListenerLock_);
|
||||
InputMethodPanelTest::panelListenerCv_.wait_for(lock, std::chrono::seconds(InputMethodPanelTest::DEALY_TIME),
|
||||
[] { return InputMethodPanelTest::hidePanel_ == false; });
|
||||
}
|
||||
EXPECT_EQ(InputMethodPanelTest::hidePanel_, false);
|
||||
|
||||
ret = inputMethodPanel->DestroyPanel();
|
||||
EXPECT_EQ(ret, ErrorCode::NO_ERROR);
|
||||
}
|
||||
} // namespace MiscServices
|
||||
} // namespace OHOS
|
Loading…
x
Reference in New Issue
Block a user