mirror of
https://github.com/openharmony/miscservices_inputmethod.git
synced 2026-07-20 23:45:31 -04:00
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
* 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 "securec.h"
|
||||
|
||||
#include "utils/log.h"
|
||||
#include "input_method_ability.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;
|
||||
};
|
||||
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;
|
||||
}
|
||||
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(const char* type, Event* event)
|
||||
{
|
||||
IMSA_HILOGI("EventTarget::Emit");
|
||||
napi_handle_scope scope = nullptr;
|
||||
napi_open_handle_scope(env_, &scope);
|
||||
|
||||
napi_value thisVar = nullptr;
|
||||
napi_get_reference_value(env_, thisVarRef_, &thisVar);
|
||||
for (EventListener* eventListener = first_; eventListener != nullptr; eventListener = eventListener->next) {
|
||||
if (strcmp(eventListener->type, type) == 0) {
|
||||
napi_value jsEvent = event ? event->ToJsObject() : nullptr;
|
||||
napi_value handler = nullptr;
|
||||
napi_value result = nullptr;
|
||||
napi_get_reference_value(env_, eventListener->handlerRef, &handler);
|
||||
napi_call_function(env_, thisVar, handler, jsEvent ? 1 : 0, jsEvent ? &jsEvent : nullptr, &result);
|
||||
if (eventListener->isOnce) {
|
||||
Off(type, handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
napi_close_handle_scope(env_, scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "input_method_ability.h"
|
||||
#include "input_method_core_proxy.h"
|
||||
#include "input_method_core_stub.h"
|
||||
#include "input_method_agent_proxy.h"
|
||||
#include "input_method_agent_stub.h"
|
||||
#include "message_parcel.h"
|
||||
#include "event_target.h"
|
||||
#include "iservice_registry.h"
|
||||
#include "system_ability_definition.h"
|
||||
#include "input_data_channel_proxy.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
using namespace MessageID;
|
||||
sptr<InputMethodAbility> InputMethodAbility::instance_;
|
||||
std::mutex InputMethodAbility::instanceLock_;
|
||||
|
||||
InputMethodAbility::InputMethodAbility() {
|
||||
Initialize();
|
||||
OnConnect();
|
||||
}
|
||||
|
||||
InputMethodAbility::~InputMethodAbility() {
|
||||
if (msgHandler != nullptr) {
|
||||
delete msgHandler;
|
||||
}
|
||||
}
|
||||
|
||||
sptr<InputMethodAbility> InputMethodAbility::GetInstance() {
|
||||
IMSA_HILOGI("InputMethodAbility::GetInstance");
|
||||
if (instance_ == nullptr) {
|
||||
std::lock_guard<std::mutex> autoLock(instanceLock_);
|
||||
if (instance_ == nullptr) {
|
||||
IMSA_HILOGI("InputMethodAbility::GetInstance need new IMA");
|
||||
instance_ = new InputMethodAbility();
|
||||
}
|
||||
}
|
||||
return instance_;
|
||||
}
|
||||
|
||||
sptr<InputMethodSystemAbilityProxy> InputMethodAbility::GetImsaProxy() {
|
||||
IMSA_HILOGI("InputMethodAbility::GetImsaProxy");
|
||||
sptr<ISystemAbilityManager> systemAbilityManager =
|
||||
SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
|
||||
if (systemAbilityManager == nullptr) {
|
||||
IMSA_HILOGI("InputMethodAbility::GetImsaProxy systemAbilityManager is nullptr");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto systemAbility = systemAbilityManager->GetSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID, "");
|
||||
if (systemAbility == nullptr) {
|
||||
IMSA_HILOGI("InputMethodAbility::GetImsaProxy systemAbility is nullptr");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sptr<InputMethodSystemAbilityProxy> iface = new InputMethodSystemAbilityProxy(systemAbility);
|
||||
return iface;
|
||||
}
|
||||
|
||||
sptr<IInputMethodCore> InputMethodAbility::OnConnect() {
|
||||
IMSA_HILOGI("InputMethodAbility::OnConnect");
|
||||
mImms = GetImsaProxy();
|
||||
sptr<InputMethodCoreStub> stub = new InputMethodCoreStub(0);
|
||||
stub->SetMessageHandler(msgHandler);
|
||||
sptr<IInputMethodCore> stub2=stub;
|
||||
if (mImms != nullptr) {
|
||||
mImms->setInputMethodCore(stub2);
|
||||
}
|
||||
IMSA_HILOGI("InputMethodAbility::OnConnect() mImms is nullptr");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void InputMethodAbility::Initialize() {
|
||||
IMSA_HILOGI("InputMethodAbility::Initialize");
|
||||
InitialInputWindow();
|
||||
msgHandler = new MessageHandler();
|
||||
workThreadHandler = std::thread([this]{WorkThread();});
|
||||
}
|
||||
|
||||
void InputMethodAbility::setEventTarget(sptr<EventTarget> &eventTarget) {
|
||||
IMSA_HILOGI("InputMethodAbility::setEventTarget");
|
||||
eventTarget_ = eventTarget;
|
||||
}
|
||||
|
||||
void InputMethodAbility::WorkThread() {
|
||||
while(1){
|
||||
Message* msg = msgHandler->GetMessage();
|
||||
switch(msg->msgId_) {
|
||||
case MSG_ID_INITIALIZE_INPUT: {
|
||||
OnInitialInput(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;
|
||||
}
|
||||
|
||||
default:{
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete msg;
|
||||
}
|
||||
}
|
||||
|
||||
void InputMethodAbility::OnInitialInput(Message* msg) {
|
||||
IMSA_HILOGI("InputMethodAbility::OnInitialInput");
|
||||
MessageParcel* data = msg->msgContent_;
|
||||
displyId = data->ReadInt32();
|
||||
sptr<IRemoteObject> channelObject = data->ReadRemoteObject();
|
||||
if (channelObject == nullptr) {
|
||||
IMSA_HILOGI("InputMethodAbility::OnInitialInput channelObject is nullptr");
|
||||
return;
|
||||
}
|
||||
sptr<InputControlChannelProxy> channelProxy=new InputControlChannelProxy(channelObject);
|
||||
inputControlChannel = channelProxy;
|
||||
if(inputControlChannel == nullptr) {
|
||||
IMSA_HILOGI("InputMethodAbility::OnInitialInput inputControlChannel is nullptr");
|
||||
return;
|
||||
}
|
||||
InitialInputWindow();
|
||||
}
|
||||
|
||||
void InputMethodAbility::OnStartInput(Message* msg) {
|
||||
IMSA_HILOGI("InputMethodAbility::OnStartInput");
|
||||
MessageParcel* data = msg->msgContent_;
|
||||
sptr<InputDataChannelProxy> channalProxy = new InputDataChannelProxy(data->ReadRemoteObject());
|
||||
inputDataChannel = channalProxy;
|
||||
if(inputDataChannel == nullptr) {
|
||||
IMSA_HILOGI("InputMethodAbility::OnStartInput inputDataChannel is nullptr");
|
||||
}
|
||||
editorAttribute = data->ReadParcelable<InputAttribute>();
|
||||
if(editorAttribute == nullptr) {
|
||||
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");
|
||||
ShowInputWindow();
|
||||
}
|
||||
|
||||
void InputMethodAbility::OnHideKeyboard(Message* msg) {
|
||||
IMSA_HILOGI("InputMethodAbility::OnHideKeyboard");
|
||||
DissmissInputWindow();
|
||||
}
|
||||
|
||||
void InputMethodAbility::OnStopInput(Message* msg) {
|
||||
IMSA_HILOGI("InputMethodAbility::OnStopInput");
|
||||
if (writeInputChannel != nullptr) {
|
||||
delete writeInputChannel;
|
||||
}
|
||||
}
|
||||
|
||||
bool InputMethodAbility::DispatchKey(Message* msg) {
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
||||
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("keyboardShow",nullptr);
|
||||
}
|
||||
|
||||
void InputMethodAbility::DissmissInputWindow() {
|
||||
IMSA_HILOGI("InputMethodAbility::DissmissInputWindow");
|
||||
eventTarget_->Emit("keyboardHide",nullptr);
|
||||
}
|
||||
|
||||
bool InputMethodAbility::InsertText(const std::string text) {
|
||||
IMSA_HILOGI("InputMethodAbility::InsertText");
|
||||
if (inputDataChannel == nullptr){
|
||||
IMSA_HILOGI("InputMethodAbility::InsertText inputDataChanel is nullptr");
|
||||
return false;
|
||||
}
|
||||
|
||||
return inputDataChannel->InsertText(Utils::to_utf16(text));
|
||||
}
|
||||
|
||||
void InputMethodAbility::DeleteBackward(int32_t length) {
|
||||
IMSA_HILOGI("InputMethodAbility::DeleteBackward");
|
||||
if (inputDataChannel == nullptr){
|
||||
IMSA_HILOGI("InputMethodAbility::DeleteBackward inputDataChanel is nullptr");
|
||||
return;
|
||||
}
|
||||
inputDataChannel->DeleteBackward(length);
|
||||
}
|
||||
|
||||
void InputMethodAbility::HideKeyboardSelf() {
|
||||
IMSA_HILOGI("InputMethodAbility::HideKeyboardSelf");
|
||||
inputControlChannel->hideKeyboardSelf(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "input_method_agent_proxy.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
using namespace ErrorCode;
|
||||
InputMethodAgentProxy::InputMethodAgentProxy(const sptr<IRemoteObject> &object) : IRemoteProxy<IInputMethodAgent>(object) {
|
||||
}
|
||||
|
||||
int32_t InputMethodAgentProxy::DispatchKey(int32_t key, int32_t status) {
|
||||
IMSA_HILOGI("InputMethodAgentProxy::DispatchKey key = %{public}d, status = %{public}d", key, status);
|
||||
MessageParcel data, reply;
|
||||
MessageOption option;
|
||||
if (!data.WriteInterfaceToken(GetDescriptor())) {
|
||||
IMSA_HILOGI("InputMethodAgentProxy::DispatchKey descriptor is not match");
|
||||
return ERROR_EX_PARCELABLE;
|
||||
}
|
||||
|
||||
data.WriteInt32(key);
|
||||
data.WriteInt32(status);
|
||||
|
||||
auto ret = Remote()->SendRequest(DISPATCH_KEY, data, reply, option);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "input_method_agent_stub.h"
|
||||
#include "global.h"
|
||||
#include "message_handler.h"
|
||||
#include "message.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
using namespace MessageID;
|
||||
|
||||
InputMethodAgentStub::InputMethodAgentStub() {
|
||||
}
|
||||
|
||||
InputMethodAgentStub::~InputMethodAgentStub() {
|
||||
}
|
||||
|
||||
int32_t InputMethodAgentStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) {
|
||||
IMSA_HILOGI("InputMethodAgentStub::OnRemoteRequest code = %{public}d", code);
|
||||
auto descriptorToken = data.ReadInterfaceToken();
|
||||
if (descriptorToken != GetDescriptor()) {
|
||||
return ErrorCode::ERROR_STATUS_UNKNOWN_TRANSACTION;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
default: {
|
||||
return IRemoteStub::OnRemoteRequest(code, data, reply, option);
|
||||
}
|
||||
}
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
|
||||
int32_t InputMethodAgentStub::DispatchKey(int32_t key, int32_t status) {
|
||||
IMSA_HILOGI("InputMethodAgentStub::DispatchKey key = %{public}d, status = %{public}d", key, status);
|
||||
if (msgHandler_ == nullptr) {
|
||||
return ErrorCode::ERROR_NULL_POINTER;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
void InputMethodAgentStub::SetMessageHandler(MessageHandler* msgHandler) {
|
||||
msgHandler_ = msgHandler;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "input_method_core_proxy.h"
|
||||
#include "message_parcel.h"
|
||||
#include "message_option.h"
|
||||
#include "input_attribute.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
InputMethodCoreProxy::InputMethodCoreProxy(const OHOS::sptr<OHOS::IRemoteObject> &impl) : IRemoteProxy<IInputMethodCore>(impl) {
|
||||
}
|
||||
|
||||
InputMethodCoreProxy::~InputMethodCoreProxy() = default;
|
||||
|
||||
int32_t InputMethodCoreProxy::initializeInput(sptr<IRemoteObject> &startInputToken, int32_t displayId, sptr<IInputControlChannel> &inputControlChannel) {
|
||||
IMSA_HILOGI("InputMethodCoreProxy::initializeInput");
|
||||
if (startInputToken == nullptr) {
|
||||
IMSA_HILOGI("InputMethodCoreProxy::initializeInput startInputToken is nullptr");
|
||||
}
|
||||
|
||||
if (inputControlChannel == nullptr) {
|
||||
IMSA_HILOGI("InputMethodCoreProxy::initializeInput inputControlChannel is nullptr");
|
||||
}
|
||||
IMSA_HILOGI("InputMethodCoreProxy::initializeInput displayId = %{public}d", displayId);
|
||||
MessageParcel data, reply;
|
||||
data.WriteInterfaceToken(GetDescriptor());
|
||||
data.WriteInt32(displayId);
|
||||
sptr<IRemoteObject> channelObject = inputControlChannel->AsObject();
|
||||
if (channelObject == nullptr) {
|
||||
IMSA_HILOGI("InputMethodCoreProxy::initializeInput channelObject is nullptr");
|
||||
}
|
||||
bool wor = data.WriteRemoteObject(channelObject);
|
||||
if (wor) {
|
||||
IMSA_HILOGI("InputMethodCoreProxy::initializeInput Success to write inputControlChannel");
|
||||
} else {
|
||||
IMSA_HILOGI("InputMethodCoreProxy::initializeInput Failed to write inputControlChannel");
|
||||
}
|
||||
MessageOption option { MessageOption::TF_SYNC };
|
||||
int32_t status = Remote()->SendRequest(INITIALIZE_INPUT, data, reply, option);
|
||||
if (status != ErrorCode::NO_ERROR) {
|
||||
IMSA_HILOGI("InputMethodCoreProxy::initializeInput 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) {
|
||||
IMSA_HILOGI("InputMethodCoreProxy::startInput");
|
||||
if (inputDataChannel == nullptr) {
|
||||
IMSA_HILOGI("InputMethodCoreProxy::startInput inputDataChannel is nullptr");
|
||||
}
|
||||
|
||||
MessageParcel data;
|
||||
if (!(data.WriteInterfaceToken(GetDescriptor())
|
||||
&& data.WriteRemoteObject(inputDataChannel->AsObject())
|
||||
&& data.WriteParcelable(&editorAttribute)
|
||||
&& data.WriteBool(supportPhysicalKbd))) {
|
||||
IMSA_HILOGI("InputMethodCoreProxy::startInput write error");
|
||||
return false;
|
||||
}
|
||||
MessageParcel reply;
|
||||
MessageOption option { MessageOption::TF_SYNC };
|
||||
|
||||
int32_t status = Remote()->SendRequest(START_INPUT, data, reply, option);
|
||||
if (status != ErrorCode::NO_ERROR) {
|
||||
IMSA_HILOGI("InputMethodCoreProxy::startInput status = %{public}d", status);
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t code = reply.ReadException();
|
||||
return code == ErrorCode::NO_ERROR;
|
||||
}
|
||||
|
||||
int32_t InputMethodCoreProxy::stopInput() {
|
||||
IMSA_HILOGI("InputMethodCoreProxy::stopInput");
|
||||
MessageParcel data, reply;
|
||||
data.WriteInterfaceToken(GetDescriptor());
|
||||
MessageOption option { MessageOption::TF_SYNC };
|
||||
int32_t status = Remote()->SendRequest(STOP_INPUT, data, reply, option);
|
||||
if (status != ErrorCode::NO_ERROR) {
|
||||
IMSA_HILOGI("InputMethodCoreProxy::stopInput status = %{public}d",status);
|
||||
return status;
|
||||
}
|
||||
int code = reply.ReadException();
|
||||
if (code != ErrorCode::NO_ERROR) {
|
||||
IMSA_HILOGI("InputMethodCoreProxy::stopInput code = %{public}d",code);
|
||||
return code;
|
||||
}
|
||||
return reply.ReadInt32();
|
||||
}
|
||||
|
||||
bool InputMethodCoreProxy::showKeyboard(int32_t flags) {
|
||||
IMSA_HILOGI("InputMethodCoreProxy::showKeyboard");
|
||||
auto remote = Remote();
|
||||
if (remote == nullptr){
|
||||
IMSA_HILOGI("InputMethodCoreProxy::showKeyboard remote is nullptr");
|
||||
return false;
|
||||
}
|
||||
|
||||
MessageParcel data;
|
||||
if (!(data.WriteInterfaceToken(GetDescriptor()) && data.WriteInt32(flags))) {
|
||||
return false;
|
||||
}
|
||||
MessageParcel reply;
|
||||
MessageOption option{ MessageOption::TF_SYNC };
|
||||
|
||||
int32_t res = remote->SendRequest(SHOW_KEYBOARD, data, reply, option);
|
||||
if (res != ErrorCode::NO_ERROR) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InputMethodCoreProxy::hideKeyboard(int32_t flags) {
|
||||
IMSA_HILOGI("InputMethodCoreProxy::hideKeyboard");
|
||||
auto remote = Remote();
|
||||
if (remote == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MessageParcel data;
|
||||
if (!(data.WriteInterfaceToken(GetDescriptor()) && data.WriteInt32(flags))) {
|
||||
return false;
|
||||
}
|
||||
MessageParcel reply;
|
||||
MessageOption option{ MessageOption::TF_SYNC };
|
||||
|
||||
int32_t res = remote->SendRequest(HIDE_KEYBOARD, data, reply, option);
|
||||
if (res != ErrorCode::NO_ERROR) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t InputMethodCoreProxy::setKeyboardType(const KeyboardType& type) {
|
||||
IMSA_HILOGI("InputMethodCoreProxy::setKeyboardType");
|
||||
MessageParcel data, reply;
|
||||
data.WriteInterfaceToken(GetDescriptor());
|
||||
data.WriteParcelable(&type);
|
||||
MessageOption option{ MessageOption::TF_SYNC };
|
||||
int32_t status = Remote()->SendRequest(SET_KEYBOARD_TYPE, data, reply, option);
|
||||
if (status != ErrorCode::NO_ERROR) {
|
||||
return status;
|
||||
}
|
||||
int32_t code = reply.ReadException();
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t InputMethodCoreProxy::getKeyboardWindowHeight(int32_t * retHeight) {
|
||||
IMSA_HILOGI("InputMethodCoreProxy::getKeyboardWindowHeight");
|
||||
MessageParcel data, reply;
|
||||
data.WriteInterfaceToken(GetDescriptor());
|
||||
MessageOption option { MessageOption::TF_SYNC };
|
||||
int32_t status = Remote()->SendRequest(GET_KEYBOARD_WINDOW_HEIGHT, data, reply, option);
|
||||
if (status != ErrorCode::NO_ERROR) {
|
||||
return status;
|
||||
}
|
||||
int32_t code = reply.ReadException();
|
||||
if (code != 0) {
|
||||
return code;
|
||||
}
|
||||
*retHeight = reply.ReadInt32();
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* 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 <chrono>
|
||||
#include <stdint.h>
|
||||
#include "message_handler.h"
|
||||
#include "i_input_data_channel.h"
|
||||
#include "input_method_core_stub.h"
|
||||
#include "input_channel.h"
|
||||
#include "i_input_method_proxy.h"
|
||||
#include "platform.h"
|
||||
#include "message_parcel.h"
|
||||
#include "input_control_channel_proxy.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace MiscServices {
|
||||
using namespace MessageID;
|
||||
/**
|
||||
* param userId the id of the user to whom the object is linking
|
||||
* @param userId
|
||||
*/
|
||||
InputMethodCoreStub::InputMethodCoreStub(int userId) {
|
||||
userId_ = userId;
|
||||
}
|
||||
|
||||
InputMethodCoreStub::~InputMethodCoreStub() {
|
||||
}
|
||||
|
||||
int32_t InputMethodCoreStub::OnRemoteRequest(uint32_t code, MessageParcel & data, MessageParcel & reply, MessageOption & option) {
|
||||
IMSA_HILOGI("InputMethodCoreStub::OnRemoteRequest");
|
||||
auto descriptorToken = data.ReadInterfaceToken();
|
||||
if (descriptorToken != GetDescriptor()) {
|
||||
IMSA_HILOGI("InputMethodCoreStub::OnRemoteRequest descriptorToken is invalid");
|
||||
return ErrorCode::ERROR_STATUS_UNKNOWN_TRANSACTION;
|
||||
}
|
||||
switch (code) {
|
||||
case INITIALIZE_INPUT: {
|
||||
sptr<IRemoteObject> startInputToken = nullptr;
|
||||
int32_t displayId = data.ReadInt32();
|
||||
IMSA_HILOGI("InputMethodCoreStub::OnRemoteRequest displayId = %{public}d", displayId);
|
||||
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");
|
||||
}
|
||||
|
||||
initializeInput(startInputToken, displayId, inputControlChannel);
|
||||
reply.WriteNoException();
|
||||
break;
|
||||
}
|
||||
case START_INPUT: {
|
||||
sptr<IInputDataChannel> inputDataChannel = iface_cast<IInputDataChannel>(data.ReadRemoteObject());
|
||||
InputAttribute* editorAttribute = data.ReadParcelable<InputAttribute>();
|
||||
bool supportPhysicalKbd = data.ReadBool();
|
||||
|
||||
if (inputDataChannel == nullptr) {
|
||||
IMSA_HILOGI("InputMethodCoreStub::OnRemoteRequest START_INPUT inputDataChannel is nulltpr");
|
||||
}
|
||||
startInput(inputDataChannel, *editorAttribute, supportPhysicalKbd);
|
||||
reply.WriteNoException();
|
||||
break;
|
||||
}
|
||||
case STOP_INPUT: {
|
||||
stopInput();
|
||||
reply.WriteNoException();
|
||||
break;
|
||||
}
|
||||
case SHOW_KEYBOARD: {
|
||||
int32_t flags = data.ReadInt32();
|
||||
showKeyboard(flags);
|
||||
reply.WriteNoException();
|
||||
break;
|
||||
}
|
||||
case HIDE_KEYBOARD: {
|
||||
int32_t flags = data.ReadInt32();
|
||||
hideKeyboard(flags);
|
||||
reply.WriteNoException();
|
||||
break;
|
||||
}
|
||||
case SET_KEYBOARD_TYPE: {
|
||||
KeyboardType* type = data.ReadParcelable<KeyboardType>();
|
||||
setKeyboardType(*type);
|
||||
reply.WriteNoException();
|
||||
break;
|
||||
}
|
||||
case GET_KEYBOARD_WINDOW_HEIGHT: {
|
||||
int32_t* retHeight = nullptr;
|
||||
getKeyboardWindowHeight(retHeight);
|
||||
reply.WriteNoException();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
return IRemoteStub::OnRemoteRequest(code, data, reply, option);
|
||||
}
|
||||
}
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
int32_t InputMethodCoreStub::initializeInput(sptr<IRemoteObject>& startInputToken, int32_t displayId, sptr<IInputControlChannel>& inputControlChannel) {
|
||||
IMSA_HILOGI("InputMethodCoreStub::initializeInput");
|
||||
if (msgHandler_==nullptr) {
|
||||
return ErrorCode::ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
if (startInputToken == nullptr) {
|
||||
IMSA_HILOGI("InputMethodCoreStub::initializeInput startInputToken is nullptr");
|
||||
}
|
||||
|
||||
MessageParcel* data = new MessageParcel();
|
||||
data->WriteInt32(displayId);
|
||||
if (inputControlChannel != nullptr) {
|
||||
IMSA_HILOGI("InputMethodCoreStub::initializeInput. inputControlChannel is not nullptr");
|
||||
data->WriteRemoteObject(inputControlChannel->AsObject());
|
||||
}
|
||||
Message* msg = new Message(MessageID::MSG_ID_INITIALIZE_INPUT, data);
|
||||
msgHandler_->SendMessage(msg);
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
|
||||
bool InputMethodCoreStub::startInput(const sptr<IInputDataChannel>& inputDataChannel, const InputAttribute& editorAttribute, bool supportPhysicalKbd) {
|
||||
IMSA_HILOGI("InputMethodCoreStub::startInput");
|
||||
if (msgHandler_ == nullptr) {
|
||||
return ErrorCode::ERROR_NULL_POINTER;
|
||||
}
|
||||
MessageParcel* data = new MessageParcel();
|
||||
if (inputDataChannel !=nullptr) {
|
||||
IMSA_HILOGI("InputMethodCoreStub::startInput inputDataChannel is not nullptr");
|
||||
data->WriteRemoteObject(inputDataChannel->AsObject());
|
||||
}
|
||||
data->WriteParcelable(&editorAttribute);
|
||||
data->WriteBool(supportPhysicalKbd);
|
||||
Message* msg = new Message(MessageID::MSG_ID_START_INPUT, data);
|
||||
msgHandler_->SendMessage(msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t InputMethodCoreStub::stopInput() {
|
||||
IMSA_HILOGI("InputMethodCoreStub::stopInput");
|
||||
if (msgHandler_ == nullptr) {
|
||||
return ErrorCode::ERROR_NULL_POINTER;
|
||||
}
|
||||
MessageParcel* data = new MessageParcel();
|
||||
Message* msg = new Message(MessageID::MSG_ID_STOP_INPUT, data);
|
||||
msgHandler_->SendMessage(msg);
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
|
||||
bool InputMethodCoreStub::showKeyboard(int32_t flags) {
|
||||
IMSA_HILOGI("InputMethodCoreStub::showKeyboard");
|
||||
if (msgHandler_==nullptr) {
|
||||
return false;
|
||||
}
|
||||
MessageParcel* data = new MessageParcel();
|
||||
data->WriteInt32(userId_);
|
||||
data->WriteInt32(flags);
|
||||
|
||||
Message* msg = new Message(MessageID::MSG_ID_SHOW_KEYBOARD, data);
|
||||
msgHandler_->SendMessage(msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InputMethodCoreStub::hideKeyboard(int32_t flags) {
|
||||
IMSA_HILOGI("InputMethodCoreStub::hideKeyboard");
|
||||
if (msgHandler_==nullptr) {
|
||||
return ErrorCode::ERROR_NULL_POINTER;
|
||||
}
|
||||
MessageParcel* data = new MessageParcel();
|
||||
data->WriteInt32(userId_);
|
||||
data->WriteInt32(flags);
|
||||
|
||||
Message* msg = new Message(MessageID::MSG_ID_HIDE_KEYBOARD, data);
|
||||
msgHandler_->SendMessage(msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t InputMethodCoreStub::setKeyboardType(const KeyboardType& type) {
|
||||
IMSA_HILOGI("InputMethodCoreStub::setKeyboardType");
|
||||
if (msgHandler_==nullptr) {
|
||||
return ErrorCode::ERROR_NULL_POINTER;
|
||||
}
|
||||
MessageParcel* data = new MessageParcel();
|
||||
data->WriteParcelable(&type);
|
||||
|
||||
Message* msg = new Message(MessageID::MSG_ID_SET_KEYBOARD_TYPE, data);
|
||||
msgHandler_->SendMessage(msg);
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
|
||||
int32_t InputMethodCoreStub::getKeyboardWindowHeight(int32_t * retHeight) {
|
||||
IMSA_HILOGI("InputMethodCoreStub::getKeyboardWindowHeight");
|
||||
if (msgHandler_==nullptr) {
|
||||
return ErrorCode::ERROR_NULL_POINTER;
|
||||
}
|
||||
MessageParcel* data = new MessageParcel();
|
||||
|
||||
Message* msg = new Message(MessageID::MSG_ID_GET_KEYBOARD_WINDOW_HEIGHT, data);
|
||||
msgHandler_->SendMessage(msg);
|
||||
return ErrorCode::NO_ERROR;
|
||||
}
|
||||
|
||||
void InputMethodCoreStub::SetMessageHandler(MessageHandler* msgHandler) {
|
||||
msgHandler_=msgHandler;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user