框架jnapi从7切到8

Signed-off-by: zhouyongfei <zhouyongfei@huawei.com>
This commit is contained in:
zhouyongfei 2022-01-28 20:24:37 +08:00
parent 40d21af8e3
commit dc5c87702a
55 changed files with 1177 additions and 1749 deletions

121
bundle.json Normal file
View File

@ -0,0 +1,121 @@
{
"name": "@ohos/inputmethod",
"description": "Provide input capability to ime app",
"version": "3.1",
"license": "Apache License 2.0",
"publishAs": "code-segment",
"segment": {
"destPath": "base/miscservices/inputmethod"
},
"dirs": {},
"scripts": {},
"component": {
"name": "inputmethod_native",
"subsystem": "miscservices",
"syscap": [
"SystemCapability.Miscservices.InputMethod"
],
"features": [
],
"adapted_system_type": [
"standard"
],
"rom": "300KB",
"ram": "1024KB",
"deps": {
"components": [
"ability_runtime",
"napi",
"bundle_framework",
"ipc",
"dmsfwk_standard",
"safwk",
"samgr_standard",
"multimodalinput_base",
"utils_base",
"resmgr_standard"
],
"third_party": [
"jsoncpp"
]
},
"build": {
"sub_component": [
"//base/miscservices/inputmethod:inputmethod_native_packages"
],
"inner_kits": [
{
"name": "//base/miscservices/inputmethod/services:inputmethod_service",
"header": {
"header_files": [
"global.h",
"input_attribute.h",
"input_channel.h",
"input_control_channel_proxy.h",
"input_control_channel_stub.h",
"input_method_ability_connection_stub.h",
"input_method_property.h",
"input_method_setting.h",
"input_method_system_ability.h",
"input_method_system_ability_stub.h",
"keyboard_type.h",
"message.h",
"message_handler.h",
"peruser_session.h",
"peruser_setting.h",
"platform.h",
"platform_callback_stub.h"
],
"header_base": "//base/miscservices/inputmethod/services/include"
}
},
{
"name": "//base/miscservices/inputmethod/frameworks/inputmethod_controller:inputmethod_client",
"header": {
"header_files": [
"i_input_client.h",
"i_input_data_channel.h",
"input_client_proxy.h",
"input_client_stub.h",
"input_data_channel_proxy.h",
"input_data_channel_stub.h",
"input_method_controller.h",
"input_method_system_ability_proxy.h",
"input_method_utils.h"
],
"header_base": "//base/miscservices/inputmethod/frameworks/inputmethod_controller/include"
}
},
{
"name": "//base/miscservices/inputmethod/frameworks/inputmethod_ability:inputmethod_ability",
"header": {
"header_files": [
"i_input_method_agent.h",
"i_input_method_core.h",
"input_method_ability.h",
"input_method_agent_proxy.h",
"input_method_agent_stub.h",
"input_method_core_proxy.h",
"input_method_core_stub.h"
],
"header_base": "//base/miscservices/inputmethod/frameworks/inputmethod_ability/include"
}
},
{
"name": "//base/miscservices/inputmethod/interfaces/kits/js/napi:inputmethodengine",
"header": {
"header_files": [
"js_input_method_engine.h",
"js_input_method_engine_listener.h"
],
"header_base": "//base/miscservices/inputmethod/interfaces/kits/js/napi/include"
}
}
],
"test": [
"//base/miscservices/inputmethod/unitest:InputMethodControllerTest",
"//base/miscservices/inputmethod/unitest:InputMethodAbilityTest"
]
}
}
}

View File

@ -18,17 +18,31 @@ config("inputmethod_ability_native_config") {
include_dirs = [
"include",
"${inputmethod_path}/frameworks/inputmethod_controller/include",
"${inputmethod_path}/interfaces/kits/js/napi/include",
"${inputmethod_path}/services/include",
]
}
config("inputmethod_ability_native_public_config") {
visibility = []
include_dirs = [ "include" ]
include_dirs = [
"include",
"${inputmethod_path}/services/include",
]
}
ohos_shared_library("inputmethod_ability") {
sources = [
"${inputmethod_path}/frameworks/inputmethod_controller/src/input_data_channel_proxy.cpp",
"${inputmethod_path}/interfaces/kits/js/napi/src/js_input_method_engine.cpp",
"${inputmethod_path}/interfaces/kits/js/napi/src/js_input_method_engine_listener.cpp",
"${inputmethod_path}/services/src/input_attribute.cpp",
"${inputmethod_path}/services/src/input_channel.cpp",
"${inputmethod_path}/services/src/input_control_channel_proxy.cpp",
"${inputmethod_path}/services/src/input_method_property.cpp",
"${inputmethod_path}/services/src/keyboard_type.cpp",
"${inputmethod_path}/services/src/message.cpp",
"${inputmethod_path}/services/src/message_handler.cpp",
"../inputmethod_controller/src/input_method_system_ability_proxy.cpp",
"src/event_target.cpp",
"src/input_method_ability.cpp",
"src/input_method_agent_proxy.cpp",
"src/input_method_agent_stub.cpp",
@ -40,8 +54,6 @@ ohos_shared_library("inputmethod_ability") {
deps = [
"//base/global/resmgr_standard/frameworks/resmgr:global_resmgr",
"//base/miscservices/inputmethod/services:inputmethod_service",
"//foundation/aafwk/standard/frameworks/kits/ability/native:abilitykit_native",
"//foundation/aafwk/standard/interfaces/innerkits/ability_manager:ability_manager",
"//foundation/aafwk/standard/interfaces/innerkits/app_manager:app_manager",
"//foundation/aafwk/standard/interfaces/innerkits/base:base",
@ -59,9 +71,12 @@ ohos_shared_library("inputmethod_ability") {
"//utils/native/base:utils",
]
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
external_deps = [
"ability_runtime:runtime",
"hiviewdfx_hilog_native:libhilog",
]
public_configs = [ ":inputmethod_ability_native_config" ]
public_configs = [ ":inputmethod_ability_native_public_config" ]
subsystem_name = "miscservices"
part_name = "inputmethod_native"

View File

@ -1,98 +0,0 @@
/*
* 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.
*/
#ifndef INPUT_METHOD_NAPI_EVENT_TARGET_H
#define INPUT_METHOD_NAPI_EVENT_TARGET_H
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "global.h"
#include "input_method_ability.h"
namespace OHOS {
namespace MiscServices {
struct EventListener;
class Event {
public:
virtual napi_value ToJsObject() = 0;
};
class NapiKeyEvent : public Event {
public:
NapiKeyEvent(napi_env env, int32_t key, int32_t status);
~NapiKeyEvent();
napi_value ToJsObject() override;
private:
napi_env keyEev;
int32_t key_;
int32_t status_;
};
class NapiCursorChange : public Event {
public:
NapiCursorChange(napi_env env, int32_t px, int32_t py, int32_t height);
~NapiCursorChange();
napi_value ToJsObject() override;
private:
napi_env env_;
int32_t px_;
int32_t py_;
int32_t height_;
};
class NapiSelectionChange : public Event {
public:
NapiSelectionChange(napi_env env, int32_t oldBegin, int32_t oldEnd, int32_t newBegin, int32_t newEnd);
~NapiSelectionChange();
napi_value ToJsObject() override;
private:
napi_env env_;
int32_t oldBegin_;
int32_t oldEnd_;
int32_t newBegin_;
int32_t newEnd_;
};
class NapiTextChange : public Event {
public:
NapiTextChange(napi_env env, std::u16string text);
~NapiTextChange();
napi_value ToJsObject() override;
private:
napi_env env_;
std::u16string text_;
};
class EventTarget : public RefBase {
public:
EventTarget(napi_env env, napi_value thisVar);
virtual ~EventTarget();
virtual void On(const char *type, napi_value handler);
virtual void Once(const char *type, napi_value handler);
virtual void Off(const char *type, napi_value handler);
virtual void Off(const char *type);
virtual void Emit(sptr<EventTarget> &eventTarget, const char *type, Event *event);
virtual napi_env GetEnv();
private:
napi_env env_;
napi_ref thisVarRef_;
EventListener *first_;
EventListener *last_;
};
}
}
#endif // INPUT_METHOD_NAPI_EVENT_TARGET_H

View File

@ -28,14 +28,14 @@ namespace MiscServices {
class IInputMethodAgent : public IRemoteBroker {
public:
enum {
DISPATCH_KEY = FIRST_CALL_TRANSACTION,
DISPATCH_KEY_EVENT = FIRST_CALL_TRANSACTION,
ON_CURSOR_UPDATE,
ON_SELECTION_CHANGE,
};
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.inputmethod.IInputMethodAgent");
virtual int32_t DispatchKey(int32_t key, int32_t status) = 0;
virtual bool DispatchKeyEvent(MessageParcel& data) = 0;
virtual void OnCursorUpdate(int32_t positionX, int32_t positionY, int height) = 0;
virtual void OnSelectionChange(std::u16string text, int32_t oldBegin, int32_t oldEnd,
int32_t newBegin, int32_t newEnd) = 0;

View File

@ -40,6 +40,7 @@ namespace MiscServices {
HIDE_KEYBOARD,
SET_KEYBOARD_TYPE,
GET_KEYBOARD_WINDOW_HEIGHT,
INIT_INPUT_CONTROL_CHANNEL
};
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.inputmethod.IInputMethodCore");
@ -50,10 +51,11 @@ namespace MiscServices {
const InputAttribute& editorAttribute,
bool supportPhysicalKbd) = 0;
virtual int32_t stopInput() = 0;
virtual bool showKeyboard(int32_t flags) = 0;
virtual bool showKeyboard(const sptr<IInputDataChannel>& inputDataChannel) = 0;
virtual bool hideKeyboard(int32_t flags) = 0;
virtual int32_t setKeyboardType(const KeyboardType& type) = 0;
virtual int32_t getKeyboardWindowHeight(int32_t retHeight) = 0;
virtual int32_t InitInputControlChannel(sptr<IInputControlChannel> &inputControlChannel) = 0;
};
}
}

View File

@ -17,6 +17,7 @@
#define FM_IMMS_PROJECT_INPUTMETHODABILITY_H
#include <thread>
#include "js_input_method_engine_listener.h"
#include "iremote_object.h"
#include "i_input_control_channel.h"
#include "i_input_method_core.h"
@ -33,7 +34,8 @@
namespace OHOS {
namespace MiscServices {
class EventTarget;
class JsInputMethodEngineListener;
class MessageHandler;
class InputMethodAbility : public RefBase {
public:
InputMethodAbility();
@ -41,7 +43,7 @@ namespace MiscServices {
static sptr<InputMethodAbility> GetInstance();
sptr<IInputMethodCore> OnConnect();
bool InsertText(const std::string text);
void setEventTarget(sptr<EventTarget> &eventTarget);
void setImeListener(sptr<JsInputMethodEngineListener> &imeListener);
void DeleteForward(int32_t length);
void DeleteBackward(int32_t length);
void HideKeyboardSelf();
@ -49,6 +51,7 @@ namespace MiscServices {
std::u16string GetTextAfterCursor();
void SendFunctionKey(int32_t funcKey);
void MoveCursor(int32_t keyCode);
bool DispatchKeyEvent(int32_t keyCode, int32_t keyStatus);
private:
std::thread workThreadHandler;
@ -64,11 +67,11 @@ namespace MiscServices {
// communicating with IMSA
sptr<IInputControlChannel> inputControlChannel;
void SetCoreAndAgent();
// communicating with IMC
sptr<IInputDataChannel> inputDataChannel;
sptr<IInputMethodAgent> inputMethodAgent;
sptr<EventTarget> eventTarget_;
sptr<JsInputMethodEngineListener> imeListener_;
static std::mutex instanceLock_;
static sptr<InputMethodAbility> instance_;
sptr<InputMethodSystemAbilityProxy> mImms;
@ -76,7 +79,6 @@ namespace MiscServices {
void Initialize();
void WorkThread();
void CreateInputMethodAgent(bool supportPhysicalKbd);
// the message from IMSA
void OnInitialInput(Message *msg);
@ -85,9 +87,9 @@ namespace MiscServices {
void OnSetKeyboardType(Message *msg);
void OnShowKeyboard(Message *msg);
void OnHideKeyboard(Message *msg);
void OnInitInputControlChannel(Message *msg);
// the message from IMC
bool DispatchKey(Message *msg);
void OnCursorUpdate(Message *msg);
void OnSelectionChange(Message *msg);

View File

@ -27,7 +27,7 @@ namespace MiscServices {
~InputMethodAgentProxy() = default;
DISALLOW_COPY_AND_MOVE(InputMethodAgentProxy);
int32_t DispatchKey(int32_t key, int32_t status) override;
bool DispatchKeyEvent(MessageParcel& data) override;
void OnCursorUpdate(int32_t positionX, int32_t positionY, int32_t height) override;
void OnSelectionChange(std::u16string text, int32_t oldBegin, int32_t oldEnd,
int32_t newBegin, int32_t newEnd) override;

View File

@ -32,7 +32,7 @@ namespace MiscServices {
MessageParcel &data,
MessageParcel &reply,
MessageOption &option) override;
virtual int32_t DispatchKey(int32_t key, int32_t status) override;
virtual bool DispatchKeyEvent(MessageParcel &data) override;
virtual void OnCursorUpdate(int32_t positionX, int32_t positionY, int height) override;
virtual void OnSelectionChange(std::u16string text, int32_t oldBegin, int32_t oldEnd,
int32_t newBegin, int32_t newEnd) override;

View File

@ -40,10 +40,11 @@ namespace MiscServices {
const InputAttribute& editorAttribute,
bool supportPhysicalKbd) override;
virtual int32_t stopInput() override;
virtual bool showKeyboard(int32_t flags) override;
virtual bool showKeyboard(const sptr<IInputDataChannel>& inputDataChannel) override;
virtual bool hideKeyboard(int32_t flags) override;
virtual int32_t setKeyboardType(const KeyboardType& type) override;
virtual int32_t getKeyboardWindowHeight(int32_t retHeight) override;
virtual int32_t InitInputControlChannel(sptr<IInputControlChannel> &inputControlChannel) override;
private:
static inline BrokerDelegator<InputMethodCoreProxy> delegator_;

View File

@ -49,10 +49,11 @@ namespace MiscServices {
const InputAttribute& editorAttribute,
bool supportPhysicalKbd) override;
virtual int32_t stopInput() override;
virtual bool showKeyboard(int32_t flags) override;
virtual bool showKeyboard(const sptr<IInputDataChannel>& inputDataChannel) override;
virtual bool hideKeyboard(int32_t flags)override;
virtual int32_t setKeyboardType(const KeyboardType& type) override;
virtual int32_t getKeyboardWindowHeight(int32_t retHeight) override;
virtual int32_t InitInputControlChannel(sptr<IInputControlChannel> &inputControlChannel) override;
void SetMessageHandler(MessageHandler *msgHandler);
private:

View File

@ -1,434 +0,0 @@
/*
* 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 "event_target.h"
#include <uv.h>
#include "utils/log.h"
#include "input_method_ability.h"
#include "securec.h"
#include "string_ex.h"
#define LISTENER_TYPTE_MAX_LENGTH 64
namespace OHOS {
namespace MiscServices {
struct EventListener {
char type[LISTENER_TYPTE_MAX_LENGTH] = { 0 };
bool isOnce = false;
napi_ref handlerRef = nullptr;
EventListener *back = nullptr;
EventListener *next = nullptr;
};
struct EventTargetCB {
napi_env env;
napi_ref thisVarRef;
EventListener *first;
EventListener *last;
sptr<EventTarget> &eventTarget;
const char *type;
Event *event;
};
NapiKeyEvent::NapiKeyEvent(napi_env env, int32_t key, int32_t status)
{
keyEev = env;
key_ = key;
status_ = status;
}
NapiKeyEvent::~NapiKeyEvent()
{
}
napi_value NapiKeyEvent::ToJsObject()
{
napi_value object = nullptr;
napi_status status = napi_generic_failure;
status = napi_create_object(keyEev, &object);
if (status != napi_ok) {
napi_throw_type_error(keyEev, nullptr,
"NapiKeyEvent Throw Error:ToJsObject create object failed");
return nullptr;
}
napi_value intVal;
napi_create_int32(keyEev, key_, &intVal);
status = napi_set_named_property(keyEev, object, "keyCode", intVal);
if (status != napi_ok) {
napi_throw_type_error(keyEev, nullptr,
"NapiKeyEvent Throw Error:ToJsObject set named property failed");
return nullptr;
}
napi_create_int32(keyEev, status_, &intVal);
status = napi_set_named_property(keyEev, object, "keyAction", intVal);
if (status != napi_ok) {
napi_throw_type_error(keyEev, nullptr,
"NapiKeyEvent Throw Error:ToJsObject set named property failed");
return nullptr;
}
return object;
}
NapiCursorChange::NapiCursorChange(napi_env env, int32_t px, int32_t py, int32_t height)
{
env_ = env;
px_ = px;
py_ = py;
height_ = height;
}
NapiCursorChange::~NapiCursorChange()
{
}
napi_value NapiCursorChange::ToJsObject()
{
napi_value object = nullptr;
napi_status status = napi_generic_failure;
status = napi_create_object(env_, &object);
if (status != napi_ok) {
napi_throw_type_error(env_, nullptr,
"NapiCursorChange Throw Error:ToJsObject create object failed");
return nullptr;
}
napi_value intVal;
napi_create_int32(env_, px_, &intVal);
status = napi_set_named_property(env_, object, "x", intVal);
if (status != napi_ok) {
napi_throw_type_error(env_, nullptr,
"NapiCursorChange Throw Error:ToJsObject set named property failed");
return nullptr;
}
napi_create_int32(env_, py_, &intVal);
status = napi_set_named_property(env_, object, "y", intVal);
if (status != napi_ok) {
napi_throw_type_error(env_, nullptr,
"NapiCursorChange Throw Error:ToJsObject set named property failed");
return nullptr;
}
napi_create_int32(env_, height_, &intVal);
status = napi_set_named_property(env_, object, "height", intVal);
if (status != napi_ok) {
napi_throw_type_error(env_, nullptr,
"NapiCursorChange Throw Error:ToJsObject set named property failed");
return nullptr;
}
return object;
}
NapiSelectionChange::NapiSelectionChange(napi_env env, int32_t oldBegin, int32_t oldEnd,
int32_t newBegin, int32_t newEnd)
{
env_ = env;
oldBegin_ = oldBegin;
oldEnd_ = oldEnd;
newBegin_ = newBegin;
newEnd_ = newEnd;
}
NapiSelectionChange::~NapiSelectionChange()
{
}
napi_value NapiSelectionChange::ToJsObject()
{
napi_value object = nullptr;
napi_status status = napi_generic_failure;
status = napi_create_object(env_, &object);
if (status != napi_ok) {
napi_throw_type_error(env_, nullptr,
"NapiSelectionChange Throw Error:ToJsObject create object failed");
return nullptr;
}
napi_value intVal;
napi_create_int32(env_, oldBegin_, &intVal);
status = napi_set_named_property(env_, object, "oldBegin", intVal);
if (status != napi_ok) {
napi_throw_type_error(env_, nullptr,
"NapiSelectionChange Throw Error:ToJsObject set named property failed");
return nullptr;
}
napi_create_int32(env_, oldEnd_, &intVal);
status = napi_set_named_property(env_, object, "oldEnd", intVal);
if (status != napi_ok) {
napi_throw_type_error(env_, nullptr,
"NapiSelectionChange Throw Error:ToJsObject set named property failed");
return nullptr;
}
napi_create_int32(env_, newBegin_, &intVal);
status = napi_set_named_property(env_, object, "newBegin", intVal);
if (status != napi_ok) {
napi_throw_type_error(env_, nullptr,
"NapiCursorChange Throw Error:ToJsObject set named property failed");
return nullptr;
}
napi_create_int32(env_, newEnd_, &intVal);
status = napi_set_named_property(env_, object, "newEnd", intVal);
if (status != napi_ok) {
napi_throw_type_error(env_, nullptr,
"NapiCursorChange Throw Error:ToJsObject set named property failed");
return nullptr;
}
return object;
}
NapiTextChange::NapiTextChange(napi_env env, std::u16string text)
{
env_ = env;
text_ = text;
}
NapiTextChange::~NapiTextChange()
{
}
napi_value NapiTextChange::ToJsObject()
{
napi_value object = nullptr;
napi_status status = napi_generic_failure;
status = napi_create_object(env_, &object);
if (status != napi_ok) {
napi_throw_type_error(env_, nullptr,
"NapiTextChange Throw Error:ToJsObject create object failed");
return nullptr;
}
napi_value intVal;
std::string outString = Str16ToStr8(text_.c_str());
napi_create_string_utf8(env_, outString.c_str(), NAPI_AUTO_LENGTH, &intVal);
status = napi_set_named_property(env_, object, "text", intVal);
if (status != napi_ok) {
napi_throw_type_error(env_, nullptr,
"NapiTextChange Throw Error:ToJsObject set named property failed");
return nullptr;
}
return object;
}
EventTarget::EventTarget(napi_env env, napi_value thisVar)
{
IMSA_HILOGI("EventTarget::EventTarget");
env_ = env;
first_ = last_ = nullptr;
thisVarRef_ = nullptr;
napi_create_reference(env, thisVar, 1, &thisVarRef_);
}
EventTarget::~EventTarget()
{
EventListener *temp = nullptr;
for (EventListener *i = first_; i != nullptr; i = temp) {
temp = i->next;
if (i == first_) {
first_ = first_->next;
} else if (i == last_) {
last_ = last_->back;
} else {
i->next->back = i->back;
i->back->next = i->next;
}
napi_delete_reference(env_, i->handlerRef);
delete i;
i = nullptr;
}
napi_delete_reference(env_, thisVarRef_);
}
void EventTarget::On(const char *type, napi_value handler)
{
IMSA_HILOGI("EventTarget::On");
auto tmp = new EventListener();
if (strncpy_s(tmp->type, LISTENER_TYPTE_MAX_LENGTH, type, strlen(type)) == -1) {
delete tmp;
tmp = nullptr;
return;
}
if (first_ == nullptr) {
first_ = last_ = tmp;
} else {
last_->next = tmp;
last_->next->back = last_;
last_ = last_->next;
}
last_->isOnce = false;
napi_create_reference(env_, handler, 1, &last_->handlerRef);
}
void EventTarget::Once(const char *type, napi_value handler)
{
IMSA_HILOGI("EventTarget::Once");
auto tmp = new EventListener();
if (strncpy_s(tmp->type, LISTENER_TYPTE_MAX_LENGTH, type, strlen(type)) == -1) {
delete tmp;
tmp = nullptr;
return;
}
if (first_ == nullptr) {
first_ = last_ = tmp;
} else {
last_->next = tmp;
last_->next->back = last_;
last_ = last_->next;
}
last_->isOnce = true;
napi_create_reference(env_, handler, 1, &last_->handlerRef);
}
void EventTarget::Off(const char *type, napi_value handler)
{
IMSA_HILOGI("EventTarget::Off");
napi_handle_scope scope = nullptr;
napi_open_handle_scope(env_, &scope);
if (scope == nullptr) {
HILOG_ERROR("scope is nullptr");
return;
}
EventListener *temp = nullptr;
for (EventListener *eventListener = first_; eventListener != nullptr; eventListener = temp) {
temp = eventListener->next;
bool isEquals = false;
napi_value handlerTemp = nullptr;
napi_get_reference_value(env_, eventListener->handlerRef, &handlerTemp);
napi_strict_equals(env_, handlerTemp, handler, &isEquals);
if (strcmp(eventListener->type, type) == 0 && isEquals) {
if (eventListener == first_) {
first_ = first_->next;
} else if (eventListener == last_) {
last_ = last_->back;
} else {
eventListener->next->back = eventListener->back;
eventListener->back->next = eventListener->next;
}
napi_delete_reference(env_, eventListener->handlerRef);
delete eventListener;
eventListener = nullptr;
break;
}
}
napi_close_handle_scope(env_, scope);
}
void EventTarget::Off(const char *type)
{
IMSA_HILOGI("EventTarget::Off");
EventListener *temp = nullptr;
for (EventListener *eventListener = first_; eventListener != nullptr; eventListener = temp) {
temp = eventListener->next;
if (strcmp(eventListener->type, type) == 0) {
if (eventListener == first_) {
first_ = first_->next;
} else if (eventListener == last_) {
last_ = last_->back;
} else {
eventListener->next->back = eventListener->back;
eventListener->back->next = eventListener->next;
}
napi_delete_reference(env_, eventListener->handlerRef);
delete eventListener;
eventListener = nullptr;
}
}
}
void EventTarget::Emit(sptr<EventTarget> &eventTarget, const char *type, Event *event)
{
IMSA_HILOGI("EventTarget::Emit");
uv_loop_s *loop = nullptr;
napi_get_uv_event_loop(env_, &loop);
if (loop == nullptr) {
IMSA_HILOGI("EventTarget::Emit loop == nullptr");
return;
}
uv_work_t *work = new (std::nothrow) uv_work_t;
if (work == nullptr) {
IMSA_HILOGI("EventTarget::Emit No memory work == nullptr");
return;
}
EventTargetCB *eventTargetCB = new (std::nothrow) EventTargetCB {.env = env_, .thisVarRef = thisVarRef_,
.first = first_, .last = last_, .type = type, .event = event, .eventTarget = eventTarget};
work->data = (void *)eventTargetCB;
int ret = uv_queue_work(loop, work, [](uv_work_t *work) {}, [](uv_work_t *work, int status) {
// Js Thread
if (work == nullptr) {
IMSA_HILOGI("EventTarget::Emit work == nullptr");
return;
}
EventTargetCB *eventTargetCB = (EventTargetCB *)work->data;
do {
napi_handle_scope scope = nullptr;
napi_open_handle_scope(eventTargetCB->env, &scope);
napi_value thisVar = nullptr;
napi_get_reference_value(eventTargetCB->env, eventTargetCB->thisVarRef, &thisVar);
for (EventListener *eventListener = eventTargetCB->first; eventListener != nullptr;
eventListener = eventListener->next) {
if (strcmp(eventListener->type, eventTargetCB->type) == 0) {
napi_value jsEvent = eventTargetCB->event ? eventTargetCB->event->ToJsObject() : nullptr;
napi_value handler = nullptr;
napi_value result = nullptr;
napi_get_reference_value(eventTargetCB->env, eventListener->handlerRef, &handler);
napi_call_function(eventTargetCB->env, thisVar, handler,
jsEvent ? 1 : 0, jsEvent ? &jsEvent : nullptr, &result);
if (eventListener->isOnce) {
eventTargetCB->eventTarget->Off(eventTargetCB->type, handler);
}
}
}
napi_close_handle_scope(eventTargetCB->env, scope);
} while (0);
if (eventTargetCB) {
delete eventTargetCB;
}
delete work;
});
if (ret != 0) {
IMSA_HILOGI("EventTarget::Emit failed to execute libuv work queue");
delete work;
}
}
napi_env EventTarget::GetEnv()
{
return env_;
}
}
}

View File

@ -17,7 +17,6 @@
#include "input_method_agent_proxy.h"
#include "input_method_agent_stub.h"
#include "message_parcel.h"
#include "event_target.h"
#include "system_ability_definition.h"
#include "input_data_channel_proxy.h"
#include "input_method_utils.h"
@ -27,6 +26,7 @@
namespace OHOS {
namespace MiscServices {
class MessageHandler;
using namespace MessageID;
sptr<InputMethodAbility> InputMethodAbility::instance_;
std::mutex InputMethodAbility::instanceLock_;
@ -35,7 +35,6 @@ namespace MiscServices {
{
writeInputChannel = nullptr;
Initialize();
OnConnect();
}
InputMethodAbility::~InputMethodAbility()
@ -82,35 +81,48 @@ namespace MiscServices {
return iface;
}
sptr<IInputMethodCore> InputMethodAbility::OnConnect()
void InputMethodAbility::SetCoreAndAgent()
{
IMSA_HILOGI("InputMethodAbility::OnConnect");
IMSA_HILOGI("InputMethodAbility::SetCoreAndAgent");
mImms = GetImsaProxy();
if (mImms == nullptr) {
IMSA_HILOGI("InputMethodAbility::SetCoreAndAgent() mImms is nullptr");
return;
}
sptr<InputMethodCoreStub> stub = new InputMethodCoreStub(0);
stub->SetMessageHandler(msgHandler);
sptr<IInputMethodCore> stub2 = stub;
if (mImms != nullptr) {
mImms->setInputMethodCore(stub2);
} else {
IMSA_HILOGI("InputMethodAbility::OnConnect() mImms is nullptr");
sptr<InputMethodAgentStub> inputMethodAgentStub(new InputMethodAgentStub());
inputMethodAgentStub->SetMessageHandler(msgHandler);
sptr<IInputMethodAgent> inputMethodAgent = sptr(new InputMethodAgentProxy(inputMethodAgentStub));
MessageParcel data;
if (!(data.WriteInterfaceToken(mImms->GetDescriptor())
&& data.WriteRemoteObject(stub2->AsObject())
&& data.WriteRemoteObject(inputMethodAgent->AsObject()))) {
return;
}
return nullptr;
mImms->SetCoreAndAgent(data);
}
void InputMethodAbility::Initialize()
{
IMSA_HILOGI("InputMethodAbility::Initialize");
InitialInputWindow();
msgHandler = new MessageHandler();
workThreadHandler = std::thread([this] {
WorkThread();
});
SetCoreAndAgent();
}
void InputMethodAbility::setEventTarget(sptr<EventTarget> &eventTarget)
void InputMethodAbility::setImeListener(sptr<JsInputMethodEngineListener> &imeListener)
{
IMSA_HILOGI("InputMethodAbility::setEventTarget");
eventTarget_ = eventTarget;
IMSA_HILOGI("InputMethodAbility::setImeListener");
if (imeListener_ == nullptr) {
imeListener_ = imeListener;
}
}
void InputMethodAbility::WorkThread()
@ -122,31 +134,26 @@ namespace MiscServices {
OnInitialInput(msg);
break;
}
case MSG_ID_INIT_INPUT_CONTROL_CHANNEL: {
OnInitInputControlChannel(msg);
break;
}
case MSG_ID_START_INPUT: {
OnStartInput(msg);
break;
}
case MSG_ID_STOP_INPUT: {
OnStopInput(msg);
break;
}
case MSG_ID_SHOW_KEYBOARD: {
OnShowKeyboard(msg);
break;
}
case MSG_ID_HIDE_KEYBOARD: {
OnHideKeyboard(msg);
break;
}
case MSG_ID_DISPATCH_KEY: {
DispatchKey(msg);
break;
}
case MSG_ID_ON_CURSOR_UPDATE: {
OnCursorUpdate(msg);
break;
@ -180,7 +187,22 @@ namespace MiscServices {
IMSA_HILOGI("InputMethodAbility::OnInitialInput inputControlChannel is nullptr");
return;
}
InitialInputWindow();
}
void InputMethodAbility::OnInitInputControlChannel(Message *msg)
{
IMSA_HILOGI("InputMethodAbility::OnInitInputControlChannel");
MessageParcel *data = msg->msgContent_;
sptr<IRemoteObject> channelObject = data->ReadRemoteObject();
if (channelObject == nullptr) {
IMSA_HILOGI("InputMethodAbility::OnInitInputControlChannel channelObject is nullptr");
return;
}
sptr<InputControlChannelProxy> channelProxy = new InputControlChannelProxy(channelObject);
inputControlChannel = channelProxy;
if (inputControlChannel == nullptr) {
IMSA_HILOGI("InputMethodAbility::OnInitInputControlChannel inputControlChannel is nullptr");
}
}
void InputMethodAbility::OnStartInput(Message *msg)
@ -197,17 +219,17 @@ namespace MiscServices {
IMSA_HILOGI("InputMethodAbility::OnStartInput editorAttribute is nullptr");
}
mSupportPhysicalKbd = data->ReadBool();
CreateInputMethodAgent(mSupportPhysicalKbd);
if (inputControlChannel != nullptr) {
IMSA_HILOGI("InputMethodAbility::OnStartInput inputControlChannel is not nullptr");
inputControlChannel->onAgentCreated(inputMethodAgent, nullptr);
}
}
void InputMethodAbility::OnShowKeyboard(Message *msg)
{
IMSA_HILOGI("InputMethodAbility::OnShowKeyboard");
MessageParcel *data = msg->msgContent_;
sptr<InputDataChannelProxy> channalProxy = new InputDataChannelProxy(data->ReadRemoteObject());
inputDataChannel = channalProxy;
if (inputDataChannel == nullptr) {
IMSA_HILOGI("InputMethodAbility::OnShowKeyboard inputDataChannel is nullptr");
}
ShowInputWindow();
}
@ -226,71 +248,27 @@ namespace MiscServices {
}
}
bool InputMethodAbility::DispatchKey(Message *msg)
bool InputMethodAbility::DispatchKeyEvent(int32_t keyCode, int32_t keyStatus)
{
IMSA_HILOGI("InputMethodAbility::DispatchKey");
MessageParcel *data = msg->msgContent_;
int32_t key = data->ReadInt32();
int32_t status = data->ReadInt32();
IMSA_HILOGI("InputMethodAbility::DispatchKey: key = %{public}d, status = %{public}d", key, status);
napi_env env = eventTarget_->GetEnv();
MiscServices::NapiKeyEvent *napiKeyEvent = new MiscServices::NapiKeyEvent(env, key, status);
eventTarget_->Emit(eventTarget_, "keyDown", napiKeyEvent);
return true;
IMSA_HILOGI("InputMethodAbility::DispatchKeyEvent");
IMSA_HILOGI("InputMethodAbility::DispatchKeyEvent: key = %{public}d, status = %{public}d", keyCode, keyStatus);
return imeListener_->OnKeyEvent(keyCode, keyStatus);
}
void InputMethodAbility::OnCursorUpdate(Message *msg)
{
IMSA_HILOGI("InputMethodAbility::OnCursorUpdate");
MessageParcel *data = msg->msgContent_;
int32_t positionX = data->ReadInt32();
int32_t positionY = data->ReadInt32();
int32_t height = data->ReadInt32();
napi_env env = eventTarget_->GetEnv();
MiscServices::NapiCursorChange *napiCursorChange = new MiscServices::NapiCursorChange(env, positionX,
positionY, height);
eventTarget_->Emit(eventTarget_, "cursorContextChange", napiCursorChange);
}
void InputMethodAbility::OnSelectionChange(Message *msg)
{
IMSA_HILOGI("InputMethodAbility::OnSelectionChange");
MessageParcel *data = msg->msgContent_;
const std::u16string text = data->ReadString16();
int32_t oldBegin = data->ReadInt32();
int32_t oldEnd = data->ReadInt32();
int32_t newBegin = data->ReadInt32();
int32_t newEnd = data->ReadInt32();
napi_env env = eventTarget_->GetEnv();
MiscServices::NapiTextChange *napiTextChange = new MiscServices::NapiTextChange(env, text);
eventTarget_->Emit(eventTarget_, "textChange", napiTextChange);
MiscServices::NapiSelectionChange *napiSelectionChange = new MiscServices::NapiSelectionChange(env, oldBegin,
oldEnd, newBegin, newEnd);
eventTarget_->Emit(eventTarget_, "selectionChange", napiSelectionChange);
}
void InputMethodAbility::CreateInputMethodAgent(bool supportPhysicalKbd)
{
IMSA_HILOGI("InputMethodAbility::CreateInputMethodAgent");
sptr<InputMethodAgentStub> inputMethodAgentStub(new InputMethodAgentStub());
inputMethodAgentStub->SetMessageHandler(msgHandler);
inputMethodAgent = sptr(new InputMethodAgentProxy(inputMethodAgentStub));
}
void InputMethodAbility::InitialInputWindow()
{
IMSA_HILOGI("InputMethodAbility::InitialInputWindow");
}
void InputMethodAbility::ShowInputWindow()
{
IMSA_HILOGI("InputMethodAbility::ShowInputWindow");
eventTarget_->Emit(eventTarget_, "keyboardShow", nullptr);
imeListener_->OnKeyboardStatus(true);
if (inputDataChannel != nullptr) {
inputDataChannel->SendKeyboardStatus(KEYBOARD_SHOW);
}
@ -299,7 +277,7 @@ namespace MiscServices {
void InputMethodAbility::DissmissInputWindow()
{
IMSA_HILOGI("InputMethodAbility::DissmissInputWindow");
eventTarget_->Emit(eventTarget_, "keyboardHide", nullptr);
imeListener_->OnKeyboardStatus(false);
if (inputDataChannel != nullptr) {
inputDataChannel->SendKeyboardStatus(KEYBOARD_HIDE);
}

View File

@ -23,20 +23,17 @@ namespace MiscServices {
{
}
int32_t InputMethodAgentProxy::DispatchKey(int32_t key, int32_t status)
bool InputMethodAgentProxy::DispatchKeyEvent(MessageParcel& data)
{
IMSA_HILOGI("InputMethodAgentProxy::DispatchKey key = %{public}d, status = %{public}d", key, status);
MessageParcel data, reply;
IMSA_HILOGI("InputMethodAgentProxy::DispatchKeyEvent");
MessageParcel reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
IMSA_HILOGI("InputMethodAgentProxy::DispatchKey descriptor is not match");
return ERROR_EX_PARCELABLE;
auto ret = Remote()->SendRequest(DISPATCH_KEY_EVENT, data, reply, option);
if (ret != NO_ERROR) {
IMSA_HILOGI("InputMethodAgentProxy::DispatchKeyEvent SendRequest failed");
}
data.WriteInt32(key);
data.WriteInt32(status);
auto ret = Remote()->SendRequest(DISPATCH_KEY, data, reply, option);
ret = reply.ReadBool();
return ret;
}

View File

@ -17,6 +17,7 @@
#include "global.h"
#include "message_handler.h"
#include "message.h"
#include "input_method_ability.h"
namespace OHOS {
namespace MiscServices {
@ -41,16 +42,10 @@ namespace MiscServices {
}
switch (code) {
case DISPATCH_KEY: {
int32_t key = data.ReadInt32();
int32_t status = data.ReadInt32();
int32_t result = DispatchKey(key, status);
if (result == ErrorCode::NO_ERROR) {
reply.WriteNoException();
} else {
reply.WriteInt32(result);
}
return result;
case DISPATCH_KEY_EVENT: {
MessageParcel *msgParcel = (MessageParcel*) &data;
reply.WriteBool(DispatchKeyEvent(*msgParcel));
break;
}
case ON_CURSOR_UPDATE: {
int32_t positionX = data.ReadInt32();
@ -77,18 +72,13 @@ namespace MiscServices {
return ErrorCode::NO_ERROR;
}
int32_t InputMethodAgentStub::DispatchKey(int32_t key, int32_t status)
bool InputMethodAgentStub::DispatchKeyEvent(MessageParcel& data)
{
IMSA_HILOGI("InputMethodAgentStub::DispatchKey key = %{public}d, status = %{public}d", key, status);
IMSA_HILOGI("InputMethodAgentStub::DispatchKeyEvent");
if (msgHandler_ == nullptr) {
return ErrorCode::ERROR_NULL_POINTER;
return false;
}
MessageParcel *data = new MessageParcel();
data->WriteInt32(key);
data->WriteInt32(status);
Message *message = new Message(MessageID::MSG_ID_DISPATCH_KEY, data);
msgHandler_->SendMessage(message);
return ErrorCode::NO_ERROR;
return InputMethodAbility::GetInstance()->DispatchKeyEvent(data.ReadInt32(), data.ReadInt32());
}
void InputMethodAgentStub::OnCursorUpdate(int32_t positionX, int32_t positionY, int height)

View File

@ -21,7 +21,7 @@
namespace OHOS {
namespace MiscServices {
InputMethodCoreProxy::InputMethodCoreProxy(const OHOS::sptr<OHOS::IRemoteObject> &impl)
: IRemoteProxy<IInputMethodCore>(impl)
: IRemoteProxy<IInputMethodCore>(impl)
{
}
@ -64,6 +64,32 @@ namespace MiscServices {
return code;
}
int32_t InputMethodCoreProxy::InitInputControlChannel(sptr<IInputControlChannel> &inputControlChannel)
{
IMSA_HILOGI("InputMethodCoreProxy::InitInputControlChannel");
if (inputControlChannel == nullptr) {
IMSA_HILOGI("InputMethodCoreProxy::InitInputControlChannel inputControlChannel is nullptr");
}
MessageParcel data, reply;
data.WriteInterfaceToken(GetDescriptor());
sptr<IRemoteObject> channelObject = inputControlChannel->AsObject();
if (channelObject == nullptr) {
IMSA_HILOGI("InputMethodCoreProxy::InitInputControlChannel channelObject is nullptr");
}
data.WriteRemoteObject(channelObject);
MessageOption option {
MessageOption::TF_SYNC
};
int32_t status = Remote()->SendRequest(INIT_INPUT_CONTROL_CHANNEL, data, reply, option);
if (status != ErrorCode::NO_ERROR) {
IMSA_HILOGI("InputMethodCoreProxy::InitInputControlChannel status = %{public}d", status);
return status;
}
int32_t code = reply.ReadException();
return code;
}
bool InputMethodCoreProxy::startInput(const sptr<IInputDataChannel> &inputDataChannel,
const InputAttribute& editorAttribute, bool supportPhysicalKbd)
{
@ -116,7 +142,7 @@ namespace MiscServices {
return reply.ReadInt32();
}
bool InputMethodCoreProxy::showKeyboard(int32_t flags)
bool InputMethodCoreProxy::showKeyboard(const sptr<IInputDataChannel> &inputDataChannel)
{
IMSA_HILOGI("InputMethodCoreProxy::showKeyboard");
auto remote = Remote();
@ -126,7 +152,8 @@ namespace MiscServices {
}
MessageParcel data;
if (!(data.WriteInterfaceToken(GetDescriptor()) && data.WriteInt32(flags))) {
if (!(data.WriteInterfaceToken(GetDescriptor())
&& data.WriteRemoteObject(inputDataChannel->AsObject()))) {
return false;
}
MessageParcel reply;

View File

@ -22,6 +22,7 @@
#include "platform.h"
#include "message_parcel.h"
#include "input_control_channel_proxy.h"
#include "input_method_ability.h"
namespace OHOS {
namespace MiscServices {
@ -67,6 +68,20 @@ namespace MiscServices {
reply.WriteNoException();
break;
}
case INIT_INPUT_CONTROL_CHANNEL: {
sptr<IRemoteObject> channelObject = data.ReadRemoteObject();
if (channelObject == nullptr) {
IMSA_HILOGI("InputMethodCoreStub::OnRemoteRequest channelObject is nullptr");
}
sptr<IInputControlChannel> inputControlChannel = new InputControlChannelProxy(channelObject);
if (inputControlChannel == nullptr) {
IMSA_HILOGI("InputMethodCoreStub::OnRemoteRequest inputControlChannel is nullptr");
}
InitInputControlChannel(inputControlChannel);
reply.WriteNoException();
break;
}
case START_INPUT: {
sptr<IInputDataChannel> inputDataChannel = iface_cast<IInputDataChannel>(data.ReadRemoteObject());
InputAttribute *editorAttribute = data.ReadParcelable<InputAttribute>();
@ -85,8 +100,8 @@ namespace MiscServices {
break;
}
case SHOW_KEYBOARD: {
int32_t flags = data.ReadInt32();
showKeyboard(flags);
sptr<IInputDataChannel> inputDataChannel = iface_cast<IInputDataChannel>(data.ReadRemoteObject());
showKeyboard(inputDataChannel);
reply.WriteNoException();
break;
}
@ -138,6 +153,23 @@ namespace MiscServices {
return ErrorCode::NO_ERROR;
}
int32_t InputMethodCoreStub::InitInputControlChannel(sptr<IInputControlChannel>& inputControlChannel)
{
IMSA_HILOGI("InputMethodCoreStub::initializeInput");
if (msgHandler_ == nullptr) {
return ErrorCode::ERROR_NULL_POINTER;
}
MessageParcel *data = new MessageParcel();
if (inputControlChannel != nullptr) {
IMSA_HILOGI("InputMethodCoreStub::initializeInput. inputControlChannel is not nullptr");
data->WriteRemoteObject(inputControlChannel->AsObject());
}
Message *msg = new Message(MessageID::MSG_ID_INIT_INPUT_CONTROL_CHANNEL, data);
msgHandler_->SendMessage(msg);
return ErrorCode::NO_ERROR;
}
bool InputMethodCoreStub::startInput(const sptr<IInputDataChannel>& inputDataChannel,
const InputAttribute& editorAttribute, bool supportPhysicalKbd)
{
@ -169,15 +201,17 @@ namespace MiscServices {
return ErrorCode::NO_ERROR;
}
bool InputMethodCoreStub::showKeyboard(int32_t flags)
bool InputMethodCoreStub::showKeyboard(const sptr<IInputDataChannel>& inputDataChannel)
{
IMSA_HILOGI("InputMethodCoreStub::showKeyboard");
if (msgHandler_ == nullptr) {
return false;
}
MessageParcel *data = new MessageParcel();
data->WriteInt32(userId_);
data->WriteInt32(flags);
if (inputDataChannel != nullptr) {
IMSA_HILOGI("InputMethodCoreStub::startInput inputDataChannel is not nullptr");
data->WriteRemoteObject(inputDataChannel->AsObject());
}
Message *msg = new Message(MessageID::MSG_ID_SHOW_KEYBOARD, data);
msgHandler_->SendMessage(msg);

View File

@ -18,6 +18,7 @@ config("inputmethod_client_native_config") {
include_dirs = [
"include",
"//utils/native/base/include",
"${inputmethod_path}/services/include",
]
}
@ -37,9 +38,7 @@ config("inputmethod_client_native_public_config") {
ohos_shared_library("inputmethod_client") {
sources = [
"${inputmethod_path}/frameworks/inputmethod_ability/src/input_method_agent_proxy.cpp",
"${inputmethod_path}/services/src/global.cpp",
"${inputmethod_path}/services/src/input_attribute.cpp",
"${inputmethod_path}/services/src/input_channel.cpp",
"${inputmethod_path}/services/src/input_method_property.cpp",
"${inputmethod_path}/services/src/keyboard_type.cpp",
"${inputmethod_path}/services/src/message.cpp",

View File

@ -37,8 +37,7 @@ namespace MiscServices {
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.inputmethod.InputClient");
virtual int32_t onInputReady(int32_t retValue, const sptr<IInputMethodAgent>& agent,
const InputChannel *channel) = 0;
virtual int32_t onInputReady(const sptr<IInputMethodAgent>& agent) = 0;
virtual int32_t onInputReleased(int32_t retValue) = 0;
virtual int32_t setDisplayMode(int32_t mode) = 0;
};

View File

@ -22,13 +22,13 @@
namespace OHOS {
namespace MiscServices {
class InputClientProxy : public IRemoteProxy<IInputClient> {
class InputClientProxy : public IRemoteProxy<IInputClient> {
public:
explicit InputClientProxy(const sptr<IRemoteObject> &object);
~InputClientProxy() = default;
DISALLOW_COPY_AND_MOVE(InputClientProxy);
int32_t onInputReady(int32_t retValue, const sptr<IInputMethodAgent>& agent, const InputChannel *channel) override;
int32_t onInputReady(const sptr<IInputMethodAgent>& agent) override;
int32_t onInputReleased(int32_t retValue) override;
int32_t setDisplayMode(int32_t mode) override;

View File

@ -20,6 +20,7 @@
#include "iremote_stub.h"
#include "i_input_client.h"
#include "message_handler.h"
#include "message.h"
namespace OHOS {
namespace MiscServices {
@ -32,8 +33,7 @@ namespace MiscServices {
~InputClientStub();
void SetHandler(MessageHandler *handler);
int32_t onInputReady(int32_t retValue, const sptr<IInputMethodAgent>& agent,
const InputChannel *channel) override;
int32_t onInputReady(const sptr<IInputMethodAgent>& agent) override;
int32_t onInputReleased(int32_t retValue) override;
int32_t setDisplayMode(int32_t mode) override;
private:

View File

@ -91,7 +91,7 @@ namespace MiscServices {
int mSelectOldEnd = 0;
int mSelectNewBegin = 0;
int mSelectNewEnd = 0;
int32_t mSpecialKeyPress = 0;
CursorInfo cursorInfo_;
static std::mutex instanceLock_;
static sptr<InputMethodController> instance_;
@ -101,4 +101,4 @@ namespace MiscServices {
};
}
}
#endif
#endif

View File

@ -40,8 +40,7 @@ namespace MiscServices {
virtual void releaseInput(MessageParcel& data) override;
virtual void startInput(MessageParcel& data) override;
virtual void stopInput(MessageParcel& data) override;
virtual void DispatchKey(MessageParcel& data) override;
virtual int32_t setInputMethodCore(sptr<IInputMethodCore> &core) override;
virtual void SetCoreAndAgent(MessageParcel& data) override;
int32_t Prepare(int32_t displayId, sptr<InputClientStub> &client, sptr<InputDataChannelStub> &channel,
InputAttribute &attribute);

View File

@ -22,8 +22,7 @@ using namespace ErrorCode;
{
}
int32_t InputClientProxy::onInputReady(int32_t retValue, const sptr<IInputMethodAgent>& agent,
const InputChannel *channel)
int32_t InputClientProxy::onInputReady(const sptr<IInputMethodAgent>& agent)
{
IMSA_HILOGI("InputClientProxy::onInputReady");
MessageParcel data, reply;
@ -32,22 +31,7 @@ using namespace ErrorCode;
return ERROR_EX_PARCELABLE;
}
if (!data.WriteInt32(retValue)) {
return ERROR_EX_PARCELABLE;
}
if (agent == nullptr) {
data.WriteInt32(0);
} else {
data.WriteInt32(1);
data.WriteRemoteObject(agent->AsObject().GetRefPtr());
}
if (channel == nullptr) {
data.WriteInt32(0);
} else {
data.WriteInt32(1);
data.WriteParcelable(channel);
}
data.WriteRemoteObject(agent->AsObject().GetRefPtr());
auto ret = Remote()->SendRequest(ON_INPUT_READY, data, reply, option);
if (ret != NO_ERROR) {

View File

@ -18,6 +18,7 @@
namespace OHOS {
namespace MiscServices {
// using namespace Message;
InputClientStub::InputClientStub()
{
}
@ -40,13 +41,7 @@ namespace MiscServices {
break;
}
MessageParcel *parcel = new MessageParcel();
parcel->WriteInt32(data.ReadInt32());
if (data.ReadInt32() > 0) {
parcel->WriteRemoteObject(data.ReadRemoteObject());
}
if (data.ReadInt32() > 0) {
parcel->WriteParcelable(data.ReadParcelable<InputChannel>());
}
parcel->WriteRemoteObject(data.ReadRemoteObject());
Message *msg = new Message(MessageID::MSG_ID_ON_INPUT_READY, parcel);
msgHandler->SendMessage(msg);
@ -78,8 +73,7 @@ namespace MiscServices {
return NO_ERROR;
}
int32_t InputClientStub::onInputReady(int32_t retValue, const sptr<IInputMethodAgent>& agent,
const InputChannel *channel)
int32_t InputClientStub::onInputReady(const sptr<IInputMethodAgent>& agent)
{
return ErrorCode::NO_ERROR;
}

View File

@ -68,6 +68,7 @@ using namespace MessageID;
mAttribute.SetInputPattern(InputAttribute::PATTERN_TEXT);
textListener = nullptr;
PrepareInput(0, mClient, mInputDataChannel, mAttribute);
return true;
}
@ -136,18 +137,9 @@ using namespace MessageID;
}
case MSG_ID_ON_INPUT_READY: {
MessageParcel *data = msg->msgContent_;
int32_t ret = data->ReadInt32();
if (ret != ErrorCode::NO_ERROR) {
if (textListener != nullptr) {
textListener->SetKeyboardStatus(false);
}
mAgent = nullptr;
break;
}
sptr<IRemoteObject> object = data->ReadRemoteObject();
mAgent = new InputMethodAgentProxy(object);
if (textListener != nullptr) {
textListener->SetKeyboardStatus(true);
if (object != nullptr) {
mAgent = new InputMethodAgentProxy(object);
}
break;
}
@ -201,8 +193,8 @@ using namespace MessageID;
void InputMethodController::Attach(sptr<OnTextChangedListener> &listener)
{
PrepareInput(0, mClient, mInputDataChannel, mAttribute);
textListener = listener;
StartInput(mClient);
}
void InputMethodController::ShowTextInput()
@ -304,12 +296,19 @@ using namespace MessageID;
return;
}
if(cursorInfo_.left == cursorInfo.left && cursorInfo_.top == cursorInfo.top && cursorInfo_.height == cursorInfo.height){
return;
}
cursorInfo_ = cursorInfo;
mAgent->OnCursorUpdate(cursorInfo.left, cursorInfo.top, cursorInfo.height);
}
void InputMethodController::OnSelectionChange(std::u16string text, int start, int end)
{
IMSA_HILOGI("InputMethodController::OnSelectionChange");
if (mTextString == text && mSelectNewBegin == start && mSelectNewEnd == end) {
return;
}
mTextString = text;
mSelectOldBegin = mSelectNewBegin;
mSelectOldEnd = mSelectNewEnd;
@ -350,35 +349,18 @@ using namespace MessageID;
bool InputMethodController::dispatchKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)
{
IMSA_HILOGI("InputMethodController::dispatchKeyEvent");
if (textListener == nullptr) {
IMSA_HILOGI("InputMethodController::dispatchKeyEvent textListener is nullptr");
return false;
}
if (mImms == nullptr) {
return false;
}
int32_t code = keyEvent->GetKeyCode();
int32_t status = keyEvent->GetKeyAction();
if (mSpecialKeyPress != 0) {
if ((code == MMI::KeyEvent::KEYCODE_CTRL_LEFT || code == MMI::KeyEvent::KEYCODE_CTRL_RIGHT) && status == MMI::KeyEvent::KEY_ACTION_UP) {
mSpecialKeyPress--;
}
return false;
}
if ((code == MMI::KeyEvent::KEYCODE_CTRL_LEFT || code == MMI::KeyEvent::KEYCODE_CTRL_RIGHT) && status == MMI::KeyEvent::KEY_ACTION_DOWN) {
mSpecialKeyPress++;
if (mAgent == nullptr) {
IMSA_HILOGI("InputMethodController::dispatchKeyEvent mAgent is nullptr");
return false;
}
MessageParcel data;
if (!(data.WriteInterfaceToken(mImms->GetDescriptor())
&& data.WriteRemoteObject(mClient->AsObject().GetRefPtr())
if (!(data.WriteInterfaceToken(mAgent->GetDescriptor())
&& data.WriteInt32(keyEvent->GetKeyCode())
&& data.WriteInt32(keyEvent->GetKeyAction()))) {
return false;
}
mImms->DispatchKey(data);
return true;
return mAgent->DispatchKeyEvent(data);
}
}
}
}

View File

@ -97,49 +97,20 @@ namespace MiscServices {
}
}
void InputMethodSystemAbilityProxy::DispatchKey(MessageParcel& data)
void InputMethodSystemAbilityProxy::SetCoreAndAgent(MessageParcel& data)
{
IMSA_HILOGI("InputMethodSystemAbilityProxy::DispatchKey");
MessageParcel reply;
MessageOption option;
IMSA_HILOGI("InputMethodSystemAbilityProxy::SetCoreAndAgent");
auto ret = Remote()->SendRequest(DISPATCH_KEY, data, reply, option);
if (ret != NO_ERROR) {
IMSA_HILOGI("InputMethodSystemAbilityProxy::DispatchKey SendRequest failed");
return;
}
ret = reply.ReadInt32();
if (ret != NO_ERROR) {
IMSA_HILOGI("InputMethodSystemAbilityProxy::DispatchKey reply failed");
return;
}
}
int32_t InputMethodSystemAbilityProxy::setInputMethodCore(sptr<IInputMethodCore> &core)
{
IMSA_HILOGI("InputMethodSystemAbilityProxy::setInputMethodCore");
if (core == nullptr) {
IMSA_HILOGI("InputMethodSystemAbilityProxy::setInputMethodCore inputDataChannel is nullptr");
}
auto remote = Remote();
if (remote == nullptr) {
return -1;
}
MessageParcel data;
if (!(data.WriteInterfaceToken(GetDescriptor())
&& data.WriteRemoteObject(core->AsObject()))) {
return -1;
return;
}
MessageParcel reply;
MessageOption option {
MessageOption::TF_SYNC
};
int32_t status = Remote()->SendRequest(SET_INPUT_METHOD_CORE, data, reply, option);
return status;
Remote()->SendRequest(SET_CORE_AND_AGENT, data, reply, option);
}
int32_t InputMethodSystemAbilityProxy::Prepare(int32_t displayId, sptr<InputClientStub> &client,

View File

@ -24,18 +24,12 @@ config("inputmethodengine_native_public_config") {
}
ohos_shared_library("inputmethodengine") {
include_dirs = [
"//third_party/node/src",
"//foundation/ace/napi/interfaces/kits",
sources = [
"src/input_method_engine_module.cpp",
"src/js_input_method_engine.cpp",
"src/js_input_method_engine_listener.cpp",
]
cflags = [
"-fPIC",
"-g3",
]
sources = [ "js_input_method_engine.cpp" ]
configs = [ ":inputmethodengine_native_config" ]
deps = [
@ -61,11 +55,12 @@ ohos_shared_library("inputmethodengine") {
]
external_deps = [
"ability_runtime:runtime",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
]
relative_install_dir = "module"
public_configs = [ ":inputmethodengine_native_public_config" ]
subsystem_name = "miscservices"
part_name = "inputmethod_native"

View File

@ -0,0 +1,30 @@
/*
* 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.
*/
#ifndef OHOS_MISCSERVICES_JS_INPUT_METHOD_ENGINE_H
#define OHOS_MISCSERVICES_JS_INPUT_METHOD_ENGINE_H
#include "native_engine/native_engine.h"
#include "native_engine/native_value.h"
#include "global.h"
#include "js_runtime_utils.h"
namespace OHOS {
namespace MiscServices {
NativeValue* JsInputMethodEngineInit(NativeEngine* engine, NativeValue* exportObj);
}
}
#endif // OHOS_MISCSERVICES_JS_INPUT_METHOD_ENGINE_H

View File

@ -0,0 +1,51 @@
/*
* 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.
*/
#ifndef FM_IMMS_PROJECT_INPUTMETHODENGINELISTENER_H
#define FM_IMMS_PROJECT_INPUTMETHODENGINELISTENER_H
#include <map>
#include <mutex>
#include <unordered_set>
#include <queue>
#include <condition_variable>
#include "native_engine/native_engine.h"
#include "native_engine/native_value.h"
#include <refbase.h>
namespace OHOS {
namespace MiscServices {
class JsInputMethodEngineListener : virtual public RefBase {
public:
explicit JsInputMethodEngineListener(NativeEngine* engine) : engine_(engine) {}
virtual ~JsInputMethodEngineListener() = default;
void RegisterListenerWithType(NativeEngine& engine, std::string type, NativeValue* value);
void UnregisterListenerWithType(std::string type, NativeValue* value);
void OnKeyboardStatus(bool isShow);
bool OnKeyEvent(int32_t keyCode, int32_t keyStatus);
void OnCursorUpdate(int32_t positionX, int32_t positionY, int height);
void OnSelectionChange(int32_t oldBegin, int32_t oldEnd, int32_t newBegin, int32_t newEnd);
void OnTextChange(std::string text);
private:
void AddCallback(std::string type, NativeValue* jsListenerObject);
void CallJsMethod(std::string methodName, NativeValue* const* argv = nullptr, size_t argc = 0);
bool CallJsMethodReturnBool(std::string methodName, NativeValue* const* argv = nullptr, size_t argc = 0);
void RemoveCallback(NativeValue* jsListenerObject);
bool IfCallbackRegistered(std::string type, NativeValue* jsListenerObject);
NativeEngine* engine_ = nullptr;
std::mutex mMutex;
std::map<std::string, std::vector<std::unique_ptr<NativeReference>>> jsCbMap_;
};
}
}
#endif // FM_IMMS_PROJECT_INPUTMETHODENGINELISTENER_H

View File

@ -1,341 +0,0 @@
/*
* 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 "event_target.h"
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "global.h"
#include "string_ex.h"
#include "input_method_utils.h"
namespace OHOS {
namespace MiscServices {
napi_value JS_Constructor(napi_env env, napi_callback_info cbInfo)
{
IMSA_HILOGI("JS_Constructor() is called!");
napi_value thisVar = nullptr;
void *data = nullptr;
napi_get_cb_info(env, cbInfo, nullptr, nullptr, &thisVar, &data);
OHOS::MiscServices::EventTarget *eventTarget = new OHOS::MiscServices::EventTarget(env, thisVar);
napi_wrap(env, thisVar, eventTarget,
[](napi_env env, void *data, void *hint) {
EventTarget *eventTarget = (EventTarget*)data;
delete eventTarget;
eventTarget = nullptr;
},
nullptr, nullptr);
OHOS::sptr<EventTarget> eventTarget_ = eventTarget;
InputMethodAbility::GetInstance()->setEventTarget(eventTarget_);
return thisVar;
}
napi_value JS_InsertText(napi_env env, napi_callback_info cbInfo)
{
IMSA_HILOGI("JS_InsertText() is called!");
size_t argc = 1;
napi_value argv[2] = { 0 };
napi_value thisVar = nullptr;
void *data = nullptr;
napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, &data);
EventTarget *eventTarget = nullptr;
napi_unwrap(env, thisVar, (void **)&eventTarget);
char type[64] = { 0 };
size_t typeLen = 0;
napi_get_value_string_utf8(env, argv[0], type, sizeof(type), &typeLen);
std::string text = type;
InputMethodAbility::GetInstance()->InsertText(text);
napi_value result = nullptr;
napi_get_undefined(env, &result);
IMSA_HILOGI("JS_InsertText() is end!");
return result;
}
napi_value JS_DeleteForward(napi_env env, napi_callback_info cbInfo)
{
IMSA_HILOGI("JS_DeleteForward() is called!");
size_t argc = 1;
napi_value argv[2] = { 0 };
napi_value thisVar = nullptr;
void *data = nullptr;
napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, &data);
EventTarget *eventTarget = nullptr;
napi_unwrap(env, thisVar, (void **)&eventTarget);
int32_t value32 = 0;
napi_get_value_int32(env, argv[0], &value32);
InputMethodAbility::GetInstance()->DeleteForward(value32);
napi_value result = nullptr;
napi_get_undefined(env, &result);
return result;
}
napi_value JS_DeleteBackward(napi_env env, napi_callback_info cbInfo)
{
IMSA_HILOGI("JS_DeleteBackward() is called!");
size_t argc = 1;
napi_value argv[2] = { 0 };
napi_value thisVar = nullptr;
void *data = nullptr;
napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, &data);
EventTarget *eventTarget = nullptr;
napi_unwrap(env, thisVar, (void **)&eventTarget);
int32_t value32 = 0;
napi_get_value_int32(env, argv[0], &value32);
InputMethodAbility::GetInstance()->DeleteBackward(value32);
napi_value result = nullptr;
napi_get_undefined(env, &result);
return result;
}
napi_value JS_MoveCursor(napi_env env, napi_callback_info cbInfo)
{
IMSA_HILOGI("JS_MoveCursor() is called!");
size_t argc = 1;
napi_value argv[2] = { 0 };
napi_value thisVar = nullptr;
void *data = nullptr;
napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, &data);
EventTarget *eventTarget = nullptr;
napi_unwrap(env, thisVar, (void **)&eventTarget);
int32_t value32 = 0;
napi_get_value_int32(env, argv[0], &value32);
InputMethodAbility::GetInstance()->MoveCursor(value32);
napi_value result = nullptr;
napi_get_undefined(env, &result);
return result;
}
napi_value JS_HideKeyboardSelf(napi_env env, napi_callback_info cbInfo)
{
IMSA_HILOGI("JS_HideKeyboardSelf() is called!");
size_t argc = 1;
napi_value argv[2] = { 0 };
napi_value thisVar = nullptr;
void *data = nullptr;
napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, &data);
EventTarget *eventTarget = nullptr;
napi_unwrap(env, thisVar, (void **)&eventTarget);
InputMethodAbility::GetInstance()->HideKeyboardSelf();
napi_value result = nullptr;
napi_get_undefined(env, &result);
return result;
}
napi_value JS_GetTextBeforeCursor(napi_env env, napi_callback_info cbInfo)
{
IMSA_HILOGI("JS_GetTextBeforeCursor() is called!");
size_t argc = 1;
napi_value argv[2] = { 0 };
napi_value thisVar = nullptr;
void *data = nullptr;
napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, &data);
EventTarget *eventTarget = nullptr;
napi_unwrap(env, thisVar, (void **)&eventTarget);
std::u16string textString = InputMethodAbility::GetInstance()->GetTextBeforeCursor();
std::string outString = Str16ToStr8(textString.c_str());
napi_value result = nullptr;
napi_create_string_utf8(env, outString.c_str(), NAPI_AUTO_LENGTH, &result);
return result;
}
napi_value JS_GetTextAfterCursor(napi_env env, napi_callback_info cbInfo)
{
IMSA_HILOGI("JS_GetTextAfterCursor() is called!");
size_t argc = 1;
napi_value argv[2] = { 0 };
napi_value thisVar = nullptr;
void *data = nullptr;
napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, &data);
EventTarget *eventTarget = nullptr;
napi_unwrap(env, thisVar, (void **)&eventTarget);
std::u16string textString = InputMethodAbility::GetInstance()->GetTextAfterCursor();
std::string outString = Str16ToStr8(textString.c_str());
napi_value result = nullptr;
napi_create_string_utf8(env, outString.c_str(), NAPI_AUTO_LENGTH, &result);
return result;
}
napi_value JS_SendFunctionKey(napi_env env, napi_callback_info cbInfo)
{
IMSA_HILOGI("JS_SendFunctionKey() is called!");
size_t argc = 1;
napi_value argv[2] = { 0 };
napi_value thisVar = nullptr;
void *data = nullptr;
napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, &data);
EventTarget *eventTarget = nullptr;
napi_unwrap(env, thisVar, (void **)&eventTarget);
int32_t value32 = 0;
napi_get_value_int32(env, argv[0], &value32);
InputMethodAbility::GetInstance()->SendFunctionKey(value32);
napi_value result = nullptr;
napi_get_undefined(env, &result);
return result;
}
napi_value JS_On(napi_env env, napi_callback_info cbInfo)
{
IMSA_HILOGI("JS_On() is called!");
size_t requireArgc = 2;
size_t argc = 2;
napi_value argv[2] = { 0 };
napi_value thisVar = 0;
void *data = nullptr;
napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, &data);
EventTarget *eventTarget = nullptr;
napi_unwrap(env, thisVar, (void **)&eventTarget);
NAPI_ASSERT(env, argc >= requireArgc, "requires 2 parameter");
napi_valuetype eventValueType;
napi_typeof(env, argv[0], &eventValueType);
NAPI_ASSERT(env, eventValueType == napi_string, "type mismatch for parameter 1");
napi_valuetype eventHandleType;
napi_typeof(env, argv[1], &eventHandleType);
NAPI_ASSERT(env, eventHandleType == napi_function, "type mismatch for parameter 2");
char type[64] = { 0 };
size_t typeLen = 0;
napi_get_value_string_utf8(env, argv[0], type, sizeof(type), &typeLen);
IMSA_HILOGI("call ima on function");
eventTarget->On((const char*)type, argv[1]);
napi_value result = nullptr;
napi_get_undefined(env, &result);
IMSA_HILOGI("JS_On() is end!");
return result;
}
napi_value JS_Off(napi_env env, napi_callback_info cbInfo)
{
size_t requireArgc = 1;
size_t argc = 2;
napi_value argv[2] = { 0 };
napi_value thisVar = 0;
void *data = nullptr;
napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, &data);
EventTarget *eventTarget = nullptr;
napi_unwrap(env, thisVar, (void **)&eventTarget);
NAPI_ASSERT(env, argc >= requireArgc, "requires 2 parameter");
napi_valuetype eventValueType;
napi_typeof(env, argv[0], &eventValueType);
NAPI_ASSERT(env, eventValueType == napi_string, "type mismatch for parameter 1");
char *type = nullptr;
size_t typeLen = 0;
napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typeLen);
type = new char[typeLen + 1];
napi_get_value_string_utf8(env, argv[0], type, typeLen + 1, &typeLen);
if (argc > requireArgc) {
NAPI_ASSERT(env, eventValueType == napi_function, "type mismatch for parameter 2");
eventTarget->Off(type, argv[1]);
} else {
eventTarget->Off(type);
}
type = nullptr;
napi_value result = nullptr;
napi_get_undefined(env, &result);
return result;
}
napi_value ToInt32Value(napi_env env, int32_t value)
{
napi_value staticValue = nullptr;
napi_create_int32(env, value, &staticValue);
return staticValue;
}
napi_value InputMethodEngineInit(napi_env env, napi_value exports)
{
IMSA_HILOGI("InputMethodEngineInit() is called!");
const char className[] = "EventTarget";
napi_value constructor = nullptr;
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("InsertText", JS_InsertText),
DECLARE_NAPI_FUNCTION("DeleteForward", JS_DeleteForward),
DECLARE_NAPI_FUNCTION("DeleteBackward", JS_DeleteBackward),
DECLARE_NAPI_FUNCTION("MoveCursor", JS_MoveCursor),
DECLARE_NAPI_FUNCTION("HideKeyboardSelf", JS_HideKeyboardSelf),
DECLARE_NAPI_FUNCTION("GetTextBeforeCursor", JS_GetTextBeforeCursor),
DECLARE_NAPI_FUNCTION("GetTextAfterCursor", JS_GetTextAfterCursor),
DECLARE_NAPI_FUNCTION("SendFunctionKey", JS_SendFunctionKey),
DECLARE_NAPI_FUNCTION("on", JS_On),
DECLARE_NAPI_FUNCTION("off", JS_Off),
DECLARE_NAPI_STATIC_PROPERTY("FUNCTION_KEY_CONFIRM", ToInt32Value(env, 1)),
DECLARE_NAPI_STATIC_PROPERTY("CURSOR_UP", ToInt32Value(env, 1)),
DECLARE_NAPI_STATIC_PROPERTY("CURSOR_DOWN", ToInt32Value(env, 2)),
DECLARE_NAPI_STATIC_PROPERTY("CURSOR_LEFT", ToInt32Value(env, 3)),
DECLARE_NAPI_STATIC_PROPERTY("CURSOR_RIGHT", ToInt32Value(env, 4)),
};
napi_define_class(env, className, sizeof(className), JS_Constructor, nullptr,
sizeof(desc) / sizeof(desc[0]), desc, &constructor);
napi_set_named_property(env, exports, "InputMethodEngine", constructor);
return exports;
}
/*
* module define
*/
static napi_module inputMethodEngineModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = InputMethodEngineInit,
.nm_modname = "inputMethodEngine",
.nm_priv = ((void*)0),
.reserved = {0},
};
/*
* module register
*/
extern "C" __attribute__((constructor)) void RegisterModule()
{
IMSA_HILOGI("RegisterModule() is called!");
napi_module_register(&inputMethodEngineModule);
}
}
}

View File

@ -0,0 +1,29 @@
/*
* 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 "native_engine/native_engine.h"
#include "js_input_method_engine.h"
extern "C" __attribute__((constructor)) void NAPI_inputMethodEngine_AutoRegister()
{
auto moduleManager = NativeModuleManager::GetInstance();
NativeModule newModuleInfo = {
.name = "inputMethodEngine",
.fileName = "inputmethodengine.so/inputmethod_engine.js",
.registerCallback = OHOS::MiscServices::JsInputMethodEngineInit,
};
moduleManager->Register(&newModuleInfo);
}

View File

@ -0,0 +1,355 @@
/*
* 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 "js_input_method_engine.h"
#include "js_input_method_engine_listener.h"
#include "input_method_ability.h"
#include <map>
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "string_ex.h"
#include "input_method_utils.h"
namespace OHOS {
namespace MiscServices {
namespace {
constexpr size_t ARGC_ZERO = 0;
constexpr size_t ARGC_ONE = 1;
constexpr size_t ARGC_TWO = 2;
}
class JsInputMethodEngine{
public:
sptr<JsInputMethodEngineListener> imeListener_;
explicit JsInputMethodEngine(NativeEngine* engine) {
IMSA_HILOGI("JsInputMethodEngine::Constructor is called");
imeListener_ = new JsInputMethodEngineListener(engine);
InputMethodAbility::GetInstance()->setImeListener(imeListener_);
}
~JsInputMethodEngine() = default;
static void Finalizer(NativeEngine* engine, void* data, void* hint)
{
IMSA_HILOGI("JsInputMethodEngine::Finalizer is called");
std::unique_ptr<JsInputMethodEngine>(static_cast<JsInputMethodEngine*>(data));
}
static NativeValue* InsertText(NativeEngine* engine, NativeCallbackInfo* info)
{
JsInputMethodEngine* me = AbilityRuntime::CheckParamsAndGetThis<JsInputMethodEngine>(engine, info);
return (me != nullptr) ? me->OnInsertText(*engine, *info) : nullptr;
}
static NativeValue* DeleteForward(NativeEngine* engine, NativeCallbackInfo* info)
{
JsInputMethodEngine* me = AbilityRuntime::CheckParamsAndGetThis<JsInputMethodEngine>(engine, info);
return (me != nullptr) ? me->OnDeleteForward(*engine, *info) : nullptr;
}
static NativeValue* DeleteBackward(NativeEngine* engine, NativeCallbackInfo* info)
{
JsInputMethodEngine* me = AbilityRuntime::CheckParamsAndGetThis<JsInputMethodEngine>(engine, info);
return (me != nullptr) ? me->OnDeleteBackward(*engine, *info) : nullptr;
}
static NativeValue* MoveCursor(NativeEngine* engine, NativeCallbackInfo* info)
{
JsInputMethodEngine* me = AbilityRuntime::CheckParamsAndGetThis<JsInputMethodEngine>(engine, info);
return (me != nullptr) ? me->OnMoveCursor(*engine, *info) : nullptr;
}
static NativeValue* HideKeyboardSelf(NativeEngine* engine, NativeCallbackInfo* info)
{
JsInputMethodEngine* me = AbilityRuntime::CheckParamsAndGetThis<JsInputMethodEngine>(engine, info);
return (me != nullptr) ? me->OnHideKeyboardSelf(*engine, *info) : nullptr;
}
static NativeValue* GetTextBeforeCursor(NativeEngine* engine, NativeCallbackInfo* info)
{
JsInputMethodEngine* me = AbilityRuntime::CheckParamsAndGetThis<JsInputMethodEngine>(engine, info);
return (me != nullptr) ? me->OnGetTextBeforeCursor(*engine, *info) : nullptr;
}
static NativeValue* GetTextAfterCursor(NativeEngine* engine, NativeCallbackInfo* info)
{
JsInputMethodEngine* me = AbilityRuntime::CheckParamsAndGetThis<JsInputMethodEngine>(engine, info);
return (me != nullptr) ? me->OnGetTextAfterCursor(*engine, *info) : nullptr;
}
static NativeValue* SendFunctionKey(NativeEngine* engine, NativeCallbackInfo* info)
{
JsInputMethodEngine* me = AbilityRuntime::CheckParamsAndGetThis<JsInputMethodEngine>(engine, info);
return (me != nullptr) ? me->OnSendFunctionKey(*engine, *info) : nullptr;
}
static NativeValue* RegisterCallback(NativeEngine* engine, NativeCallbackInfo* info)
{
JsInputMethodEngine* me = AbilityRuntime::CheckParamsAndGetThis<JsInputMethodEngine>(engine, info);
return (me != nullptr) ? me->OnRegisterCallback(*engine, *info) : nullptr;
}
static NativeValue* UnRegisterCallback(NativeEngine* engine, NativeCallbackInfo* info)
{
JsInputMethodEngine* me = AbilityRuntime::CheckParamsAndGetThis<JsInputMethodEngine>(engine, info);
return (me != nullptr) ? me->OnUnRegisterCallback(*engine, *info) : nullptr;
}
private:
std::mutex mtx_;
NativeValue* OnInsertText(NativeEngine& engine, NativeCallbackInfo& info)
{
IMSA_HILOGI("JsInputMethodEngine::OnInsertText is called!");
if (info.argc < ARGC_ONE) {
IMSA_HILOGI("JsInputMethodEngine::OnInsertText has no params!");
return engine.CreateUndefined();
}
NativeValue* nativeString = nullptr;
nativeString = info.argv[ARGC_ZERO];
std::string textString;
if(!AbilityRuntime::ConvertFromJsValue(engine, nativeString, textString)) {
IMSA_HILOGI("JsInputMethodEngine::OnInsertText Failed to convert parameter to string");
return engine.CreateUndefined();
}
bool ret = InputMethodAbility::GetInstance()->InsertText(textString);
NativeValue* result = AbilityRuntime::CreateJsValue(engine, ret);
return result;
}
NativeValue* OnDeleteForward(NativeEngine& engine, NativeCallbackInfo& info)
{
IMSA_HILOGI("JsInputMethodEngine::OnDeleteForward is called!");
if (info.argc < ARGC_ONE) {
IMSA_HILOGI("JsInputMethodEngine::OnDeleteForward has no params!");
return engine.CreateUndefined();
}
NativeValue* nativeString = nullptr;
nativeString = info.argv[ARGC_ZERO];
int32_t number;
if(!AbilityRuntime::ConvertFromJsValue(engine, nativeString, number)) {
IMSA_HILOGI("JsInputMethodEngine::OnDeleteForward Failed to convert parameter to string");
return engine.CreateUndefined();
}
InputMethodAbility::GetInstance()->DeleteForward(number);
NativeValue* result = AbilityRuntime::CreateJsValue(engine, true);
return result;
}
NativeValue* OnDeleteBackward(NativeEngine& engine, NativeCallbackInfo& info)
{
IMSA_HILOGI("JsInputMethodEngine::OnDeleteBackward is called!");
if (info.argc < ARGC_ONE) {
IMSA_HILOGI("JsInputMethodEngine::OnDeleteBackward has no params!");
return engine.CreateUndefined();
}
NativeValue* nativeString = nullptr;
nativeString = info.argv[ARGC_ZERO];
int32_t number;
if(!AbilityRuntime::ConvertFromJsValue(engine, nativeString, number)) {
IMSA_HILOGI("JsInputMethodEngine::OnDeleteBackward Failed to convert parameter to string");
return engine.CreateUndefined();
}
InputMethodAbility::GetInstance()->DeleteBackward(number);
NativeValue* result = AbilityRuntime::CreateJsValue(engine, true);
return result;
}
NativeValue* OnMoveCursor(NativeEngine& engine, NativeCallbackInfo& info)
{
IMSA_HILOGI("JsInputMethodEngine::OnMoveCursor is called!");
if (info.argc < ARGC_ONE) {
IMSA_HILOGI("JsInputMethodEngine::OnMoveCursor has no params!");
return engine.CreateUndefined();
}
NativeValue* nativeString = nullptr;
nativeString = info.argv[ARGC_ZERO];
int32_t number;
if(!AbilityRuntime::ConvertFromJsValue(engine, nativeString, number)) {
IMSA_HILOGI("JsInputMethodEngine::OnMoveCursor Failed to convert parameter to string");
return engine.CreateUndefined();
}
InputMethodAbility::GetInstance()->MoveCursor(number);
NativeValue* result = AbilityRuntime::CreateJsValue(engine, true);
return result;
}
NativeValue* OnHideKeyboardSelf(NativeEngine& engine, NativeCallbackInfo& info)
{
IMSA_HILOGI("JsInputMethodEngine::OnHideKeyboardSelf is called!");
if (info.argc != ARGC_ZERO) {
IMSA_HILOGI("JsInputMethodEngine::OnHideKeyboardSelf has params, return!");
return engine.CreateUndefined();
}
InputMethodAbility::GetInstance()->HideKeyboardSelf();
return engine.CreateUndefined();
}
NativeValue* OnGetTextBeforeCursor(NativeEngine& engine, NativeCallbackInfo& info)
{
IMSA_HILOGI("JsInputMethodEngine::OnGetTextBeforeCursor is called!");
if (info.argc != ARGC_ZERO) {
IMSA_HILOGI("JsInputMethodEngine::OnGetTextBeforeCursor has params, return!");
return engine.CreateUndefined();
}
std::string ret = Str16ToStr8(InputMethodAbility::GetInstance()->GetTextBeforeCursor());
NativeValue* result = AbilityRuntime::CreateJsValue(engine, ret);
return result;
}
NativeValue* OnGetTextAfterCursor(NativeEngine& engine, NativeCallbackInfo& info)
{
IMSA_HILOGI("JsInputMethodEngine::OnGetTextAfterCursor is called!");
if (info.argc != ARGC_ZERO) {
IMSA_HILOGI("JsInputMethodEngine::OnGetTextAfterCursor has params, return!");
return engine.CreateUndefined();
}
std::string ret = Str16ToStr8(InputMethodAbility::GetInstance()->GetTextAfterCursor());
NativeValue* result = AbilityRuntime::CreateJsValue(engine, ret);
return result;
}
NativeValue* OnSendFunctionKey(NativeEngine& engine, NativeCallbackInfo& info)
{
IMSA_HILOGI("JsInputMethodEngine::OnSendFunctionKey is called!");
if (info.argc < ARGC_ONE) {
IMSA_HILOGI("JsInputMethodEngine::OnSendFunctionKey has no params!");
return engine.CreateUndefined();
}
NativeValue* nativeString = nullptr;
nativeString = info.argv[ARGC_ZERO];
int32_t number;
if(!AbilityRuntime::ConvertFromJsValue(engine, nativeString, number)) {
IMSA_HILOGI("JsInputMethodEngine::OnSendFunctionKey Failed to convert parameter to string");
return engine.CreateUndefined();
}
InputMethodAbility::GetInstance()->SendFunctionKey(number);
return engine.CreateUndefined();
}
NativeValue* OnRegisterCallback(NativeEngine& engine, NativeCallbackInfo& info)
{
IMSA_HILOGI("JsInputMethodEngine::OnRegisterCallback is called!");
if (info.argc != ARGC_TWO) {
IMSA_HILOGI("JsInputMethodEngine::OnRegisterCallback Params not match");
return engine.CreateUndefined();
}
std::string cbType;
if (!AbilityRuntime::ConvertFromJsValue(engine, info.argv[0], cbType)) {
IMSA_HILOGI("JsInputMethodEngine::OnRegisterCallback Failed to convert parameter to callbackType");
return engine.CreateUndefined();
}
NativeValue* value = info.argv[1];
imeListener_->RegisterListenerWithType(engine, cbType, value);
return engine.CreateUndefined();
}
NativeValue* OnUnRegisterCallback(NativeEngine& engine, NativeCallbackInfo& info)
{
IMSA_HILOGI("JsInputMethodEngine::OnUnRegisterCallback is called!");
if (info.argc == 0) {
IMSA_HILOGI("JsInputMethodEngine::OnUnRegisterCallback Params not match");
return engine.CreateUndefined();
}
std::string cbType;
if (!AbilityRuntime::ConvertFromJsValue(engine, info.argv[0], cbType)) {
IMSA_HILOGI("JsInputMethodEngine::OnUnRegisterCallback Failed to convert parameter to callbackType");
return engine.CreateUndefined();
}
std::lock_guard<std::mutex> lock(mtx_);
NativeValue* value = info.argv[1];
if (!value->IsCallable()) {
IMSA_HILOGI("JsInputMethodEngine::OnUnregisterWindowManagerCallback info->argv[1] is not callable");
return engine.CreateUndefined();
}
imeListener_->UnregisterListenerWithType(cbType, value);
return engine.CreateUndefined();
}
};
NativeValue* JsInputMethodEngineInit(NativeEngine* engine, NativeValue* exportObj)
{
IMSA_HILOGI("JsInputMethodEngineInit() is called!");
if (engine == nullptr || exportObj == nullptr) {
IMSA_HILOGI("engine or exportObj null");
return nullptr;
}
NativeObject* object = AbilityRuntime::ConvertNativeValueTo<NativeObject>(exportObj);
if (object == nullptr) {
IMSA_HILOGI("object null");
return nullptr;
}
std::unique_ptr<JsInputMethodEngine> jsIMEngine = std::make_unique<JsInputMethodEngine>(engine);
object->SetNativePointer(jsIMEngine.release(), JsInputMethodEngine::Finalizer, nullptr);
AbilityRuntime::BindNativeFunction(*engine, *object, "InsertText", JsInputMethodEngine::InsertText);
AbilityRuntime::BindNativeFunction(*engine, *object, "DeleteForward", JsInputMethodEngine::DeleteForward);
AbilityRuntime::BindNativeFunction(*engine, *object, "DeleteBackward", JsInputMethodEngine::DeleteBackward);
AbilityRuntime::BindNativeFunction(*engine, *object, "MoveCursor", JsInputMethodEngine::MoveCursor);
AbilityRuntime::BindNativeFunction(*engine, *object, "HideKeyboardSelf", JsInputMethodEngine::HideKeyboardSelf);
AbilityRuntime::BindNativeFunction(*engine, *object, "GetTextBeforeCursor", JsInputMethodEngine::GetTextBeforeCursor);
AbilityRuntime::BindNativeFunction(*engine, *object, "GetTextAfterCursor", JsInputMethodEngine::GetTextAfterCursor);
AbilityRuntime::BindNativeFunction(*engine, *object, "SendFunctionKey", JsInputMethodEngine::SendFunctionKey);
AbilityRuntime::BindNativeFunction(*engine, *object, "on", JsInputMethodEngine::RegisterCallback);
AbilityRuntime::BindNativeFunction(*engine, *object, "off", JsInputMethodEngine::UnRegisterCallback);
object->SetProperty("FUNCTION_KEY_CONFIRM", AbilityRuntime::CreateJsValue(*engine, static_cast<uint32_t>(1)));
object->SetProperty("CURSOR_UP", AbilityRuntime::CreateJsValue(*engine, static_cast<uint32_t>(1)));
object->SetProperty("CURSOR_DOWN", AbilityRuntime::CreateJsValue(*engine, static_cast<uint32_t>(2)));
object->SetProperty("CURSOR_LEFT", AbilityRuntime::CreateJsValue(*engine, static_cast<uint32_t>(3)));
object->SetProperty("CURSOR_RIGHT", AbilityRuntime::CreateJsValue(*engine, static_cast<uint32_t>(4)));
return engine->CreateUndefined();
}
}
}

View File

@ -0,0 +1,263 @@
/*
* 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 "js_input_method_engine_listener.h"
#include "global.h"
#include "js_runtime_utils.h"
namespace OHOS {
namespace MiscServices {
void JsInputMethodEngineListener::RegisterListenerWithType(NativeEngine& engine, std::string type, NativeValue* value)
{
// should do type check
if (IfCallbackRegistered(type, value)) {
IMSA_HILOGI("JsInputMethodEngineListener::RegisterListenerWithType callback already registered!");
return;
}
std::unique_ptr<NativeReference> callbackRef;
callbackRef.reset(engine.CreateReference(value, 1));
AddCallback(type, value);
}
void JsInputMethodEngineListener::AddCallback(std::string type, NativeValue* jsListenerObject)
{
IMSA_HILOGI("JsInputMethodEngineListener::AddCallback is called");
std::lock_guard<std::mutex> lock(mMutex);
std::unique_ptr<NativeReference> callbackRef;
callbackRef.reset(engine_->CreateReference(jsListenerObject, 1));
jsCbMap_[type].push_back(std::move(callbackRef));
IMSA_HILOGI("JsInputMethodEngineListener::AddCallback success jsCbMap_ size: %{public}d, and type[%{public}s] size: %{public}d!",
static_cast<uint32_t>(jsCbMap_.size()), type.c_str(), static_cast<uint32_t>(jsCbMap_[type].size()));
return;
}
void JsInputMethodEngineListener::UnregisterListenerWithType(std::string type, NativeValue* value)
{
// should do type check
if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
IMSA_HILOGI("JsInputMethodEngineListener::UnregisterListenerWithType methodName %{public}s not registerted!",
type.c_str());
return;
}
for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) {
if (value->StrictEquals((*it)->Get())) {
jsCbMap_[type].erase(it);
break;
}
}
// one type with multi jscallback, erase type when there is no callback in one type
if (jsCbMap_[type].empty()) {
jsCbMap_.erase(type);
}
return;
}
bool JsInputMethodEngineListener::IfCallbackRegistered(std::string type, NativeValue* jsListenerObject)
{
if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
IMSA_HILOGI("JsInputMethodEngineListener::IfCallbackRegistered methodName %{public}s not registertd!", type.c_str());
return false;
}
for (auto iter = jsCbMap_[type].begin(); iter != jsCbMap_[type].end(); iter++) {
if (jsListenerObject->StrictEquals((*iter)->Get())) {
IMSA_HILOGI("JsInputMethodEngineListener::IfCallbackRegistered callback already registered!");
return true;
}
}
return false;
}
void JsInputMethodEngineListener::CallJsMethod(std::string methodName, NativeValue* const* argv, size_t argc)
{
IMSA_HILOGI("JsInputMethodEngineListener::CallJsMethod");
if (engine_ == nullptr) {
IMSA_HILOGI("engine_ nullptr");
return;
}
if (jsCbMap_.empty() || jsCbMap_.find(methodName) == jsCbMap_.end()) {
IMSA_HILOGI("JsInputMethodEngineListener::CallJsMethod methodName %{public}s not registertd!", methodName.c_str());
return;
}
for (auto iter = jsCbMap_[methodName].begin(); iter != jsCbMap_[methodName].end(); iter++) {
engine_->CallFunction(engine_->CreateUndefined(), (*iter)->Get(), argv, argc);
}
}
bool JsInputMethodEngineListener::CallJsMethodReturnBool(std::string methodName, NativeValue* const* argv, size_t argc)
{
IMSA_HILOGI("JsInputMethodEngineListener::CallJsMethodReturnBool");
if (engine_ == nullptr) {
IMSA_HILOGI("engine_ nullptr");
return false;
}
if (jsCbMap_.empty() || jsCbMap_.find(methodName) == jsCbMap_.end()) {
IMSA_HILOGI("JsInputMethodEngineListener::CallJsMethodReturnBool methodName %{public}s not registertd!", methodName.c_str());
return false;
}
bool result = false;
for (auto iter = jsCbMap_[methodName].begin(); iter != jsCbMap_[methodName].end(); iter++) {
NativeValue* nativeValue = engine_->CallFunction(engine_->CreateUndefined(), (*iter)->Get(), argv, argc);
bool ret = false;
if (AbilityRuntime::ConvertFromJsValue(*engine_, nativeValue, ret) && ret) {
result = true;
}
}
return result;
}
void JsInputMethodEngineListener::OnKeyboardStatus(bool isShow)
{
std::lock_guard<std::mutex> lock(mMutex);
IMSA_HILOGI("JsInputMethodEngineListener::OnKeyboardStatus");
NativeValue* nativeValue = engine_->CreateObject();
NativeObject* object = AbilityRuntime::ConvertNativeValueTo<NativeObject>(nativeValue);
if (object == nullptr) {
IMSA_HILOGI("Failed to convert rect to jsObject");
return;
}
NativeValue* argv[] = {nativeValue};
std::string methodName;
if (isShow) {
methodName = "keyboardShow";
} else {
methodName = "keyboardHide";
}
CallJsMethod(methodName, argv, AbilityRuntime::ArraySize(argv));
}
bool JsInputMethodEngineListener::OnKeyEvent(int32_t keyCode, int32_t keyStatus)
{
std::lock_guard<std::mutex> lock(mMutex);
IMSA_HILOGI("JsInputMethodEngineListener::OnKeyEvent");
NativeValue* nativeValue = engine_->CreateObject();
NativeObject* object = AbilityRuntime::ConvertNativeValueTo<NativeObject>(nativeValue);
if (object == nullptr) {
IMSA_HILOGI("Failed to convert rect to jsObject");
return false;
}
NativeValue* argv[] = {nativeValue};
std::string methodName;
if (keyStatus == 2) {
methodName = "keyDown";
} else {
methodName = "keyUp";
}
object->SetProperty("keyCode", AbilityRuntime::CreateJsValue(*engine_, static_cast<uint32_t>(keyCode)));
object->SetProperty("keyAction", AbilityRuntime::CreateJsValue(*engine_, static_cast<uint32_t>(keyStatus)));
return CallJsMethodReturnBool(methodName, argv, AbilityRuntime::ArraySize(argv));
}
void JsInputMethodEngineListener::OnCursorUpdate(int32_t positionX, int32_t positionY, int height)
{
std::lock_guard<std::mutex> lock(mMutex);
IMSA_HILOGI("JsInputMethodEngineListener::OnCursorUpdate");
NativeValue* nativeXValue = engine_->CreateObject();
NativeObject* objectX = AbilityRuntime::ConvertNativeValueTo<NativeObject>(nativeXValue);
if (objectX == nullptr) {
IMSA_HILOGI("Failed to convert rect to jsObject");
return;
}
objectX->SetProperty("x", AbilityRuntime::CreateJsValue(*engine_, static_cast<uint32_t>(positionX)));
NativeValue* nativeYValue = engine_->CreateObject();
NativeObject* objectY = AbilityRuntime::ConvertNativeValueTo<NativeObject>(nativeYValue);
if (objectY == nullptr) {
IMSA_HILOGI("Failed to convert rect to jsObject");
return;
}
objectY->SetProperty("y", AbilityRuntime::CreateJsValue(*engine_, static_cast<uint32_t>(positionY)));
NativeValue* nativeHValue = engine_->CreateObject();
NativeObject* objectH = AbilityRuntime::ConvertNativeValueTo<NativeObject>(nativeHValue);
if (objectH == nullptr) {
IMSA_HILOGI("Failed to convert rect to jsObject");
return;
}
objectH->SetProperty("height", AbilityRuntime::CreateJsValue(*engine_, static_cast<uint32_t>(height)));
NativeValue* argv[] = {nativeXValue, nativeYValue, nativeHValue};
std::string methodName = "cursorContextChange";
CallJsMethod(methodName, argv, AbilityRuntime::ArraySize(argv));
}
void JsInputMethodEngineListener::OnSelectionChange(int32_t oldBegin, int32_t oldEnd, int32_t newBegin, int32_t newEnd)
{
std::lock_guard<std::mutex> lock(mMutex);
IMSA_HILOGI("JsInputMethodEngineListener::OnSelectionChange");
NativeValue* nativeOBValue = engine_->CreateObject();
NativeObject* objectOB = AbilityRuntime::ConvertNativeValueTo<NativeObject>(nativeOBValue);
if (objectOB == nullptr) {
IMSA_HILOGI("Failed to convert rect to jsObject");
return;
}
objectOB->SetProperty("oldBegin", AbilityRuntime::CreateJsValue(*engine_, static_cast<uint32_t>(oldBegin)));
NativeValue* nativeOEValue = engine_->CreateObject();
NativeObject* objectOE = AbilityRuntime::ConvertNativeValueTo<NativeObject>(nativeOEValue);
if (objectOE == nullptr) {
IMSA_HILOGI("Failed to convert rect to jsObject");
return;
}
objectOE->SetProperty("oldEnd", AbilityRuntime::CreateJsValue(*engine_, static_cast<uint32_t>(oldEnd)));
NativeValue* nativeNBHValue = engine_->CreateObject();
NativeObject* objectNB = AbilityRuntime::ConvertNativeValueTo<NativeObject>(nativeNBHValue);
if (objectNB == nullptr) {
IMSA_HILOGI("Failed to convert rect to jsObject");
return;
}
objectNB->SetProperty("newBegin", AbilityRuntime::CreateJsValue(*engine_, static_cast<uint32_t>(newBegin)));
NativeValue* nativeNEValue = engine_->CreateObject();
NativeObject* objectNE = AbilityRuntime::ConvertNativeValueTo<NativeObject>(nativeNEValue);
if (objectNE == nullptr) {
IMSA_HILOGI("Failed to convert rect to jsObject");
return;
}
objectNE->SetProperty("newEnd", AbilityRuntime::CreateJsValue(*engine_, static_cast<uint32_t>(newEnd)));
NativeValue* argv[] = {nativeOEValue, nativeOEValue, nativeNBHValue, nativeNEValue};
std::string methodName = "selectionChange";
CallJsMethod(methodName, argv, AbilityRuntime::ArraySize(argv));
}
void JsInputMethodEngineListener::OnTextChange(std::string text)
{
std::lock_guard<std::mutex> lock(mMutex);
IMSA_HILOGI("JsInputMethodEngineListener::OnTextChange");
NativeValue* nativeValue = engine_->CreateObject();
NativeObject* object = AbilityRuntime::ConvertNativeValueTo<NativeObject>(nativeValue);
if (object == nullptr) {
IMSA_HILOGI("Failed to convert rect to jsObject");
return;
}
object->SetProperty("text", AbilityRuntime::CreateJsValue(*engine_, text));
NativeValue* argv[] = {nativeValue};
std::string methodName = "textChange";
CallJsMethod(methodName, argv, AbilityRuntime::ArraySize(argv));
}
}
}

View File

@ -1,53 +0,0 @@
{
"subsystem": "miscservices",
"parts": {
"inputmethod_native": {
"variants": [
"phone",
"wearable",
"ivi"
],
"module_list": [
"//base/miscservices/inputmethod:inputmethod_native_packages"
],
"inner_kits": [
{
"name": "//base/miscservices/inputmethod/frameworks/inputmethod_controller:inputmethod_client",
"header": {
"header_files": [
"i_input_client.h",
"i_input_data_channel.h",
"input_client_proxy.h",
"input_client_stub.h",
"input_data_channel_proxy.h",
"input_data_channel_stub.h",
"input_method_controller.h",
"input_method_system_ability_proxy.h"
],
"header_base": "//base/miscservices/inputmethod/frameworks/inputmethod_controller/include"
}
},
{
"name": "//base/miscservices/inputmethod/frameworks/inputmethod_ability:inputmethod_ability",
"header": {
"header_files": [
"event_target.h",
"i_input_method_agent.h",
"i_input_method_core.h",
"input_method_ability.h",
"input_method_agent_proxy.h",
"input_method_agent_stub.h",
"input_method_core_proxy.h",
"input_method_core_stub.h"
],
"header_base": "//base/miscservices/inputmethod/frameworks/inputmethod_ability/include"
}
}
],
"test_list": [
"//base/miscservices/inputmethod/unitest:InputMethodControllerTest",
"//base/miscservices/inputmethod/unitest:InputMethodAbilityTest"
]
}
}
}

View File

@ -26,34 +26,24 @@ config("inputmethod_services_native_config") {
ohos_shared_library("inputmethod_service") {
sources = [
"${inputmethod_path}/frameworks/inputmethod_ability/src/event_target.cpp",
"${inputmethod_path}/frameworks/inputmethod_ability/src/input_method_ability.cpp",
"${inputmethod_path}/frameworks/inputmethod_ability/src/input_method_agent_proxy.cpp",
"${inputmethod_path}/frameworks/inputmethod_ability/src/input_method_agent_stub.cpp",
"${inputmethod_path}/frameworks/inputmethod_ability/src/input_method_core_proxy.cpp",
"${inputmethod_path}/frameworks/inputmethod_ability/src/input_method_core_stub.cpp",
"${inputmethod_path}/frameworks/inputmethod_controller/src/input_client_proxy.cpp",
"${inputmethod_path}/frameworks/inputmethod_controller/src/input_data_channel_proxy.cpp",
"${inputmethod_path}/frameworks/inputmethod_controller/src/input_method_system_ability_proxy.cpp",
"../services/src/global.cpp",
"../services/src/input_attribute.cpp",
"../services/src/input_channel.cpp",
"../services/src/input_control_channel_proxy.cpp",
"../services/src/input_control_channel_stub.cpp",
"../services/src/input_method_ability_connection_stub.cpp",
"../services/src/input_method_property.cpp",
"../services/src/input_method_setting.cpp",
"../services/src/input_method_system_ability.cpp",
"../services/src/input_method_system_ability_stub.cpp",
"../services/src/keyboard_type.cpp",
"../services/src/message.cpp",
"../services/src/message_handler.cpp",
"../services/src/peruser_session.cpp",
"../services/src/peruser_setting.cpp",
"../services/src/platform.cpp",
"../services/src/platform_api_proxy.cpp",
"../services/src/platform_callback_proxy.cpp",
"../services/src/platform_callback_stub.cpp",
"src/global.cpp",
"src/input_attribute.cpp",
"src/input_channel.cpp",
"src/input_control_channel_proxy.cpp",
"src/input_control_channel_stub.cpp",
"src/input_method_ability_connection_stub.cpp",
"src/input_method_property.cpp",
"src/input_method_setting.cpp",
"src/input_method_system_ability.cpp",
"src/input_method_system_ability_stub.cpp",
"src/keyboard_type.cpp",
"src/message.cpp",
"src/message_handler.cpp",
"src/peruser_session.cpp",
"src/peruser_setting.cpp",
"src/platform.cpp",
"src/platform_callback_stub.cpp",
]
configs = [ ":inputmethod_services_native_config" ]
@ -61,8 +51,8 @@ ohos_shared_library("inputmethod_service") {
public_configs = [ ":inputmethod_services_native_config" ]
deps = [
"//base/miscservices/inputmethod/frameworks/inputmethod_ability:inputmethod_ability",
"//base/global/resmgr_standard/frameworks/resmgr:global_resmgr",
"//foundation/aafwk/standard/frameworks/kits/ability/native:abilitykit_native",
"//foundation/aafwk/standard/interfaces/innerkits/ability_manager:ability_manager",
"//foundation/aafwk/standard/interfaces/innerkits/app_manager:app_manager",
"//foundation/aafwk/standard/interfaces/innerkits/base:base",

View File

@ -26,8 +26,7 @@ namespace OHOS {
class IInputControlChannel : public IRemoteBroker {
public:
enum {
ON_AGENT_CREATED = FIRST_CALL_TRANSACTION,
HIDE_KEYBOARD_SELF,
HIDE_KEYBOARD_SELF = FIRST_CALL_TRANSACTION,
ADVANCE_TO_NEXT,
SET_DISPLAY_MODE,
ON_KEYBOARD_SHOWED,
@ -35,7 +34,6 @@ namespace OHOS {
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.inputmethod.InputControlChannel");
virtual void onAgentCreated(sptr<IInputMethodAgent>& agent, InputChannel *channel) = 0;
virtual void hideKeyboardSelf(int flags) = 0;
virtual bool advanceToNext(bool isCurrentIme) = 0;
virtual void setDisplayMode(int mode) = 0;

View File

@ -37,7 +37,6 @@ namespace MiscServices {
RELEASE_INPUT,
START_INPUT,
STOP_INPUT,
DISPATCH_KEY,
SET_INPUT_METHOD_CORE,
GET_DISPLAY_MODE,
GET_KEYBOARD_WINDOW_HEIGHT,
@ -45,6 +44,7 @@ namespace MiscServices {
LIST_INPUT_METHOD_ENABLED,
LIST_INPUT_METHOD,
LIST_KEYBOARD_TYPE,
SET_CORE_AND_AGENT,
};
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.inputmethod.IInputMethodSystemAbility");
@ -53,8 +53,7 @@ namespace MiscServices {
virtual void releaseInput(MessageParcel& data) = 0;
virtual void startInput(MessageParcel& data) = 0;
virtual void stopInput(MessageParcel& data) = 0;
virtual void DispatchKey(MessageParcel& data) = 0;
virtual int32_t setInputMethodCore(sptr<IInputMethodCore> &core) = 0;
virtual void SetCoreAndAgent(MessageParcel& data) = 0;
virtual int32_t getDisplayMode(int32_t retMode) = 0;
virtual int32_t getKeyboardWindowHeight(int32_t retHeight) = 0;

View File

@ -56,7 +56,6 @@ namespace OHOS {
InputMethodProperty *inputMethodProperty) = 0;
virtual int32_t getInputMethodSetting(int userId, InputMethodSetting *inputMethodSetting) = 0;
virtual int32_t setInputMethodSetting(int userId, const InputMethodSetting& inputMethodSetting) = 0;
};
}
}

View File

@ -33,7 +33,6 @@ namespace MiscServices {
InputControlChannelProxy(const sptr<IRemoteObject> &impl);
~InputControlChannelProxy();
virtual void onAgentCreated(sptr<IInputMethodAgent>& agent, InputChannel *channel) override;
virtual void hideKeyboardSelf(int flags) override;
virtual bool advanceToNext(bool isCurrentIme) override;
virtual void setDisplayMode(int mode) override;

View File

@ -35,19 +35,15 @@ namespace OHOS {
MessageParcel &data,
MessageParcel &reply,
MessageOption &option) override;
virtual void onAgentCreated(sptr<IInputMethodAgent>& agent, InputChannel *channel) override;
virtual void hideKeyboardSelf(int flags) override;
virtual bool advanceToNext(bool isCurrentIme) override;
virtual void setDisplayMode(int mode) override;
virtual void onKeyboardShowed() override;
void ResetFlag();
bool GetAgentAndChannel(sptr<IInputMethodAgent> *retAgent, InputChannel **retChannel);
bool WaitKeyboardReady();
private:
int userId_;
sptr<IInputMethodAgent> agent = nullptr;
InputChannel *channel = nullptr;
std::mutex mtx;
std::condition_variable cv;

View File

@ -32,7 +32,6 @@ namespace MiscServices {
const static std::u16string CURRENT_SYS_KEYBOARD_TYPE_TAG; // default keyboard type for security IME
const static std::u16string SYSTEM_LOCALE_TAG; // locale list supported in the system
InputMethodSetting();
~InputMethodSetting();
InputMethodSetting(const InputMethodSetting& inputMethodSetting);

View File

@ -23,7 +23,6 @@
#include "peruser_setting.h"
#include "peruser_session.h"
#include "event_handler.h"
#include "input_method_ability.h"
namespace OHOS {
namespace MiscServices {
@ -52,7 +51,6 @@ namespace MiscServices {
virtual int32_t listInputMethodEnabled(std::vector<InputMethodProperty*> *properties) override;
virtual int32_t listInputMethod(std::vector<InputMethodProperty*> *properties) override;
virtual int32_t listKeyboardType(const std::u16string& imeId, std::vector<KeyboardType*> *types) override;
virtual int32_t setInputMethodCore(sptr<IInputMethodCore> &core) override;
protected:
void OnStart() override;
void OnStop() override;
@ -84,7 +82,6 @@ namespace MiscServices {
int32_t OnAdvanceToNext(const Message *msg);
ServiceRunningState state_;
sptr<InputMethodAbility> inputMethodAbility_;
void InitServiceHandler();
static std::mutex instanceLock_;
static sptr<InputMethodSystemAbility> instance_;

View File

@ -33,8 +33,7 @@ namespace MiscServices {
virtual void releaseInput(MessageParcel& data) override;
virtual void startInput(MessageParcel& data) override;
virtual void stopInput(MessageParcel& data) override;
virtual void DispatchKey(MessageParcel& data) override;
void setInputMethodCoreFromHap(MessageParcel& data);
virtual void SetCoreAndAgent(MessageParcel& data) override;
protected:
int32_t getUserId(int32_t uid);
int USER_ID_CHANGE_VALUE = 200000; // user range

View File

@ -44,7 +44,7 @@ namespace MessageID {
MSG_ID_START_INPUT, // start input
MSG_ID_STOP_INPUT, // stop input
MSG_ID_RELEASE_INPUT, // release input
MSG_ID_SET_INPUT_METHOD_CORE,
MSG_ID_SET_CORE_AND_AGENT,
// the request to handle the condition that the remote object died
MSG_ID_CLIENT_DIED, // input client died
@ -74,9 +74,9 @@ namespace MessageID {
MSG_ID_HIDE_KEYBOARD,
MSG_ID_SET_KEYBOARD_TYPE,
MSG_ID_GET_KEYBOARD_WINDOW_HEIGHT,
MSG_ID_INIT_INPUT_CONTROL_CHANNEL,
// the request from IMC to IMA
MSG_ID_DISPATCH_KEY, // dispatch key from PhysicalKbd
MSG_ID_ON_CURSOR_UPDATE,
MSG_ID_ON_SELECTION_CHANGE,
};

View File

@ -38,7 +38,6 @@
#include "keyboard_type.h"
#include "ability_manager_interface.h"
#include "ability_connect_callback_proxy.h"
#include "input_method_ability.h"
namespace OHOS {
namespace MiscServices {
@ -113,7 +112,6 @@ namespace MiscServices {
int OnSettingChanged(const std::u16string& key, const std::u16string& value);
void CreateWorkThread(MessageHandler& handler);
void JoinWorkThread();
void SetInputMethodAbility(sptr<InputMethodAbility> &inputMethodAbility);
static bool StartInputService();
private:
int userId_; // the id of the user to whom the object is linking
@ -148,7 +146,6 @@ namespace MiscServices {
std::thread workThreadHandler; // work thread handler
std::mutex mtx; // mutex to lock the operations among multi work threads
sptr<AAFwk::AbilityConnectionProxy> connCallback;
sptr<InputMethodAbility> inputMethodAbility_;
PerUserSession(const PerUserSession&);
PerUserSession& operator =(const PerUserSession&);
@ -165,7 +162,7 @@ namespace MiscServices {
void OnReleaseInput(Message *msg);
void OnStartInput(Message *msg);
void OnStopInput(Message *msg);
void DispatchKey(Message *msg);
void SetCoreAndAgent(Message *msg);
void OnClientDied(const wptr<IRemoteObject>& who);
void OnImsDied(const wptr<IRemoteObject>& who);
void OnHideKeyboardSelf(int flags);
@ -184,7 +181,9 @@ namespace MiscServices {
void SetDisplayId(int displayId);
int GetImeIndex(const sptr<IInputClient>& inputClient);
static sptr<AAFwk::IAbilityManager> GetAbilityManagerService();
void onSetInputMethodCore(Message *msg);
void SendAgentToSingleClient(const sptr<IInputClient>& inputClient);
void InitInputControlChannel();
void SendAgentToAllClients();
};
}
}

View File

@ -27,10 +27,12 @@ namespace OHOS {
namespace MiscServices {
class Utils {
public:
static std::string to_utf8(std::u16string str16) {
static std::string to_utf8(std::u16string str16)
{
return std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(str16);
}
static std::u16string to_utf16(std::string str) {
static std::u16string to_utf16(std::string str)
{
return std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.from_bytes(str);
}
};

View File

@ -40,24 +40,6 @@ namespace MiscServices {
{
}
void InputControlChannelProxy::onAgentCreated(sptr<IInputMethodAgent> &agent, InputChannel *channel)
{
IMSA_HILOGI("InputControlChannelProxy::onAgentCreated start.");
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteRemoteObject(agent->AsObject());
if (channel == nullptr) {
data.WriteInt32(0);
} else {
data.WriteInt32(1);
data.WriteParcelable(channel);
}
Remote()->SendRequest(ON_AGENT_CREATED, data, reply, option);
IMSA_HILOGI("InputMethodCoreStub::onAgentCreated end.");
}
void InputControlChannelProxy::hideKeyboardSelf(int flags)
{
IMSA_HILOGI("InputControlChannelProxy::hideKeyboardSelf");

View File

@ -53,18 +53,6 @@ namespace MiscServices {
return ErrorCode::ERROR_STATUS_UNKNOWN_TRANSACTION;
}
switch (code) {
case ON_AGENT_CREATED: {
sptr<InputMethodAgentProxy> proxy = new InputMethodAgentProxy(data.ReadRemoteObject());
sptr<IInputMethodAgent> agent = proxy;
InputChannel *channel = nullptr;
if (data.ReadInt32() > 0) {
channel = data.ReadParcelable<InputChannel>();
}
onAgentCreated(agent, channel);
reply.WriteNoException();
break;
}
case HIDE_KEYBOARD_SELF: {
int flag = data.ReadInt32();
hideKeyboardSelf(flag);
@ -96,25 +84,6 @@ namespace MiscServices {
return NO_ERROR;
}
/*! Called when input method service creates InputMethodAgentProxy
\n This call is running in binder thread
\param agent the remote handler from input method service, with which input client can remotely callback to
input method service
\param channel channel for sending physical keyboard event from input client to input method service
*/
void InputControlChannelStub::onAgentCreated(sptr < IInputMethodAgent >& agent, InputChannel *channel)
{
IMSA_HILOGI("InputControlChannelStub::onAgentCreated");
{
std::unique_lock<std::mutex> lck(mtx);
agentReadyFlag = true;
}
this->agent = agent;
this->channel = channel;
cv.notify_one();
}
/*! Called when input method service showed keyboard
\n This call is running in binder thread
*/
@ -193,43 +162,6 @@ namespace MiscServices {
std::unique_lock<std::mutex> lck(mtx);
keyboardReadyFlag = false;
agentReadyFlag = false;
if (agent) {
agent = nullptr;
}
if (channel) {
delete channel;
channel = nullptr;
}
}
/*! Get input method agent and input write channel
\n This should be called in work thread of PerUserSession
\param[out] retAgent remote handler of InputMethodAgentProxy returned to the caller
\param[out] retChannel input write channel returned to caller
\return true - onAgentCreated is called by input method service in time
\n false - onAgentCreated is not called by input method service in time
*/
bool InputControlChannelStub::GetAgentAndChannel(sptr<IInputMethodAgent> *retAgent, InputChannel **retChannel)
{
IMSA_HILOGI("InputControlChannelStub::GetAgentAndChannel");
std::chrono::milliseconds millsec(sleepTime);
bool ret = false;
{
std::unique_lock<std::mutex> lck(mtx);
ret = cv.wait_for(lck, millsec, [this] {
return agentReadyFlag;
});
}
if (ret) {
if (retAgent) {
*retAgent = agent;
}
if (retChannel) {
*retChannel = channel;
channel = nullptr;
}
return true;
}
return false;
}
/*! Wait for keyboard to be ready

View File

@ -59,7 +59,7 @@ namespace MiscServices {
}
std::map<int32_t, PerUserSession*>::const_iterator it;
for (it = userSessions.cbegin(); it != userSessions.cend();) {
for (it = userSessions.cbegin(); it != userSessions.cend(); ) {
PerUserSession *session = it->second;
it = userSessions.erase(it);
delete session;
@ -67,7 +67,7 @@ namespace MiscServices {
}
userSessions.clear();
std::map<int32_t, PerUserSetting*>::const_iterator it1;
for (it1 = userSettings.cbegin(); it1 != userSettings.cend();) {
for (it1 = userSettings.cbegin(); it1 != userSettings.cend(); ) {
PerUserSetting *setting = it1->second;
it1 = userSettings.erase(it1);
delete setting;
@ -75,7 +75,7 @@ namespace MiscServices {
}
userSettings.clear();
std::map<int32_t, MessageHandler*>::const_iterator it2;
for (it2 = msgHandlers.cbegin(); it2 != msgHandlers.cend();) {
for (it2 = msgHandlers.cbegin(); it2 != msgHandlers.cend(); ) {
MessageHandler *handler = it2->second;
it2 = msgHandlers.erase(it2);
delete handler;
@ -172,6 +172,7 @@ namespace MiscServices {
}
void InputMethodSystemAbility::StartInputService() {
IMSA_HILOGE("InputMethodSystemAbility::StartInputService()");
PerUserSession *session = GetUserSession(MAIN_USER_ID);
std::map<int32_t, MessageHandler*>::const_iterator it = msgHandlers.find(MAIN_USER_ID);
@ -433,12 +434,11 @@ namespace MiscServices {
case MSG_ID_RELEASE_INPUT:
case MSG_ID_START_INPUT:
case MSG_ID_STOP_INPUT:
case MSG_ID_SET_INPUT_METHOD_CORE:
case MSG_ID_SET_CORE_AND_AGENT:
case MSG_ID_HIDE_KEYBOARD_SELF:
case MSG_ID_SET_DISPLAY_MODE:
case MSG_ID_CLIENT_DIED:
case MSG_ID_IMS_DIED:
case MSG_ID_DISPATCH_KEY:
case MSG_ID_RESTART_IMS: {
OnHandleMessage(msg);
break;
@ -542,11 +542,6 @@ namespace MiscServices {
return ErrorCode::NO_ERROR;
}
int32_t InputMethodSystemAbility::setInputMethodCore(sptr<IInputMethodCore> &core)
{
return ErrorCode::NO_ERROR;
}
/*! Called when a user is unlocked. (EVENT_USER_UNLOCKED is received)
\n Run in work thread of input method management service
\param msg the parameters are saved in msg->msgContent_
@ -632,7 +627,7 @@ namespace MiscServices {
int32_t userId = data->ReadInt32();
PerUserSetting *setting = GetUserSetting(userId);
if (setting == nullptr || setting->GetUserState() != UserState::USER_STATE_UNLOCKED) {
IMSA_HILOGE("Aborted! %s %d\n", ErrorCode::ToString(ErrorCode::ERROR_USER_NOT_UNLOCKED), userId);
IMSA_HILOGE("InputMethodSystemAbility::OnHandleMessage Aborted! userId = %{public}d", userId);
return ErrorCode::ERROR_USER_NOT_UNLOCKED;
}

View File

@ -61,15 +61,9 @@ namespace MiscServices {
reply.WriteInt32(NO_ERROR);
break;
}
case DISPATCH_KEY: {
case SET_CORE_AND_AGENT: {
MessageParcel *msgParcel = (MessageParcel*) &data;
DispatchKey(*msgParcel);
reply.WriteInt32(NO_ERROR);
break;
}
case SET_INPUT_METHOD_CORE: {
MessageParcel *msgParcel = (MessageParcel*) &data;
setInputMethodCoreFromHap(*msgParcel);
SetCoreAndAgent(*msgParcel);
reply.WriteInt32(NO_ERROR);
break;
}
@ -251,37 +245,23 @@ namespace MiscServices {
MessageHandler::Instance()->SendMessage(msg);
}
void InputMethodSystemAbilityStub::DispatchKey(MessageParcel& data)
{
IMSA_HILOGI("InputMethodSystemAbilityStub::DispatchKey");
int32_t uid = IPCSkeleton::GetCallingUid();
int32_t userId = getUserId(uid);
MessageParcel *parcel = new MessageParcel();
parcel->WriteInt32(userId);
parcel->WriteRemoteObject(data.ReadRemoteObject());
parcel->WriteInt32(data.ReadInt32());
parcel->WriteInt32(data.ReadInt32());
Message *msg = new Message(MSG_ID_DISPATCH_KEY, parcel);
MessageHandler::Instance()->SendMessage(msg);
}
/*! Prepare input
\n Send prepareInput command to work thread.
The handling of prepareInput is in the work thread of PerUserSession.
\see PerUserSession::OnPrepareInput
\param data the parcel in which the parameters are saved
*/
void InputMethodSystemAbilityStub::setInputMethodCoreFromHap(MessageParcel& data)
void InputMethodSystemAbilityStub::SetCoreAndAgent(MessageParcel& data)
{
IMSA_HILOGI("InputMethodSystemAbilityStub::setInputMethodCoreFromHap");
IMSA_HILOGI("InputMethodSystemAbilityStub::SetCoreAndAgent");
int32_t uid = IPCSkeleton::GetCallingUid();
int32_t userId = getUserId(uid);
MessageParcel *parcel = new MessageParcel();
parcel->WriteInt32(userId);
parcel->WriteRemoteObject(data.ReadRemoteObject());
parcel->WriteRemoteObject(data.ReadRemoteObject());
Message *msg = new Message(MSG_ID_SET_INPUT_METHOD_CORE, parcel);
Message *msg = new Message(MSG_ID_SET_CORE_AND_AGENT, parcel);
MessageHandler::Instance()->SendMessage(msg);
}

View File

@ -110,7 +110,6 @@ namespace MiscServices {
} else {
mHashCode = ID_NONE;
}
}
void KeyboardType::setLabelId(int32_t labelId)

View File

@ -13,6 +13,7 @@
* limitations under the License.
*/
#include "peruser_session.h"
#include "unistd.h"
#include "platform.h"
#include "parcel.h"
@ -21,7 +22,6 @@
#include "want.h"
#include "input_method_ability_connection_stub.h"
#include <vector>
#include "peruser_session.h"
#include "ability_connect_callback_proxy.h"
#include "ability_manager_interface.h"
#include "sa_mgr_client.h"
@ -32,6 +32,7 @@
#include "input_control_channel_proxy.h"
#include "ipc_skeleton.h"
#include "input_method_core_proxy.h"
#include "input_method_agent_proxy.h"
namespace OHOS {
namespace MiscServices {
@ -113,11 +114,6 @@ namespace MiscServices {
}
}
void PerUserSession::SetInputMethodAbility(sptr<InputMethodAbility> &inputMethodAbility)
{
inputMethodAbility_ = inputMethodAbility;
}
/*! Work thread for this user
*/
void PerUserSession::WorkThread()
@ -152,12 +148,8 @@ namespace MiscServices {
OnStopInput(msg);
break;
}
case MSG_ID_DISPATCH_KEY: {
DispatchKey(msg);
break;
}
case MSG_ID_SET_INPUT_METHOD_CORE: {
onSetInputMethodCore(msg);
case MSG_ID_SET_CORE_AND_AGENT: {
SetCoreAndAgent(msg);
break;
}
case MSG_ID_CLIENT_DIED: {
@ -492,46 +484,13 @@ namespace MiscServices {
return ErrorCode::ERROR_CLIENT_NOT_FOUND;
}
lastImeIndex = index;
bool supportPhysicalKbd = Platform::Instance()->CheckPhysicalKeyboard();
if (imsCore[index] == nullptr) {
if (imsCore[0] == nullptr) {
IMSA_HILOGE("PerUserSession::ShowKeyboard Aborted! imsCore[%{public}d] is nullptr", index);
return ErrorCode::ERROR_NULL_POINTER;
}
bool ret = imsCore[index]->startInput(clientInfo->channel, clientInfo->attribute, supportPhysicalKbd);
if (!ret ||
localControlChannel[index]->GetAgentAndChannel(&imsAgent, &imsChannel) == false) {
IMSA_HILOGE("PerUserSession::ShowKeyboard Aborted! client is not ready");
int result = clientInfo->client->onInputReady(1, nullptr, nullptr);
if (result != ErrorCode::NO_ERROR) {
IMSA_HILOGE("PerUserSession::ShowKeyboard onInputReady return : %{public}s", ErrorCode::ToString(ret));
}
return ErrorCode::ERROR_IME_START_FAILED;
}
ret = imsCore[index]->showKeyboard(1);
if (!ret) {
IMSA_HILOGE("PerUserSession::ShowKeyboard Aborted! showKeyboard has error : %{public}s",
ErrorCode::ToString(ret));
imsCore[0]->showKeyboard(clientInfo->channel);
int ret_client = clientInfo->client->onInputReady(1, nullptr, nullptr);
if (ret_client != ErrorCode::NO_ERROR) {
IMSA_HILOGE("PerUserSession::ShowKeyboard onInputReady has error : %{public}s",
ErrorCode::ToString(ret_client));
}
return ErrorCode::ERROR_KBD_SHOW_FAILED;
}
if (clientInfo->client == nullptr) {
IMSA_HILOGI("PerUserSession::ShowKeyboard clientInfo->client is nullptr");
}
int result = clientInfo->client->onInputReady(0, imsAgent, imsChannel);
if (result != ErrorCode::NO_ERROR) {
IMSA_HILOGE("PerUserSession::ShowKeyboard Aborted! onInputReady return : %{public}s",
ErrorCode::ToString(ret));
return result;
}
currentClient = inputClient;
return ErrorCode::NO_ERROR;
}
@ -557,34 +516,17 @@ namespace MiscServices {
if (clientInfo == nullptr) {
IMSA_HILOGE("PerUserSession::HideKeyboard GetClientInfo pointer nullptr");
}
if (imsCore[index] == nullptr) {
if (imsCore[0] == nullptr) {
IMSA_HILOGE("PerUserSession::HideKeyboard imsCore[index] is nullptr");
clientInfo->client->onInputReady(1, nullptr, nullptr);
return ErrorCode::ERROR_IME_NOT_STARTED;
}
if (currentClient == nullptr) {
clientInfo->client->onInputReady(1, nullptr, nullptr);
IMSA_HILOGE("PerUserSession::HideKeyboard Aborted! ErrorCode::ERROR_KBD_IS_NOT_SHOWING");
return ErrorCode::ERROR_KBD_IS_NOT_SHOWING;
}
bool ret = imsCore[index]->hideKeyboard(1);
bool ret = imsCore[0]->hideKeyboard(1);
if (!ret) {
IMSA_HILOGE("PerUserSession::HideKeyboard [imsCore->hideKeyboard] failed");
ret = ErrorCode::ERROR_KBD_HIDE_FAILED;
}
int ret_client_stop = clientInfo->client->onInputReady(1, nullptr, nullptr);
if (ret_client_stop != ErrorCode::NO_ERROR) {
IMSA_HILOGE("PerUserSession::HideKeyboard onInputReady return : %{public}s",
ErrorCode::ToString(ret_client_stop));
}
currentClient = nullptr;
imsAgent = nullptr;
if (imsChannel != nullptr) {
delete imsChannel;
imsChannel = nullptr;
}
return ErrorCode::NO_ERROR;
}
@ -1226,6 +1168,7 @@ namespace MiscServices {
sptr<IRemoteObject> clientObject = data->ReadRemoteObject();
if (clientObject == nullptr) {
IMSA_HILOGI("PerUserSession::OnPrepareInput clientObject is null");
return;
}
sptr<InputClientProxy> client = new InputClientProxy(clientObject);
sptr<IRemoteObject> channelObject = data->ReadRemoteObject();
@ -1243,12 +1186,21 @@ namespace MiscServices {
IMSA_HILOGE("PerUserSession::OnPrepareInput Aborted! %{public}s", ErrorCode::ToString(ret));
return;
}
SetDisplayId(displayId);
int index = GetImeIndex(client);
IMSA_HILOGI("PerUserSession::OnPrepareInput index = %{public}d", index);
currentIndex = index;
ShowKeyboard(client);
currentClient = client;
SendAgentToSingleClient(client);
}
void PerUserSession::SendAgentToSingleClient(const sptr<IInputClient>& inputClient) {
IMSA_HILOGI("PerUserSession::SendAgentToSingleClient");
if (imsAgent == nullptr) {
IMSA_HILOGI("PerUserSession::SendAgentToSingleClient imsAgent is nullptr");
return;
}
ClientInfo *clientInfo = GetClientInfo(inputClient);
if (clientInfo == nullptr) {
IMSA_HILOGE("PerUserSession::SendAgentToSingleClient clientInfo is nullptr");
return;
}
clientInfo->client->onInputReady(imsAgent);
}
/*! Release input. Called by an input client.
@ -1284,38 +1236,53 @@ namespace MiscServices {
MessageParcel *data = msg->msgContent_;
sptr<IRemoteObject> clientObject = data->ReadRemoteObject();
sptr<InputClientProxy> client = new InputClientProxy(clientObject);
int ret = ShowKeyboard(client);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("PerUserSession::OnStartInput Aborted! %{public}s", ErrorCode::ToString(ret));
} else {
IMSA_HILOGI("PerUserSession::OnStartInput End...[%{public}d]\n", userId_);
}
ShowKeyboard(client);
}
void PerUserSession::onSetInputMethodCore(Message *msg)
void PerUserSession::SetCoreAndAgent(Message *msg)
{
IMSA_HILOGI("PerUserSession::onSetInputMethodCore Start...[%{public}d]\n", userId_);
IMSA_HILOGI("PerUserSession::SetCoreAndAgent Start...[%{public}d]\n", userId_);
MessageParcel *data = msg->msgContent_;
sptr<IRemoteObject> coreObject = data->ReadRemoteObject();
sptr<InputMethodCoreProxy> core = new InputMethodCoreProxy(coreObject);
int index = currentIndex;
IMSA_HILOGI("PerUserSession::onSetInputMethodCore index = [%{public}d]\n", index);
if (index >= MAX_IME || index < 0) {
IMSA_HILOGE("PerUserSession::onSetInputMethodCore Aborted! ErrorCode::ERROR_BAD_PARAMETERS");
if (imsCore[0] != nullptr) {
IMSA_HILOGI("PerUserSession::SetCoreAndAgent Input Method Service has already been started ! ");
}
imsCore[0] = core;
sptr<IRemoteObject> agentObject = data->ReadRemoteObject();
sptr<InputMethodAgentProxy> proxy=new InputMethodAgentProxy(agentObject);
imsAgent = proxy;
InitInputControlChannel();
SendAgentToAllClients();
}
void PerUserSession::SendAgentToAllClients() {
IMSA_HILOGI("PerUserSession::SendAgentToAllClients");
if (imsAgent == nullptr) {
IMSA_HILOGI("PerUserSession::SendAgentToAllClients imsAgent is nullptr");
return;
}
if (imsCore[index] != nullptr) {
IMSA_HILOGI("PerUserSession::onSetInputMethodCore End... Input Method Service has already been started ! ");
for (std::map<sptr<IRemoteObject>, ClientInfo*>::iterator it = mapClients.begin(); it != mapClients.end(); it++) {
ClientInfo *clientInfo = (ClientInfo*) it->second;
if(clientInfo != nullptr) {
clientInfo->client->onInputReady(imsAgent);
}
}
imsCore[index] = core;
int ret = StartInputMethod(index);
}
void PerUserSession::InitInputControlChannel()
{
IMSA_HILOGI("PerUserSession::InitInputControlChannel");
sptr<IInputControlChannel> inputControlChannel = new InputControlChannelStub(userId_);
int ret = imsCore[0]->InitInputControlChannel(inputControlChannel);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("PerUserSession::onSetInputMethodCore Aborted! %{public}s", ErrorCode::ToString(ret));
} else {
IMSA_HILOGI("PerUserSession::onSetInputMethodCore End...[%{public}d]\n", userId_);
IMSA_HILOGI("PerUserSession::InitInputControlChannel fail %{public}s", ErrorCode::ToString(ret));
}
IMSA_HILOGI("PerUserSession::OnStartInput End. currentClient is nullptr");
}
/*! Stop input. Called by an input client.
@ -1330,28 +1297,7 @@ namespace MiscServices {
sptr<IRemoteObject> clientObject = data->ReadRemoteObject();
sptr<InputClientProxy> client = new InputClientProxy(clientObject);
int ret = HideKeyboard(client);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("PerUserSession::OnStopInput Aborted! %{public}s", ErrorCode::ToString(ret));
} else {
IMSA_HILOGI("PerUserSession::OnStopInput End...[%{public}d]\n", userId_);
}
}
void PerUserSession::DispatchKey(Message *msg)
{
IMSA_HILOGI("PerUserSession::DispatchKey");
MessageParcel *data = msg->msgContent_;
sptr<IRemoteObject> clientObject = data->ReadRemoteObject();
int32_t keyCode = data->ReadInt32();
int32_t state = data->ReadInt32();
if (localControlChannel[currentIndex]->GetAgentAndChannel(&imsAgent, &imsChannel) == true) {
IMSA_HILOGI("PerUserSession::DispatchKey GetAgentAndChannel");
sptr<InputMethodAgentProxy> agent = new InputMethodAgentProxy(imsAgent->AsObject().GetRefPtr());
agent->DispatchKey(keyCode, state);
}
HideKeyboard(client);
}
}
}

View File

@ -12,7 +12,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "unistd.h"
#include "peruser_setting.h"
#include "platform.h"

View File

@ -1,231 +0,0 @@
/*
* 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 "i_platform_api.h"
#include "i_input_method_core.h"
#include "iremote_proxy.h"
#include "message_parcel.h"
#include "peer_holder.h"
#include "input_method_setting.h"
#include "peer_holder.h"
#include "utils.h"
#include <string>
#include <cstdint>
/*! \class PlatformApiProxy
\brief The proxy implementation of IPlatformApi
*/
namespace OHOS {
namespace MiscServices {
class PlatformApiProxy : public IRemoteProxy<IPlatformApi> {
public:
PlatformApiProxy(const sptr<IRemoteObject>& impl) : IRemoteProxy<IPlatformApi>(impl)
{
}
~PlatformApiProxy()
{
}
int32_t registerCallback(const sptr<IPlatformCallback>& cb)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteRemoteObject(cb->AsObject());
int32_t status = Remote()->SendRequest(REGISTER_CALLBACK, data, reply, option);
if (status != ErrorCode::NO_ERROR) {
return status;
}
int code = reply.ReadException();
if (code != 0) {
return code;
}
return ErrorCode::NO_ERROR;
}
std::u16string getInterfaceDescriptor()
{
return Utils::to_utf16("20210814");
}
sptr<IInputMethodCore> bindInputMethodService(const std::u16string& packageName,
const std::u16string& intention, int userId)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteString16(packageName);
data.WriteString16(intention);
data.WriteInt32(userId);
int32_t status = Remote()->SendRequest(BIND_IMS, data, reply, option);
if (status != ErrorCode::NO_ERROR) {
LOG_DEBUG("status = %s\n", ErrorCode::ToString(status));
return nullptr;
}
int code = reply.ReadException();
if (code != 0) {// code = 0, means no exception.
LOG_DEBUG("exception code : %d\n", code);
return nullptr;
}
sptr < IInputMethodCore > ims = nullptr;
reply.ReadRemoteObject();
return ims;
}
int32_t unbindInputMethodService(int userId, const std::u16string& packageName)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteInt32(userId);
data.WriteString16(packageName);
int32_t status = Remote()->SendRequest(UNBIND_IMS, data, reply, option);
if (status != ErrorCode::NO_ERROR) {
return status;
}
int code = reply.ReadException();
if (code != 0) {
return code;
}
return ErrorCode::NO_ERROR;
}
sptr<IRemoteObject> createWindowToken(int userId, int displayId, const std::u16string& packageName)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteInt32(userId);
data.WriteInt32(displayId);
data.WriteString16(packageName);
int32_t status = Remote()->SendRequest(CREATE_WINDOW_TOKEN, data, reply, option);
if (status != ErrorCode::NO_ERROR) {
return nullptr;
}
int code = reply.ReadException();
if (code != 0) { // code = 0, means no exception.
IMSA_HILOGE("Exception code = %d\n", code);
return nullptr;
}
sptr < IRemoteObject > token = reply.ReadRemoteObject();
return token;
}
int32_t destroyWindowToken(int userId, const std::u16string& packageName)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteInt32(userId);
data.WriteString16(packageName);
int32_t status = Remote()->SendRequest(DESTROY_WINDOW_TOKEN, data, reply, option);
if (status != ErrorCode::NO_ERROR) {
return status;
}
int code = reply.ReadException();
if (code != 0) {
// code = 0, means no exception.
return code;
}
return ErrorCode::NO_ERROR;
}
int32_t listInputMethod(int userId, std::vector<InputMethodProperty*> *inputMethodProperties)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteInt32(userId);
int32_t status = Remote()->SendRequest(LIST_INPUT_METHOD, data, reply, option);
if (status != ErrorCode::NO_ERROR) {
return status;
}
int code = reply.ReadException();
if (code != 0) {
// code = 0, means no exception.
return code;
}
int size = reply.ReadInt32();
for (int i = 0; i < size; i++) {
InputMethodProperty *property = new InputMethodProperty();
property = reply.ReadParcelable<InputMethodProperty>();
inputMethodProperties->push_back(property);
}
return ErrorCode::NO_ERROR;
}
virtual int32_t getInputMethodProperty(int userId, const std::u16string& packageName,
InputMethodProperty *inputMethodProperty)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteInt32(userId);
data.WriteString16(packageName);
int32_t status = Remote()->SendRequest(GET_INPUT_METHOD_PROPERTY, data, reply, option);
if (status != ErrorCode::NO_ERROR) {
return status;
}
int code = reply.ReadException();
if (code != 0) {
// code = 0, means no exception.
return code;
}
inputMethodProperty = reply.ReadParcelable<InputMethodProperty>();
return status;
}
int32_t getInputMethodSetting(int userId, InputMethodSetting *inputMethodSetting)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteInt32(userId);
int32_t status = Remote()->SendRequest(GET_INPUT_METHOD_SETTING, data, reply, option);
if (status != ErrorCode::NO_ERROR) {
return status;
}
int code = reply.ReadException();
if (code != 0) {
// code = 0, means no exception.
return code;
}
inputMethodSetting = reply.ReadParcelable<InputMethodSetting>();
return status;
}
int32_t setInputMethodSetting(int userId, const InputMethodSetting& inputMethodSetting)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteInt32(userId);
data.WriteParcelable(&inputMethodSetting);
int32_t status = Remote()->SendRequest(SET_INPUT_METHOD_SETTING, data, reply, option);
if (status != ErrorCode::NO_ERROR) {
return status;
}
int code = reply.ReadException();
if (code != 0) {
// code = 0, means no exception.
return code;
}
return ErrorCode::NO_ERROR;
}
};
}
}

View File

@ -1,45 +0,0 @@
/*
* 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 <string>
#include "iremote_proxy.h"
#include "iremote_object.h"
#include "global.h"
#include "i_platform_callback.h"
/*! \class PlatformCallbackProxy
\brief The proxy of IPlatformCallback
*/
namespace OHOS {
namespace MiscServices {
class PlatformCallbackProxy : public IRemoteProxy<IPlatformCallback> {
public:
PlatformCallbackProxy(const sptr<IRemoteObject>& impl) : IRemoteProxy<IPlatformCallback>(impl)
{
}
~PlatformCallbackProxy()
{
}
void notifyEvent(int eventId, int userId, const std::vector<std::u16string>& eventContent)
{
(void)eventId;
(void)userId;
(void)eventContent;
}
};
}
}