add keyboardpanelmanager

Signed-off-by: guojin31 <guojin31@huawei.com>
This commit is contained in:
guojin31 2024-04-25 08:54:49 +08:00
parent 5959eb0b22
commit 4ec234ce79
11 changed files with 602 additions and 25 deletions

View File

@ -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",

View File

@ -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"

View File

@ -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)
{

View File

@ -26,6 +26,7 @@ enum class EventSubscribeModule : uint32_t {
INPUT_METHOD_SETTING,
INPUT_METHOD_ABILITY,
KEYBOARD_DELEGATE,
KEYBOARD_PANEL_MANAGER,
PANEL,
};
class EventChecker {

View 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"
}

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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",