mirror of
https://gitee.com/openharmony/inputmethod_imf
synced 2025-02-17 05:38:18 +00:00
add keyboardpanelmanager
Signed-off-by: guojin31 <guojin31@huawei.com>
This commit is contained in:
parent
5959eb0b22
commit
4ec234ce79
1
BUILD.gn
1
BUILD.gn
@ -24,6 +24,7 @@ group("imf_packages") {
|
||||
"frameworks/js/napi/inputmethodability:inputmethodengine",
|
||||
"frameworks/js/napi/inputmethodclient:inputmethod",
|
||||
"frameworks/js/napi/inputmethodlist:inputmethodlist",
|
||||
"frameworks/js/napi/keyboardpanelmanager:keyboardpanelmanager",
|
||||
"interfaces/inner_api/inputmethod_ability:inputmethod_ability",
|
||||
"interfaces/inner_api/inputmethod_controller:inputmethod_client",
|
||||
"profile:inputmethod_inputmethod_sa_profiles",
|
||||
|
@ -75,7 +75,8 @@
|
||||
"//base/inputmethod/imf/frameworks/kits/extension:inputmethod_extension_module",
|
||||
"//base/inputmethod/imf/frameworks/js/napi/inputmethodability:inputmethodengine",
|
||||
"//base/inputmethod/imf/frameworks/js/napi/inputmethod_extension_ability:inputmethodextensionability_napi",
|
||||
"//base/inputmethod/imf/frameworks/js/napi/inputmethod_extension_context:inputmethodextensioncontext_napi"
|
||||
"//base/inputmethod/imf/frameworks/js/napi/inputmethod_extension_context:inputmethodextensioncontext_napi",
|
||||
"//base/inputmethod/imf/frameworks/js/napi/keyboardpanelmanager:keyboardpanelmanager"
|
||||
]
|
||||
},
|
||||
"inner_api": [
|
||||
@ -88,10 +89,8 @@
|
||||
"../../../../frameworks/native/inputmethod_controller/include/input_method_property.h",
|
||||
"../../../../frameworks/native/inputmethod_controller/include/input_method_utils.h",
|
||||
"../../../../frameworks/native/inputmethod_controller/include/input_window_info.h",
|
||||
"../../../../frameworks/native/inputmethod_controller/include/i_system_cmd_channel.h",
|
||||
"ime_event_listener.h",
|
||||
"ime_event_monitor_manager.h",
|
||||
"ime_system_channel.h",
|
||||
"input_method_controller.h"
|
||||
],
|
||||
"header_base": "//base/inputmethod/imf/interfaces/inner_api/inputmethod_controller/include"
|
||||
|
@ -28,7 +28,8 @@ const std::unordered_map<EventSubscribeModule, std::unordered_set<std::string>>
|
||||
"securityModeChange", "privateCommand" } },
|
||||
{ EventSubscribeModule::KEYBOARD_DELEGATE, { "editorAttributeChanged", "keyDown", "keyUp", "keyEvent",
|
||||
"cursorContextChange", "selectionChange", "textChange" } },
|
||||
{ EventSubscribeModule::PANEL, { "show", "hide" } }
|
||||
{ EventSubscribeModule::PANEL, { "show", "hide" } },
|
||||
{ EventSubscribeModule::KEYBOARD_PANEL_MANAGER, { "panelPrivateCommand", "isPanelShow" } }
|
||||
};
|
||||
bool EventChecker::IsValidEventType(EventSubscribeModule module, const std::string &type)
|
||||
{
|
||||
|
@ -26,6 +26,7 @@ enum class EventSubscribeModule : uint32_t {
|
||||
INPUT_METHOD_SETTING,
|
||||
INPUT_METHOD_ABILITY,
|
||||
KEYBOARD_DELEGATE,
|
||||
KEYBOARD_PANEL_MANAGER,
|
||||
PANEL,
|
||||
};
|
||||
class EventChecker {
|
||||
|
67
frameworks/js/napi/keyboardpanelmanager/BUILD.gn
Normal file
67
frameworks/js/napi/keyboardpanelmanager/BUILD.gn
Normal file
@ -0,0 +1,67 @@
|
||||
# Copyright (C) 2024 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.
|
||||
|
||||
import("//base/inputmethod/imf/inputmethod.gni")
|
||||
import("//build/ohos.gni")
|
||||
|
||||
config("keyboard_panel_manager_config") {
|
||||
visibility = [ ":*" ]
|
||||
include_dirs = [ "include" ]
|
||||
}
|
||||
|
||||
config("keyboard_panel_manager_public_config") {
|
||||
visibility = [ "./*" ]
|
||||
include_dirs = [
|
||||
"include",
|
||||
"${inputmethod_path}/common",
|
||||
"${inputmethod_path}/frameworks/common",
|
||||
"${inputmethod_path}/frameworks/js/napi/inputmethodclient",
|
||||
]
|
||||
}
|
||||
|
||||
ohos_shared_library("keyboardpanelmanager") {
|
||||
branch_protector_ret = "pac_ret"
|
||||
sanitize = {
|
||||
cfi = true
|
||||
cfi_cross_dso = true
|
||||
debug = false
|
||||
}
|
||||
sources = [
|
||||
"${inputmethod_path}/frameworks/js/napi/inputmethodclient/async_call.cpp",
|
||||
"${inputmethod_path}/frameworks/js/napi/inputmethodclient/js_utils.cpp",
|
||||
"js_keyboard_panel_manager.cpp",
|
||||
"keyboard_panel_manager_module.cpp",
|
||||
]
|
||||
|
||||
configs = [ ":keyboard_panel_manager_config" ]
|
||||
|
||||
deps = [
|
||||
"${inputmethod_path}/frameworks/js/napi/common:inputmethod_js_common",
|
||||
"${inputmethod_path}/interfaces/inner_api/inputmethod_controller:inputmethod_client",
|
||||
]
|
||||
|
||||
external_deps = [
|
||||
"ability_runtime:abilitykit_native",
|
||||
"c_utils:utils",
|
||||
"eventhandler:libeventhandler",
|
||||
"hilog:libhilog",
|
||||
"input:libmmi-client",
|
||||
"napi:ace_napi",
|
||||
]
|
||||
|
||||
public_configs = [ ":keyboard_panel_manager_public_config" ]
|
||||
|
||||
relative_install_dir = "module"
|
||||
subsystem_name = "inputmethod"
|
||||
part_name = "imf"
|
||||
}
|
@ -0,0 +1,314 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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_keyboard_panel_manager.h"
|
||||
|
||||
#include "event_checker.h"
|
||||
#include "input_method_utils.h"
|
||||
#include "js_callback_handler.h"
|
||||
#include "js_util.h"
|
||||
#include "js_utils.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
constexpr int32_t MAX_WAIT_TIME_PRIVATE_COMMAND = 2000;
|
||||
BlockQueue<PrivateCommandInfo> JsKeyboardPanelManager::privateCommandQueue_{ MAX_WAIT_TIME_PRIVATE_COMMAND };
|
||||
std::mutex JsKeyboardPanelManager::managerMutex_;
|
||||
sptr<JsKeyboardPanelManager> JsKeyboardPanelManager::keyboardPanelManager_{ nullptr };
|
||||
|
||||
JsKeyboardPanelManager::JsKeyboardPanelManager()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(eventHandlerMutex_);
|
||||
handler_ = AppExecFwk::EventHandler::Current();
|
||||
}
|
||||
|
||||
napi_value JsKeyboardPanelManager::Init(napi_env env, napi_value info)
|
||||
{
|
||||
napi_property_descriptor descriptor[] = {
|
||||
DECLARE_NAPI_FUNCTION("sendPrivateCommand", SendPrivateCommand),
|
||||
DECLARE_NAPI_FUNCTION("getSmartMenuCfg", GetSmartMenuCfg),
|
||||
DECLARE_NAPI_FUNCTION("on", Subscribe),
|
||||
DECLARE_NAPI_FUNCTION("off", UnSubscribe),
|
||||
};
|
||||
NAPI_CALL(
|
||||
env, napi_define_properties(env, info, sizeof(descriptor) / sizeof(napi_property_descriptor), descriptor));
|
||||
return info;
|
||||
}
|
||||
|
||||
sptr<JsKeyboardPanelManager> JsKeyboardPanelManager::GetInstance()
|
||||
{
|
||||
if (keyboardPanelManager_ == nullptr) {
|
||||
std::lock_guard<std::mutex> lock(managerMutex_);
|
||||
if (keyboardPanelManager_ == nullptr) {
|
||||
keyboardPanelManager_ = new (std::nothrow) JsKeyboardPanelManager();
|
||||
}
|
||||
}
|
||||
return keyboardPanelManager_;
|
||||
}
|
||||
|
||||
napi_value JsKeyboardPanelManager::Subscribe(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = 2; // has 2 param
|
||||
napi_value argv[2] = { nullptr };
|
||||
napi_value thisVar = nullptr;
|
||||
void *data = nullptr;
|
||||
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
|
||||
std::string type;
|
||||
// 2 means least param num.
|
||||
if (argc < 2 || !JsUtil::GetValue(env, argv[0], type)
|
||||
|| !EventChecker::IsValidEventType(EventSubscribeModule::KEYBOARD_PANEL_MANAGER, type)
|
||||
|| JsUtil::GetType(env, argv[1]) != napi_function) {
|
||||
IMSA_HILOGE("Subscribe failed, type:%{public}s", type.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
auto manager = JsKeyboardPanelManager::GetInstance();
|
||||
auto ret = ImeSystemCmdChannel::GetInstance()->ConnectSystemCmd(manager);
|
||||
if (ret != ErrorCode::NO_ERROR) {
|
||||
IMSA_HILOGE("Subscribe failed, type:%{public}s", type.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
IMSA_HILOGD("Subscribe type:%{public}s.", type.c_str());
|
||||
std::shared_ptr<JSCallbackObject> callback =
|
||||
std::make_shared<JSCallbackObject>(env, argv[1], std::this_thread::get_id());
|
||||
manager->RegisterListener(argv[1], type, callback);
|
||||
return JsUtil::Const::Null(env);
|
||||
}
|
||||
|
||||
napi_value JsKeyboardPanelManager::UnSubscribe(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = 2; // has 2 param
|
||||
napi_value argv[2] = { nullptr };
|
||||
napi_value thisVar = nullptr;
|
||||
void *data = nullptr;
|
||||
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
|
||||
std::string type;
|
||||
// 1 means least param num.
|
||||
if (argc < 1 || !JsUtil::GetValue(env, argv[0], type)
|
||||
|| !EventChecker::IsValidEventType(EventSubscribeModule::KEYBOARD_PANEL_MANAGER, type)) {
|
||||
IMSA_HILOGE("UnSubscribe failed, type:%{public}s", type.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
auto manager = JsKeyboardPanelManager::GetInstance();
|
||||
auto ret = ImeSystemCmdChannel::GetInstance()->ConnectSystemCmd(manager);
|
||||
if (ret != ErrorCode::NO_ERROR) {
|
||||
IMSA_HILOGE("UnSubscribe failed, type:%{public}s", type.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
// if the second param is not napi_function/napi_null/napi_undefined, return
|
||||
auto paramType = JsUtil::GetType(env, argv[1]);
|
||||
if (paramType != napi_function && paramType != napi_null && paramType != napi_undefined) {
|
||||
return nullptr;
|
||||
}
|
||||
// if the second param is napi_function, delete it, else delete all
|
||||
argv[1] = paramType == napi_function ? argv[1] : nullptr;
|
||||
|
||||
IMSA_HILOGD("UnSubscribe type:%{public}s.", type.c_str());
|
||||
manager->UnRegisterListener(argv[1], type);
|
||||
return JsUtil::Const::Null(env);
|
||||
}
|
||||
|
||||
void JsKeyboardPanelManager::RegisterListener(
|
||||
napi_value callback, std::string type, std::shared_ptr<JSCallbackObject> callbackObj)
|
||||
{
|
||||
IMSA_HILOGD("RegisterListener %{public}s", type.c_str());
|
||||
std::lock_guard<std::recursive_mutex> lock(mutex_);
|
||||
if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
|
||||
IMSA_HILOGD("methodName: %{public}s not registered!", type.c_str());
|
||||
}
|
||||
auto callbacks = jsCbMap_[type];
|
||||
bool ret = std::any_of(callbacks.begin(), callbacks.end(), [&callback](std::shared_ptr<JSCallbackObject> cb) {
|
||||
return JsUtils::Equals(cb->env_, callback, cb->callback_, cb->threadId_);
|
||||
});
|
||||
if (ret) {
|
||||
IMSA_HILOGD("JsKeyboardPanelManagerListener callback already registered!");
|
||||
return;
|
||||
}
|
||||
|
||||
IMSA_HILOGI("Add %{public}s callbackObj into jsCbMap_", type.c_str());
|
||||
jsCbMap_[type].push_back(std::move(callbackObj));
|
||||
}
|
||||
|
||||
void JsKeyboardPanelManager::UnRegisterListener(napi_value callback, std::string type)
|
||||
{
|
||||
IMSA_HILOGI("event: %{public}s", type.c_str());
|
||||
std::lock_guard<std::recursive_mutex> lock(mutex_);
|
||||
if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
|
||||
IMSA_HILOGE("methodName: %{public}s already unRegistered!", type.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (callback == nullptr) {
|
||||
jsCbMap_.erase(type);
|
||||
IMSA_HILOGI("callback is nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto item = jsCbMap_[type].begin(); item != jsCbMap_[type].end(); item++) {
|
||||
if (JsUtils::Equals((*item)->env_, callback, (*item)->callback_, (*item)->threadId_)) {
|
||||
jsCbMap_[type].erase(item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (jsCbMap_[type].empty()) {
|
||||
jsCbMap_.erase(type);
|
||||
}
|
||||
}
|
||||
|
||||
napi_value JsKeyboardPanelManager::GetSmartMenuCfg(napi_env env, napi_callback_info info)
|
||||
{
|
||||
auto ctxt = std::make_shared<SmartMenuContext>();
|
||||
auto output = [ctxt](napi_env env, napi_value *result) -> napi_status {
|
||||
*result = JsUtil::GetValue(env, ctxt->smartMenu);
|
||||
return napi_ok;
|
||||
};
|
||||
auto exec = [ctxt](AsyncCall::Context *ctx) {
|
||||
ctxt->smartMenu = ImeSystemCmdChannel::GetInstance()->GetSmartMenuCfg();
|
||||
ctxt->SetState(napi_ok);
|
||||
};
|
||||
ctxt->SetAction(nullptr, std::move(output));
|
||||
// 1 means JsAPI:displayOptionalInputMethod has 1 params at most.
|
||||
AsyncCall asyncCall(env, info, ctxt, 1);
|
||||
return asyncCall.Call(env, exec, "GetSmartMenuCfg");
|
||||
}
|
||||
|
||||
|
||||
napi_value JsKeyboardPanelManager::SendPrivateCommand(napi_env env, napi_callback_info info)
|
||||
{
|
||||
auto ctxt = std::make_shared<SendPrivateCommandContext>();
|
||||
auto input = [ctxt](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
|
||||
PARAM_CHECK_RETURN(env, argc > 0, "should 1 parameter!", TYPE_NONE, napi_generic_failure);
|
||||
CHECK_RETURN(JsUtils::GetValue(env, argv[0], ctxt->privateCommand) == napi_ok,
|
||||
"GetValue privateCommand error", napi_generic_failure);
|
||||
if (!TextConfig::IsPrivateCommandValid(ctxt->privateCommand)) {
|
||||
PARAM_CHECK_RETURN(
|
||||
env, false, "privateCommand size limit 32KB, count limit 5.", TYPE_NONE, napi_generic_failure);
|
||||
}
|
||||
ctxt->info = { std::chrono::system_clock::now(), ctxt->privateCommand };
|
||||
privateCommandQueue_.Push(ctxt->info);
|
||||
return napi_ok;
|
||||
};
|
||||
auto output = [ctxt](napi_env env, napi_value *result) -> napi_status { return napi_ok; };
|
||||
auto exec = [ctxt](AsyncCall::Context *ctx) {
|
||||
privateCommandQueue_.Wait(ctxt->info);
|
||||
int32_t code = ImeSystemCmdChannel::GetInstance()->SendPrivateCommand(ctxt->privateCommand);
|
||||
privateCommandQueue_.Pop();
|
||||
if (code == ErrorCode::NO_ERROR) {
|
||||
ctxt->SetState(napi_ok);
|
||||
} else {
|
||||
ctxt->SetErrorCode(code);
|
||||
}
|
||||
};
|
||||
ctxt->SetAction(std::move(input), std::move(output));
|
||||
// 1 means JsAPI:SendPrivateCommand has 1 params at most.
|
||||
AsyncCall asyncCall(env, info, ctxt, 1);
|
||||
return asyncCall.Call(env, exec, "SendPrivateCommand");
|
||||
}
|
||||
|
||||
void JsKeyboardPanelManager::ReceivePrivateCommand(
|
||||
const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
|
||||
{
|
||||
IMSA_HILOGD("JsKeyboardPanelManager, run in");
|
||||
std::string type = "panelPrivateCommand";
|
||||
auto entry = GetEntry(type, [&privateCommand](UvEntry &entry) { entry.privateCommand = privateCommand; });
|
||||
if (entry == nullptr) {
|
||||
return;
|
||||
}
|
||||
auto eventHandler = GetEventHandler();
|
||||
if (eventHandler == nullptr) {
|
||||
IMSA_HILOGE("eventHandler is nullptr!");
|
||||
return;
|
||||
}
|
||||
auto task = [entry]() {
|
||||
auto paramGetter = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool {
|
||||
if (argc < 1) {
|
||||
return false;
|
||||
}
|
||||
napi_value jsObject = JsUtils::GetJsPrivateCommand(env, entry->privateCommand);
|
||||
if (jsObject == nullptr) {
|
||||
IMSA_HILOGE("GetJsPrivateCommand failed: jsObject is nullptr");
|
||||
return false;
|
||||
}
|
||||
// 0 means the first param of callback.
|
||||
args[0] = { jsObject };
|
||||
return true;
|
||||
};
|
||||
// 1 means callback has 1 params.
|
||||
JsCallbackHandler::Traverse(entry->vecCopy, { 1, paramGetter });
|
||||
};
|
||||
eventHandler->PostTask(task, type, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
|
||||
}
|
||||
|
||||
void JsKeyboardPanelManager::NotifyIsShowSysPanel(bool shouldSysPanelShow)
|
||||
{
|
||||
IMSA_HILOGD("JsKeyboardPanelManager, run in");
|
||||
std::string type = "isPanelShow";
|
||||
auto entry =
|
||||
GetEntry(type, [shouldSysPanelShow](UvEntry &entry) { entry.shouldSysPanelShow = shouldSysPanelShow; });
|
||||
if (entry == nullptr) {
|
||||
return;
|
||||
}
|
||||
auto eventHandler = GetEventHandler();
|
||||
if (eventHandler == nullptr) {
|
||||
IMSA_HILOGE("eventHandler is nullptr!");
|
||||
return;
|
||||
}
|
||||
auto task = [entry]() {
|
||||
auto paramGetter = [entry](napi_env env, napi_value *args, uint8_t argc) -> bool {
|
||||
if (argc < 1) {
|
||||
return false;
|
||||
}
|
||||
napi_value jsObject = JsUtil::GetValue(env, entry->shouldSysPanelShow);
|
||||
args[0] = { jsObject };
|
||||
return true;
|
||||
};
|
||||
// 1 means callback has 1 params.
|
||||
JsCallbackHandler::Traverse(entry->vecCopy, { 1, paramGetter });
|
||||
};
|
||||
eventHandler->PostTask(task, type, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
|
||||
}
|
||||
|
||||
std::shared_ptr<AppExecFwk::EventHandler> JsKeyboardPanelManager::GetEventHandler()
|
||||
{
|
||||
if (handler_ != nullptr) {
|
||||
return handler_;
|
||||
}
|
||||
std::lock_guard<std::mutex> lock(eventHandlerMutex_);
|
||||
if (handler_ == nullptr) {
|
||||
handler_ = AppExecFwk::EventHandler::Current();
|
||||
}
|
||||
return handler_;
|
||||
}
|
||||
|
||||
std::shared_ptr<JsKeyboardPanelManager::UvEntry> JsKeyboardPanelManager::GetEntry(
|
||||
const std::string &type, EntrySetter entrySetter)
|
||||
{
|
||||
IMSA_HILOGD("type: %{public}s", type.c_str());
|
||||
std::shared_ptr<UvEntry> entry = nullptr;
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lock(mutex_);
|
||||
if (jsCbMap_[type].empty()) {
|
||||
IMSA_HILOGD("%{public}s cb-vector is empty", type.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
entry = std::make_shared<UvEntry>(jsCbMap_[type], type);
|
||||
}
|
||||
if (entrySetter != nullptr) {
|
||||
entrySetter(*entry);
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
} // namespace MiscServices
|
||||
} // namespace OHOS
|
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 FRAMEWORKS_JS_NAPI_JS_KEYBOARD_PANEL_MANAGER_H
|
||||
#define FRAMEWORKS_JS_NAPI_JS_KEYBOARD_PANEL_MANAGER_H
|
||||
|
||||
#include "async_call.h"
|
||||
#include "block_queue.h"
|
||||
#include "event_handler.h"
|
||||
#include "js_callback_object.h"
|
||||
#include "ime_system_channel.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
struct PrivateCommandInfo {
|
||||
std::chrono::system_clock::time_point timestamp{};
|
||||
std::unordered_map<std::string, PrivateDataValue> privateCommand;
|
||||
bool operator==(const PrivateCommandInfo &info) const
|
||||
{
|
||||
return (timestamp == info.timestamp && privateCommand == info.privateCommand);
|
||||
}
|
||||
};
|
||||
|
||||
struct SendPrivateCommandContext : public AsyncCall::Context {
|
||||
std::unordered_map<std::string, PrivateDataValue> privateCommand;
|
||||
PrivateCommandInfo info;
|
||||
SendPrivateCommandContext() : Context(nullptr, nullptr){};
|
||||
|
||||
napi_status operator()(napi_env env, napi_value *result) override
|
||||
{
|
||||
if (status_ != napi_ok) {
|
||||
output_ = nullptr;
|
||||
return status_;
|
||||
}
|
||||
return Context::operator()(env, result);
|
||||
}
|
||||
};
|
||||
|
||||
struct SmartMenuContext : public AsyncCall::Context {
|
||||
std::string smartMenu;
|
||||
SmartMenuContext() : Context(nullptr, nullptr){};
|
||||
|
||||
napi_status operator()(napi_env env, napi_value *result) override
|
||||
{
|
||||
if (status_ != napi_ok) {
|
||||
output_ = nullptr;
|
||||
return status_;
|
||||
}
|
||||
return Context::operator()(env, result);
|
||||
}
|
||||
};
|
||||
|
||||
class JsKeyboardPanelManager : public OnSystemCmdListener {
|
||||
public:
|
||||
JsKeyboardPanelManager();
|
||||
~JsKeyboardPanelManager() = default;
|
||||
|
||||
static napi_value Init(napi_env env, napi_value info);
|
||||
static sptr<JsKeyboardPanelManager> GetInstance();
|
||||
static napi_value SendPrivateCommand(napi_env env, napi_callback_info info);
|
||||
static napi_value GetSmartMenuCfg(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 ReceivePrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand) override;
|
||||
void NotifyIsShowSysPanel(bool shouldSysPanelShow) override;
|
||||
|
||||
private:
|
||||
void RegisterListener(napi_value callback, std::string type, std::shared_ptr<JSCallbackObject> callbackObj);
|
||||
void UnRegisterListener(napi_value callback, std::string type);
|
||||
|
||||
struct UvEntry {
|
||||
std::vector<std::shared_ptr<JSCallbackObject>> vecCopy;
|
||||
std::string type;
|
||||
bool shouldSysPanelShow;
|
||||
std::string smartMenu;
|
||||
std::unordered_map<std::string, PrivateDataValue> privateCommand;
|
||||
explicit UvEntry(const std::vector<std::shared_ptr<JSCallbackObject>> &cbVec, const std::string &type)
|
||||
: vecCopy(cbVec), type(type)
|
||||
{
|
||||
}
|
||||
};
|
||||
using EntrySetter = std::function<void(UvEntry &)>;
|
||||
std::shared_ptr<AppExecFwk::EventHandler> GetEventHandler();
|
||||
std::shared_ptr<UvEntry> GetEntry(const std::string &type, EntrySetter entrySetter = nullptr);
|
||||
|
||||
std::recursive_mutex mutex_;
|
||||
std::map<std::string, std::vector<std::shared_ptr<JSCallbackObject>>> jsCbMap_;
|
||||
std::mutex eventHandlerMutex_;
|
||||
std::shared_ptr<AppExecFwk::EventHandler> handler_;
|
||||
static std::mutex managerMutex_;
|
||||
static sptr<JsKeyboardPanelManager> keyboardPanelManager_;
|
||||
static BlockQueue<PrivateCommandInfo> privateCommandQueue_;
|
||||
};
|
||||
} // namespace MiscServices
|
||||
} // namespace OHOS
|
||||
#endif // FRAMEWORKS_JS_NAPI_JS_KEYBOARD_PANEL_MANAGER_H
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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_keyboard_panel_manager.h"
|
||||
|
||||
EXTERN_C_START
|
||||
/*
|
||||
* function for module exports
|
||||
*/
|
||||
static napi_value Init(napi_env env, napi_value exports)
|
||||
{
|
||||
OHOS::MiscServices::JsKeyboardPanelManager::Init(env, exports);
|
||||
return exports;
|
||||
}
|
||||
EXTERN_C_END
|
||||
/*
|
||||
* module define
|
||||
*/
|
||||
static napi_module _module = { .nm_version = 1,
|
||||
.nm_flags = 0,
|
||||
.nm_filename = nullptr,
|
||||
.nm_register_func = Init,
|
||||
.nm_modname = "keyboardPanelManager",
|
||||
.nm_priv = ((void *)0),
|
||||
.reserved = { 0 } };
|
||||
/*
|
||||
* module register
|
||||
*/
|
||||
extern "C" __attribute__((constructor)) void Register()
|
||||
{
|
||||
napi_module_register(&_module);
|
||||
}
|
@ -13,10 +13,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_IME_SYSTEM_CHANNEL_H
|
||||
#define FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_IME_SYSTEM_CHANNEL_H
|
||||
#ifndef INPUTMETHOD_CONTROLLER_IME_SYSTEM_CHANNEL_H
|
||||
#define INPUTMETHOD_CONTROLLER_IME_SYSTEM_CHANNEL_H
|
||||
|
||||
#include "global.h"
|
||||
#include "bundle_mgr_client.h"
|
||||
#include "i_input_method_agent.h"
|
||||
#include "i_input_method_system_ability.h"
|
||||
#include "input_method_utils.h"
|
||||
@ -28,11 +28,11 @@
|
||||
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
using namespace OHOS::AppExecFwk;
|
||||
class OnSystemCmdListener : public virtual RefBase {
|
||||
public:
|
||||
virtual int32_t ReceivePrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
|
||||
virtual void ReceivePrivateCommand(const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
|
||||
{
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
virtual void NotifyIsShowSysPanel(bool shouldSysPanelShow)
|
||||
{
|
||||
@ -49,7 +49,7 @@ public:
|
||||
* @return The instance of ImeSystemCmdChannel.
|
||||
* @since 12
|
||||
*/
|
||||
IMF_API static sptr<ImeSystemCmdChannel> GetInstance();
|
||||
static sptr<ImeSystemCmdChannel> GetInstance();
|
||||
|
||||
/**
|
||||
* @brief Connect system channel, set listener and bind IMSA.
|
||||
@ -60,7 +60,7 @@ public:
|
||||
* @return Returns 0 for success, others for failure.
|
||||
* @since 12
|
||||
*/
|
||||
IMF_API int32_t ConnectSystemCmd(const sptr<OnSystemCmdListener> &listener);
|
||||
int32_t ConnectSystemCmd(const sptr<OnSystemCmdListener> &listener);
|
||||
|
||||
/**
|
||||
* @brief Send private command to ime.
|
||||
@ -71,28 +71,25 @@ public:
|
||||
* @return Returns 0 for success, others for failure.
|
||||
* @since 12
|
||||
*/
|
||||
IMF_API int32_t SendPrivateCommand(
|
||||
int32_t SendPrivateCommand(
|
||||
const std::unordered_map<std::string, PrivateDataValue> &privateCommand) override;
|
||||
|
||||
std::string GetSmartMenuCfg();
|
||||
int32_t ReceivePrivateCommand(
|
||||
const std::unordered_map<std::string, PrivateDataValue> &privateCommand) override;
|
||||
|
||||
int32_t ShowSysPanel(bool shouldSysPanelShow);
|
||||
|
||||
void OnConnectCmdReady(const sptr<IRemoteObject> &agentObject);
|
||||
|
||||
int32_t RunConnectSystemCmd();
|
||||
|
||||
private:
|
||||
ImeSystemCmdChannel();
|
||||
~ImeSystemCmdChannel();
|
||||
int32_t RunConnectSystemCmd();
|
||||
sptr<IInputMethodSystemAbility> GetSystemAbilityProxy();
|
||||
void OnRemoteSaDied(const wptr<IRemoteObject> &object);
|
||||
|
||||
void SetSystemCmdListener(const sptr<OnSystemCmdListener> &listener);
|
||||
sptr<IInputMethodAgent> GetSystemCmdAgent();
|
||||
sptr<OnSystemCmdListener> GetSystemCmdListener();
|
||||
void ClearSystemCmdAgent();
|
||||
void GetExtensionInfo(std::vector<ExtensionAbilityInfo> extensionInfos, ExtensionAbilityInfo &extInfo);
|
||||
|
||||
static std::mutex instanceLock_;
|
||||
static sptr<ImeSystemCmdChannel> instance_;
|
||||
@ -110,4 +107,4 @@ private:
|
||||
};
|
||||
} // namespace MiscServices
|
||||
} // namespace OHOS
|
||||
#endif // FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_IME_SYSTEM_CHANNEL_H
|
||||
#endif // INPUTMETHOD_CONTROLLER_IME_SYSTEM_CHANNEL_H
|
@ -25,6 +25,7 @@
|
||||
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
constexpr const char *SMART_MENU_METADATA_NAME = "ohos.extension.smart_menu";
|
||||
std::mutex ImeSystemCmdChannel::instanceLock_;
|
||||
sptr<ImeSystemCmdChannel> ImeSystemCmdChannel::instance_;
|
||||
ImeSystemCmdChannel::ImeSystemCmdChannel()
|
||||
@ -34,6 +35,7 @@ ImeSystemCmdChannel::ImeSystemCmdChannel()
|
||||
ImeSystemCmdChannel::~ImeSystemCmdChannel()
|
||||
{
|
||||
}
|
||||
|
||||
sptr<ImeSystemCmdChannel> ImeSystemCmdChannel::GetInstance()
|
||||
{
|
||||
if (instance_ == nullptr) {
|
||||
@ -154,7 +156,7 @@ sptr<IInputMethodAgent> ImeSystemCmdChannel::GetSystemCmdAgent()
|
||||
void ImeSystemCmdChannel::SetSystemCmdListener(const sptr<OnSystemCmdListener> &listener)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(systemCmdListenerLock_);
|
||||
systemCmdListener_ = listener;
|
||||
systemCmdListener_ = std::move(listener);
|
||||
}
|
||||
|
||||
sptr<OnSystemCmdListener> ImeSystemCmdChannel::GetSystemCmdListener()
|
||||
@ -180,11 +182,7 @@ int32_t ImeSystemCmdChannel::ReceivePrivateCommand(
|
||||
IMSA_HILOGE("cmdlistener is nullptr");
|
||||
return ErrorCode::ERROR_EX_NULL_POINTER;
|
||||
}
|
||||
auto ret = cmdlistener->ReceivePrivateCommand(privateCommand);
|
||||
if (ret != ErrorCode::NO_ERROR) {
|
||||
IMSA_HILOGE("ReceivePrivateCommand err, ret %{public}d", ret);
|
||||
return ErrorCode::ERROR_CMD_LISTENER_ERROR;
|
||||
}
|
||||
cmdlistener->ReceivePrivateCommand(privateCommand);
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
|
||||
@ -224,5 +222,47 @@ int32_t ImeSystemCmdChannel::ShowSysPanel(bool shouldSysPanelShow)
|
||||
listener->NotifyIsShowSysPanel(shouldSysPanelShow);
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
|
||||
std::string ImeSystemCmdChannel::GetSmartMenuCfg()
|
||||
{
|
||||
auto inputMethodController = InputMethodController::GetInstance();
|
||||
if (inputMethodController == nullptr) {
|
||||
return "";
|
||||
}
|
||||
std::shared_ptr<Property> defaultIme = nullptr;
|
||||
int32_t ret = inputMethodController->GetDefaultInputMethod(defaultIme);
|
||||
if (ret != ErrorCode::NO_ERROR || defaultIme == nullptr) {
|
||||
IMSA_HILOGE("GetDefaultInputMethod failed");
|
||||
return "";
|
||||
}
|
||||
BundleMgrClient client;
|
||||
BundleInfo bundleInfo;
|
||||
if (!client.GetBundleInfo(defaultIme->name, BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo)) {
|
||||
IMSA_HILOGE("GetBundleInfo failed");
|
||||
return "";
|
||||
}
|
||||
ExtensionAbilityInfo extInfo;
|
||||
GetExtensionInfo(bundleInfo.extensionInfos, extInfo);
|
||||
std::vector<std::string> profiles;
|
||||
if (!client.GetResConfigFile(extInfo, SMART_MENU_METADATA_NAME, profiles) || profiles.empty()) {
|
||||
IMSA_HILOGE("GetResConfigFile failed");
|
||||
return "";
|
||||
}
|
||||
return profiles[0];
|
||||
}
|
||||
|
||||
void ImeSystemCmdChannel::GetExtensionInfo(std::vector<ExtensionAbilityInfo> extensionInfos,
|
||||
ExtensionAbilityInfo &extInfo)
|
||||
{
|
||||
for (size_t i = 0; i < extensionInfos.size(); i++) {
|
||||
auto metadata = extensionInfos[i].metadata;
|
||||
for (size_t j = 0; j < metadata.size(); j++) {
|
||||
if (metadata[j].name == SMART_MENU_METADATA_NAME) {
|
||||
extInfo = extensionInfos[i];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace MiscServices
|
||||
} // namespace OHOS
|
@ -86,6 +86,8 @@ ohos_shared_library("inputmethod_client") {
|
||||
|
||||
external_deps = [
|
||||
"ability_base:want",
|
||||
"bundle_framework:appexecfwk_base",
|
||||
"bundle_framework:appexecfwk_core",
|
||||
"c_utils:utils",
|
||||
"eventhandler:libeventhandler",
|
||||
"hilog:libhilog",
|
||||
@ -137,6 +139,8 @@ ohos_static_library("inputmethod_client_static") {
|
||||
|
||||
external_deps = [
|
||||
"ability_base:want",
|
||||
"bundle_framework:appexecfwk_base",
|
||||
"bundle_framework:appexecfwk_core",
|
||||
"c_utils:utils",
|
||||
"eventhandler:libeventhandler",
|
||||
"hilog:libhilog",
|
||||
|
Loading…
x
Reference in New Issue
Block a user