Merge branch 'master' of gitee.com:openharmony/inputmethod_imf into master

Signed-off-by: Hollokin <taoyuxin2@huawei.com>
This commit is contained in:
Hollokin 2022-09-29 03:36:35 +00:00 committed by Gitee
commit 6ba89a0785
41 changed files with 2344 additions and 612 deletions

View File

@ -75,32 +75,12 @@
"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",
"i_input_data_channel.h",
"input_method_controller.h",
"input_method_system_ability_proxy.h",
"input_method_utils.h"
],
"header_base": "//base/inputmethod/imf/frameworks/inputmethod_controller/include"
}
},
{
"name": "//base/inputmethod/imf/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/inputmethod/imf/frameworks/inputmethod_ability/include"
}
}
],
"test": [

View File

@ -26,10 +26,7 @@ ohos_shared_library("inputmethod_para") {
sources = [ "src/para_handle.cpp" ]
configs = [ ":inputmethod_para_config" ]
deps = []
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"init:libbegetutil",
]
external_deps = [ "init:libbegetutil" ]
public_configs = [ ":inputmethod_para_public_config" ]
subsystem_name = "inputmethod"
part_name = "imf"

View File

@ -18,6 +18,7 @@ config("inputmethod_ability_native_config") {
visibility = [ ":*" ]
include_dirs = [
"include",
"//foundation/multimodalinput/input/interfaces/native/innerkits/event/include",
"${inputmethod_path}/frameworks/inputmethod_controller/include",
"${inputmethod_path}/interfaces/kits/js/napi/inputmethodengine/include",
"${inputmethod_path}/services/include",
@ -52,23 +53,13 @@ ohos_shared_library("inputmethod_ability") {
configs = [ ":inputmethod_ability_native_config" ]
deps = [
"${ability_runtime_inner_api_path}/ability_manager:ability_manager",
"${ability_runtime_inner_api_path}/app_manager:app_manager",
"//base/global/resource_management/frameworks/resmgr:global_resmgr",
"//foundation/arkui/napi/:ace_napi",
"//base/inputmethod/imf/etc/para:inputmethod_para",
"//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core",
"//foundation/communication/ipc/interfaces/innerkits/ipc_single:ipc_single",
"//foundation/multimodalinput/input/frameworks/proxy:libmmi-client",
"//foundation/systemabilitymgr/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
]
external_deps = [
"ability_base:want",
"ability_runtime:runtime",
"bundle_framework:appexecfwk_base",
"bundle_framework:appexecfwk_core",
"c_utils:utils",
"eventhandler:libeventhandler",
"hiviewdfx_hilog_native:libhilog",
]

View File

@ -84,6 +84,11 @@ namespace MiscServices {
static sptr<InputMethodAbility> instance_;
sptr<InputMethodSystemAbilityProxy> mImms;
struct ServiceDeathRecipient : public IRemoteObject::DeathRecipient {
std::shared_ptr<InputMethodEngineListener> listener{ nullptr };
void OnRemoteDied(const wptr<IRemoteObject> &object) override;
};
sptr<ServiceDeathRecipient> deathRecipientPtr_{ nullptr };
sptr<InputMethodSystemAbilityProxy> GetImsaProxy();
void SetInputDataChannel(sptr<IRemoteObject> &object);
@ -108,6 +113,8 @@ namespace MiscServices {
void InitialInputWindow();
void ShowInputWindow(bool isShowKeyboard);
void DissmissInputWindow();
void BindServiceAndClient();
};
} // namespace MiscServices
} // namespace OHOS

View File

@ -12,16 +12,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "input_method_ability.h"
#include "string_ex.h"
#include <para_handle.h>
#include <unistd.h>
#include "input_method_agent_proxy.h"
#include "input_method_agent_stub.h"
#include "message_parcel.h"
#include "system_ability_definition.h"
#include "input_method_utils.h"
#include "iservice_registry.h"
#include "input_method_core_proxy.h"
#include "input_method_core_stub.h"
#include "input_method_utils.h"
#include "iservice_registry.h"
#include "message_parcel.h"
#include "string_ex.h"
#include "system_ability_definition.h"
namespace OHOS {
namespace MiscServices {
@ -65,16 +70,26 @@ namespace MiscServices {
IMSA_HILOGI("InputMethodAbility::GetImsaProxy");
sptr<ISystemAbilityManager> systemAbilityManager =
SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (!systemAbilityManager) {
if (systemAbilityManager == nullptr) {
IMSA_HILOGI("InputMethodAbility::GetImsaProxy systemAbilityManager is nullptr");
return nullptr;
}
auto systemAbility = systemAbilityManager->GetSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID, "");
if (!systemAbility) {
if (systemAbility == nullptr) {
IMSA_HILOGI("InputMethodAbility::GetImsaProxy systemAbility is nullptr");
return nullptr;
}
if (deathRecipientPtr_ == nullptr) {
deathRecipientPtr_ = new (std::nothrow) ServiceDeathRecipient();
if (deathRecipientPtr_ == nullptr) {
IMSA_HILOGE("new ServiceDeathRecipient failed");
return nullptr;
}
}
if ((systemAbility->IsProxyObject()) && (!systemAbility->AddDeathRecipient(deathRecipientPtr_))) {
IMSA_HILOGE("failed to add death recipient.");
}
sptr<InputMethodSystemAbilityProxy> iface = new InputMethodSystemAbilityProxy(systemAbility);
return iface;
@ -90,7 +105,6 @@ namespace MiscServices {
}
sptr<InputMethodCoreStub> stub = new InputMethodCoreStub(0);
stub->SetMessageHandler(msgHandler);
sptr<IInputMethodCore> stub2 = stub;
sptr<InputMethodAgentStub> inputMethodAgentStub(new InputMethodAgentStub());
inputMethodAgentStub->SetMessageHandler(msgHandler);
@ -98,11 +112,11 @@ namespace MiscServices {
MessageParcel data;
if (!(data.WriteInterfaceToken(mImms->GetDescriptor())
&& data.WriteRemoteObject(stub2->AsObject())
&& data.WriteRemoteObject(stub->AsObject())
&& data.WriteRemoteObject(inputMethodAgent->AsObject()))) {
return;
}
mImms->SetCoreAndAgent(data);
mImms->SetCoreAndAgentDeprecated(data);
}
void InputMethodAbility::Initialize()
@ -119,15 +133,18 @@ namespace MiscServices {
void InputMethodAbility::setImeListener(std::shared_ptr<InputMethodEngineListener> imeListener)
{
IMSA_HILOGI("InputMethodAbility::setImeListener");
if (!imeListener_) {
if (imeListener_ == nullptr) {
imeListener_ = imeListener;
}
if (deathRecipientPtr_ != nullptr && deathRecipientPtr_->listener == nullptr) {
deathRecipientPtr_->listener = imeListener_;
}
}
void InputMethodAbility::setKdListener(std::shared_ptr<KeyboardListener> kdListener)
{
IMSA_HILOGI("InputMethodAbility::setKdListener");
if (!kdListener_) {
if (kdListener_ == nullptr) {
kdListener_ = kdListener;
}
}
@ -517,5 +534,37 @@ namespace MiscServices {
std::lock_guard<std::mutex> lock(controlChannelLock_);
return controlChannel_;
}
void InputMethodAbility::ServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
{
IMSA_HILOGI("ServiceDeathRecipient::OnRemoteDied");
if (listener != nullptr) {
listener->OnInputStop(ParaHandle::GetDefaultIme(Utils::ToUserId(IPCSkeleton::GetCallingUid())));
}
}
void InputMethodAbility::BindServiceAndClient()
{
IMSA_HILOGI("InputMethodAbility::BindServiceAndClient");
mImms = GetImsaProxy();
if (mImms == nullptr) {
IMSA_HILOGI("mImms is nullptr");
return;
}
sptr<InputMethodCoreStub> stub = new InputMethodCoreStub(0);
stub->SetMessageHandler(msgHandler);
sptr<InputMethodAgentStub> inputMethodAgentStub(new InputMethodAgentStub());
inputMethodAgentStub->SetMessageHandler(msgHandler);
sptr<IInputMethodAgent> inputMethodAgent = sptr(new InputMethodAgentProxy(inputMethodAgentStub));
MessageParcel data;
if (!(data.WriteInterfaceToken(mImms->GetDescriptor())
&& data.WriteRemoteObject(stub->AsObject())
&& data.WriteRemoteObject(inputMethodAgent->AsObject()))) {
return;
}
mImms->SetCoreAndAgent(data);
}
} // namespace MiscServices
} // namespace OHOS

View File

@ -58,9 +58,7 @@ ohos_shared_library("inputmethod_client") {
deps = [
"${inputmethod_path}/services/dfx:inputmethod_dfx_static",
"//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core",
"//foundation/communication/ipc/interfaces/innerkits/ipc_single:ipc_single",
"//foundation/multimodalinput/input/frameworks/proxy:libmmi-common",
"//foundation/systemabilitymgr/safwk/interfaces/innerkits/safwk:system_ability_fwk",
"//foundation/systemabilitymgr/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
]

View File

@ -22,20 +22,18 @@
#include "global.h"
#include "i_input_method_agent.h"
#include "input_client_stub.h"
#include "input_data_channel_stub.h"
#include "input_method_agent_proxy.h"
#include "input_method_system_ability_proxy.h"
#include "input_method_utils.h"
#include "ipc_skeleton.h"
#include "iremote_object.h"
#include "key_event.h"
#include "message_handler.h"
#include "i_input_client.h"
#include "input_method_property.h"
#include "i_input_data_channel.h"
#include "i_input_method_system_ability.h"
namespace OHOS {
namespace MiscServices {
class InputDataChannelStub;
class InputMethodSystemAbilityProxy;
class OnTextChangedListener : public virtual RefBase {
public:
virtual void InsertText(const std::u16string& text) = 0;
@ -75,39 +73,45 @@ namespace MiscServices {
void OnSelectionChange(std::u16string text, int start, int end);
void OnConfigurationChange(Configuration info);
bool dispatchKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent);
int32_t DisplayOptionalInputMethod();
std::vector<Property> ListInputMethodCommon(InputMethodStatus status);
std::vector<Property> ListInputMethod();
std::vector<Property> ListInputMethod(bool enable);
int32_t GetEnterKeyType();
int32_t GetInputPattern();
std::shared_ptr<Property> GetCurrentInputMethod();
int32_t HideCurrentInput();
int32_t ShowCurrentInput();
void SetCallingWindow(uint32_t windowId);
int32_t SwitchInputMethod(const Property &target);
int32_t ShowSoftKeyboard();
int32_t HideSoftKeyboard();
int32_t ShowOptionalInputMethod();
// Deprecated innerkits with no permission check, kept for compatibility
int32_t ShowCurrentInput();
int32_t HideCurrentInput();
int32_t DisplayOptionalInputMethod();
private:
InputMethodController();
~InputMethodController();
bool Initialize();
sptr<InputMethodSystemAbilityProxy> GetImsaProxy();
void PrepareInput(int32_t displayId, sptr<InputClientStub> &client, sptr<InputDataChannelStub> &channel,
sptr<IInputMethodSystemAbility> GetImsaProxy();
void PrepareInput(int32_t displayId, sptr<IInputClient> &client, sptr<IInputDataChannel> &channel,
InputAttribute &attribute);
void StartInput(sptr<InputClientStub> &client, bool isShowKeyboard);
void StopInput(sptr<InputClientStub> &client);
void ReleaseInput(sptr<InputClientStub> &client);
void StartInput(sptr<IInputClient> &client, bool isShowKeyboard);
void StopInput(sptr<IInputClient> &client);
void ReleaseInput(sptr<IInputClient> &client);
void SetInputMethodAgent(sptr<IRemoteObject> &object);
std::shared_ptr<InputMethodAgentProxy> GetInputMethodAgent();
std::shared_ptr<IInputMethodAgent> GetInputMethodAgent();
void WorkThread();
int32_t SendDataByProxy(std::function<int32_t(sptr<IInputMethodSystemAbility> &, MessageParcel &)> callback);
sptr<InputDataChannelStub> mInputDataChannel;
sptr<InputClientStub> mClient;
sptr<InputMethodSystemAbilityProxy> mImms;
sptr<IInputDataChannel> mInputDataChannel;
sptr<IInputClient> mClient;
sptr<IInputMethodSystemAbility> mImms;
sptr<ImsaDeathRecipient> deathRecipient_;
std::mutex agentLock_;
std::shared_ptr<InputMethodAgentProxy> mAgent = nullptr;
std::shared_ptr<IInputMethodAgent> mAgent = nullptr;
sptr<OnTextChangedListener> textListener;
InputAttribute mAttribute;
std::u16string mTextString;

View File

@ -25,5 +25,4 @@ enum InputMethodStatus : uint32_t {
};
}
} // namespace OHOS
#endif //INPUTMETHOD_IMF_INPUT_METHOD_STATUS_H
#endif // INPUTMETHOD_IMF_INPUT_METHOD_STATUS_H

View File

@ -65,10 +65,17 @@ namespace MiscServices {
int32_t getCurrentKeyboardType(KeyboardType *retType) override;
std::vector<InputMethodProperty> ListInputMethod(InputMethodStatus stauts) override;
int32_t listKeyboardType(const std::u16string& imeId, std::vector<KeyboardType*> *types) override;
int32_t SwitchInputMethod(const InputMethodProperty &target);
int32_t SwitchInputMethod(const InputMethodProperty &target) override;
// Deprecated because of no permission check, kept for compatibility
int32_t DisplayOptionalInputMethodDeprecated(MessageParcel &data) override;
int32_t HideCurrentInputDeprecated(MessageParcel &data) override;
int32_t ShowCurrentInputDeprecated(MessageParcel &data) override;
void SetCoreAndAgentDeprecated(MessageParcel &data) override;
private:
static inline BrokerDelegator<InputMethodSystemAbilityProxy> delegator_;
int32_t SendRequestToService(MessageParcel &data, uint32_t code);
};
} // namespace MiscServices
} // namespace OHOS

View File

@ -0,0 +1,368 @@
/*
* Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_ITYPES_UTIL_H
#define FRAMEWORKS_INPUTMETHOD_CONTROLLER_INCLUDE_ITYPES_UTIL_H
#include <climits>
#include <memory>
#include "message_parcel.h"
#include "types.h"
namespace OHOS::MiscServices {
class ITypesUtil final {
public:
static bool Marshal(MessageParcel &data);
static bool Unmarshal(MessageParcel &data);
static bool Marshalling(bool input, MessageParcel &data);
static bool Unmarshalling(bool &output, MessageParcel &data);
static bool Marshalling(uint32_t input, MessageParcel &data);
static bool Unmarshalling(uint32_t &output, MessageParcel &data);
static bool Marshalling(int32_t input, MessageParcel &data);
static bool Unmarshalling(int32_t &output, MessageParcel &data);
static bool Marshalling(uint64_t input, MessageParcel &data);
static bool Unmarshalling(uint64_t &output, MessageParcel &data);
static bool Marshalling(const std::u16string &input, MessageParcel &data);
static bool Unmarshalling(std::u16string &output, MessageParcel &data);
static bool Marshalling(const std::string &input, MessageParcel &data);
static bool Unmarshalling(std::string &output, MessageParcel &data);
static bool Marshalling(const std::vector<uint8_t> &input, MessageParcel &data);
static bool Unmarshalling(std::vector<uint8_t> &output, MessageParcel &data);
static bool Marshalling(const sptr<IRemoteObject> &input, MessageParcel &data);
static bool Unmarshalling(sptr<IRemoteObject> &output, MessageParcel &data);
template<class T>
static bool Marshalling(const std::vector<T> &val, MessageParcel &parcel);
template<class T>
static bool Unmarshalling(std::vector<T> &val, MessageParcel &parcel);
template<class K, class V>
static bool Marshalling(const std::map<K, V> &val, MessageParcel &parcel);
template<class K, class V>
static bool Unmarshalling(std::map<K, V> &val, MessageParcel &parcel);
template<typename T, typename... Types>
static bool Marshal(MessageParcel &parcel, const T &first, const Types &...others);
template<typename T, typename... Types>
static bool Unmarshal(MessageParcel &parcel, T &first, Types &...others);
template<typename T>
static Status MarshalToBuffer(const T &input, int size, MessageParcel &data);
template<typename T>
static Status MarshalToBuffer(const std::vector<T> &input, int size, MessageParcel &data);
template<typename T>
static Status UnmarshalFromBuffer(MessageParcel &data, int size, T &output);
template<typename T>
static Status UnmarshalFromBuffer(MessageParcel &data, int size, std::vector<T> &output);
};
bool ITypesUtil::Marshal(MessageParcel &data)
{
return true;
}
bool ITypesUtil::Unmarshal(MessageParcel &data)
{
return true;
}
bool ITypesUtil::Marshalling(bool input, MessageParcel &data)
{
return data.WriteBool(input);
}
bool ITypesUtil::Unmarshalling(bool &output, MessageParcel &data)
{
return data.ReadBool(output);
}
bool ITypesUtil::Marshalling(uint32_t input, MessageParcel &data)
{
return data.WriteUint32(input);
}
bool ITypesUtil::Unmarshalling(uint32_t &output, MessageParcel &data)
{
return data.ReadUint32(output);
}
bool ITypesUtil::Marshalling(int32_t input, MessageParcel &data)
{
return data.WriteInt32(input);
}
bool ITypesUtil::Unmarshalling(int32_t &output, MessageParcel &data)
{
return data.ReadInt32(output);
}
bool ITypesUtil::Marshalling(uint64_t input, MessageParcel &data)
{
return data.WriteUint64(input);
}
bool ITypesUtil::Unmarshalling(uint64_t &output, MessageParcel &data)
{
return data.ReadUint64(output);
}
bool ITypesUtil::Marshalling(const std::string &input, MessageParcel &data)
{
return data.WriteString(input);
}
bool ITypesUtil::Unmarshalling(std::string &output, MessageParcel &data)
{
return data.ReadString16(output);
}
bool ITypesUtil::Marshalling(const std::u16string &input, MessageParcel &data)
{
return data.WriteString16(input);
}
bool ITypesUtil::Unmarshalling(std::u16string &output, MessageParcel &data)
{
return data.ReadString(output);
}
bool ITypesUtil::Marshalling(const std::vector<uint8_t> &input, MessageParcel &data)
{
return data.WriteUInt8Vector(input);
}
bool ITypesUtil::Unmarshalling(std::vector<uint8_t> &output, MessageParcel &data)
{
return data.ReadUInt8Vector(&output);
}
bool ITypesUtil::Marshalling(const sptr<IRemoteObject> &input, MessageParcel &data)
{
return data.WriteRemoteObject(input);
}
bool ITypesUtil::Unmarshalling(sptr<IRemoteObject> &output, MessageParcel &data)
{
output = data.ReadRemoteObject();
return true;
}
template<class T>
bool ITypesUtil::Marshalling(const std::vector<T> &val, MessageParcel &parcel)
{
if (val.size() > INT_MAX) {
return false;
}
if (!parcel.WriteInt32(static_cast<int32_t>(val.size()))) {
return false;
}
for (auto &v : val) {
if (!Marshalling(v, parcel)) {
return false;
}
}
return true;
}
template<class T>
bool ITypesUtil::Unmarshalling(std::vector<T> &val, MessageParcel &parcel)
{
int32_t len = parcel.ReadInt32();
if (len < 0) {
return false;
}
size_t readAbleSize = parcel.GetReadableBytes();
size_t size = static_cast<size_t>(len);
if ((size > readAbleSize) || (size > val.max_size())) {
return false;
}
val.resize(size);
if (val.size() < size) {
return false;
}
for (auto &v : val) {
if (!Unmarshalling(v, parcel)) {
return false;
}
}
return true;
}
template<typename T>
Status ITypesUtil::MarshalToBuffer(const T &input, int size, MessageParcel &data)
{
std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size);
if (!data.WriteBool(buffer != nullptr)) {
return Status::IPC_ERROR;
}
if (buffer == nullptr) {
return Status::ILLEGAL_STATE;
}
int leftSize = size;
uint8_t *cursor = buffer.get();
if (!input.WriteToBuffer(cursor, leftSize)) {
return Status::IPC_ERROR;
}
return data.WriteRawData(buffer.get(), size) ? Status::SUCCESS : Status::IPC_ERROR;
}
template<typename T>
Status ITypesUtil::MarshalToBuffer(const std::vector<T> &input, int size, MessageParcel &data)
{
std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size);
if (!data.WriteBool(buffer != nullptr)) {
return Status::IPC_ERROR;
}
if (buffer == nullptr) {
return Status::ILLEGAL_STATE;
}
uint8_t *cursor = buffer.get();
for (const auto &entry : input) {
if (!entry.WriteToBuffer(cursor, size)) {
return Status::IPC_ERROR;
}
}
if (!data.WriteInt32(input.size())) {
return Status::IPC_ERROR;
}
return data.WriteRawData(buffer.get(), size) ? Status::SUCCESS : Status::IPC_ERROR;
}
template<typename T>
Status ITypesUtil::UnmarshalFromBuffer(MessageParcel &data, int size, T &output)
{
if (size < 0) {
return Status::INVALID_ARGUMENT;
}
if (!data.ReadBool()) {
return Status::ILLEGAL_STATE;
}
const uint8_t *buffer = reinterpret_cast<const uint8_t *>(data.ReadRawData(size));
if (buffer == nullptr) {
return Status::INVALID_ARGUMENT;
}
return output.ReadFromBuffer(buffer, size) ? Status::SUCCESS : Status::IPC_ERROR;
}
template<typename T>
Status ITypesUtil::UnmarshalFromBuffer(MessageParcel &data, int size, std::vector<T> &output)
{
if (size < 0) {
return Status::INVALID_ARGUMENT;
}
if (!data.ReadBool()) {
return Status::ILLEGAL_STATE;
}
int count = data.ReadInt32();
const uint8_t *buffer = reinterpret_cast<const uint8_t *>(data.ReadRawData(size));
if (count < 0 || buffer == nullptr) {
return Status::INVALID_ARGUMENT;
}
output.resize(count);
for (auto &entry : output) {
if (!entry.ReadFromBuffer(buffer, size)) {
output.clear();
return Status::IPC_ERROR;
}
}
return Status::SUCCESS;
}
template<typename T, typename... Types>
bool ITypesUtil::Marshal(MessageParcel &parcel, const T &first, const Types &...others)
{
if (!Marshalling(first, parcel)) {
return false;
}
return Marshal(parcel, others...);
}
template<typename T, typename... Types>
bool ITypesUtil::Unmarshal(MessageParcel &parcel, T &first, Types &...others)
{
if (!Unmarshalling(first, parcel)) {
return false;
}
return Unmarshal(parcel, others...);
}
template<class K, class V>
bool ITypesUtil::Marshalling(const std::map<K, V> &result, MessageParcel &parcel)
{
if (!parcel.WriteInt32(static_cast<int32_t>(result.size()))) {
return false;
}
for (const auto &entry : result) {
if (!Marshalling(entry.first, parcel)) {
return false;
}
if (!Marshalling(entry.second, parcel)) {
return false;
}
}
return true;
}
template<class K, class V>
bool ITypesUtil::Unmarshalling(std::map<K, V> &val, MessageParcel &parcel)
{
int32_t size = 0;
if (!parcel.ReadInt32(size)) {
return false;
}
if (size < 0) {
return false;
}
size_t readAbleSize = parcel.GetReadableBytes();
size_t len = static_cast<size_t>(size);
if ((len > readAbleSize) || len > val.max_size()) {
return false;
}
for (int32_t i = 0; i < size; i++) {
K key;
if (!Unmarshalling(key, parcel)) {
return false;
}
V value;
if (!Unmarshalling(value, parcel)) {
return false;
}
val.insert({ key, value });
}
return true;
}
} // namespace OHOS::MiscServices
#endif

View File

@ -21,6 +21,10 @@
#include "inputmethod_trace.h"
#include "iservice_registry.h"
#include "string_ex.h"
#include "input_client_stub.h"
#include "input_data_channel_stub.h"
#include "input_method_agent_proxy.h"
#include "input_method_system_ability_proxy.h"
#include "system_ability_definition.h"
#include "utils.h"
@ -63,11 +67,21 @@ using namespace MessageID;
msgHandler = new MessageHandler();
mClient = new InputClientStub();
mClient->SetHandler(msgHandler);
InputClientStub *client = new (std::nothrow) InputClientStub();
if (client == nullptr) {
IMSA_HILOGE("InputMethodController::Initialize client is nullptr");
return false;
}
client->SetHandler(msgHandler);
mClient = client;
mInputDataChannel = new InputDataChannelStub();
mInputDataChannel->SetHandler(msgHandler);
InputDataChannelStub *channel = new (std::nothrow) InputDataChannelStub();
if (channel == nullptr) {
IMSA_HILOGE("InputMethodController::Initialize channel is nullptr");
return false;
}
channel->SetHandler(msgHandler);
mInputDataChannel = channel;
workThreadHandler = std::thread([this] {WorkThread();});
mAttribute.SetInputPattern(InputAttribute::PATTERN_TEXT);
@ -78,7 +92,7 @@ using namespace MessageID;
return true;
}
sptr<InputMethodSystemAbilityProxy> InputMethodController::GetImsaProxy()
sptr<IInputMethodSystemAbility> InputMethodController::GetImsaProxy()
{
IMSA_HILOGI("InputMethodController::GetImsaProxy");
sptr<ISystemAbilityManager> systemAbilityManager =
@ -102,8 +116,7 @@ using namespace MessageID;
}
systemAbility->AddDeathRecipient(deathRecipient_);
sptr<InputMethodSystemAbilityProxy> iface = new InputMethodSystemAbilityProxy(systemAbility);
return iface;
return iface_cast<IInputMethodSystemAbility>(systemAbility);
}
void InputMethodController::WorkThread()
@ -214,8 +227,8 @@ using namespace MessageID;
IMSA_HILOGI("InputMethodController::Attach");
InputmethodTrace tracer("InputMethodController Attach trace.");
IMSA_HILOGI("InputMethodController::Attach isShowKeyboard %{public}s", isShowKeyboard ? "true" : "false");
StartInput(mClient, isShowKeyboard);
PrepareInput(0, mClient, mInputDataChannel, mAttribute);
StartInput(mClient, isShowKeyboard);
}
void InputMethodController::ShowTextInput()
@ -233,27 +246,17 @@ using namespace MessageID;
int32_t InputMethodController::HideCurrentInput()
{
IMSA_HILOGI("InputMethodController::HideCurrentInput");
if (!mImms) {
return ErrorCode::ERROR_KBD_HIDE_FAILED;
}
MessageParcel data;
if (!(data.WriteInterfaceToken(mImms->GetDescriptor()))) {
return ErrorCode::ERROR_KBD_HIDE_FAILED;
}
return mImms->HideCurrentInput(data);
return SendDataByProxy([](sptr<IInputMethodSystemAbility> &proxy, MessageParcel &data) -> int32_t {
return proxy->HideCurrentInputDeprecated(data);
});
}
int32_t InputMethodController::ShowCurrentInput()
{
IMSA_HILOGI("InputMethodController::ShowCurrentInput");
if (!mImms) {
return ErrorCode::ERROR_KBD_SHOW_FAILED;
}
MessageParcel data;
if (!(data.WriteInterfaceToken(mImms->GetDescriptor()))) {
return ErrorCode::ERROR_KBD_SHOW_FAILED;
}
return mImms->ShowCurrentInput(data);
return SendDataByProxy([](sptr<IInputMethodSystemAbility> &proxy, MessageParcel &data) -> int32_t {
return proxy->ShowCurrentInputDeprecated(data);
});
}
void InputMethodController::Close()
@ -264,8 +267,8 @@ using namespace MessageID;
IMSA_HILOGI("InputMethodController::Close");
}
void InputMethodController::PrepareInput(int32_t displayId, sptr<InputClientStub> &client,
sptr<InputDataChannelStub> &channel, InputAttribute &attribute)
void InputMethodController::PrepareInput(int32_t displayId, sptr<IInputClient> &client,
sptr<IInputDataChannel> &channel, InputAttribute &attribute)
{
IMSA_HILOGI("InputMethodController::PrepareInput");
if (!mImms) {
@ -285,14 +288,9 @@ using namespace MessageID;
int32_t InputMethodController::DisplayOptionalInputMethod()
{
IMSA_HILOGI("InputMethodController::DisplayOptionalInputMethod");
if (!mImms) {
return ErrorCode::ERROR_STATUS_BAD_VALUE;
}
MessageParcel data;
if (!(data.WriteInterfaceToken(mImms->GetDescriptor()))) {
return ErrorCode::ERROR_STATUS_BAD_VALUE;
}
return mImms->displayOptionalInputMethod(data);
return SendDataByProxy([](sptr<IInputMethodSystemAbility> &proxy, MessageParcel &data) -> int32_t {
return proxy->DisplayOptionalInputMethodDeprecated(data);
});
}
std::vector<Property> InputMethodController::ListInputMethodCommon(InputMethodStatus status)
@ -336,7 +334,7 @@ using namespace MessageID;
[](auto p) {} };
}
void InputMethodController::StartInput(sptr<InputClientStub> &client, bool isShowKeyboard)
void InputMethodController::StartInput(sptr<IInputClient> &client, bool isShowKeyboard)
{
IMSA_HILOGI("InputMethodController::StartInput");
if (!mImms) {
@ -351,7 +349,7 @@ using namespace MessageID;
mImms->startInput(data);
}
void InputMethodController::ReleaseInput(sptr<InputClientStub> &client)
void InputMethodController::ReleaseInput(sptr<IInputClient> &client)
{
IMSA_HILOGI("InputMethodController::ReleaseInput");
if (!mImms) {
@ -366,7 +364,7 @@ using namespace MessageID;
mImms->releaseInput(data);
}
void InputMethodController::StopInput(sptr<InputClientStub> &client)
void InputMethodController::StopInput(sptr<IInputClient> &client)
{
IMSA_HILOGI("InputMethodController::StopInput");
if (!mImms) {
@ -397,7 +395,7 @@ using namespace MessageID;
void InputMethodController::OnCursorUpdate(CursorInfo cursorInfo)
{
std::shared_ptr<InputMethodAgentProxy> agent = GetInputMethodAgent();
std::shared_ptr<IInputMethodAgent> agent = GetInputMethodAgent();
if (agent == nullptr) {
IMSA_HILOGI("InputMethodController::OnCursorUpdate agent is nullptr");
return;
@ -427,7 +425,7 @@ using namespace MessageID;
mSelectOldEnd = mSelectNewEnd;
mSelectNewBegin = start;
mSelectNewEnd = end;
std::shared_ptr<InputMethodAgentProxy> agent = GetInputMethodAgent();
std::shared_ptr<IInputMethodAgent> agent = GetInputMethodAgent();
if (agent == nullptr) {
IMSA_HILOGI("InputMethodController::OnSelectionChange agent is nullptr");
return;
@ -473,7 +471,7 @@ using namespace MessageID;
bool InputMethodController::dispatchKeyEvent(std::shared_ptr<MMI::KeyEvent> keyEvent)
{
IMSA_HILOGI("InputMethodController::dispatchKeyEvent");
std::shared_ptr<InputMethodAgentProxy> agent = GetInputMethodAgent();
std::shared_ptr<IInputMethodAgent> agent = GetInputMethodAgent();
if (agent == nullptr) {
IMSA_HILOGI("InputMethodController::dispatchKeyEvent agent is nullptr");
return false;
@ -508,8 +506,8 @@ using namespace MessageID;
void InputMethodController::SetCallingWindow(uint32_t windowId)
{
std::shared_ptr<InputMethodAgentProxy> agent = GetInputMethodAgent();
IMSA_HILOGI("InputMethodController::SetCallingWindow windowId = %{public}d", windowId);
std::shared_ptr<IInputMethodAgent> agent = GetInputMethodAgent();
if (agent == nullptr) {
IMSA_HILOGI("InputMethodController::SetCallingWindow agent is nullptr");
return;
@ -540,7 +538,7 @@ using namespace MessageID;
{
IMSA_HILOGI("run in SetInputMethodAgent");
std::lock_guard<std::mutex> lock(agentLock_);
std::shared_ptr<InputMethodAgentProxy> agent = std::make_shared<InputMethodAgentProxy>(object);
std::shared_ptr<IInputMethodAgent> agent = std::make_shared<InputMethodAgentProxy>(object);
if (agent == nullptr) {
IMSA_HILOGI("InputMethodController::SetInputMethodAgent agent is nullptr");
return;
@ -548,10 +546,51 @@ using namespace MessageID;
mAgent = agent;
}
std::shared_ptr<InputMethodAgentProxy> InputMethodController::GetInputMethodAgent()
std::shared_ptr<IInputMethodAgent> InputMethodController::GetInputMethodAgent()
{
std::lock_guard<std::mutex> lock(agentLock_);
return mAgent;
}
int32_t InputMethodController::ShowSoftKeyboard()
{
IMSA_HILOGI("InputMethodController ShowSoftKeyboard");
return SendDataByProxy([](sptr<IInputMethodSystemAbility> &proxy, MessageParcel &data) -> int32_t {
return proxy->ShowCurrentInput(data);
});
}
int32_t InputMethodController::HideSoftKeyboard()
{
IMSA_HILOGI("InputMethodController HideSoftKeyboard");
return SendDataByProxy([](sptr<IInputMethodSystemAbility> &proxy, MessageParcel &data) -> int32_t {
return proxy->HideCurrentInput(data);
});
}
int32_t InputMethodController::ShowOptionalInputMethod()
{
IMSA_HILOGI("InputMethodController::ShowOptionalInputMethod");
return SendDataByProxy([](sptr<IInputMethodSystemAbility> &proxy, MessageParcel &data) -> int32_t {
return proxy->displayOptionalInputMethod(data);
});
}
int32_t InputMethodController::SendDataByProxy(
std::function<int32_t(sptr<IInputMethodSystemAbility> &, MessageParcel &)> callback)
{
IMSA_HILOGI("InputMethodController::SendDataToByProxy");
sptr<IInputMethodSystemAbility> proxy = mImms;
if (proxy == nullptr) {
IMSA_HILOGE("proxy is nullptr");
return ErrorCode::ERROR_NULL_POINTER;
}
MessageParcel data;
if (!(data.WriteInterfaceToken(proxy->GetDescriptor()))) {
IMSA_HILOGE("write descriptor failed");
return ErrorCode::ERROR_STATUS_FAILED_TRANSACTION;
}
return callback(proxy, data);
}
} // namespace MiscServices
} // namespace OHOS

View File

@ -46,21 +46,8 @@ namespace MiscServices {
int32_t InputMethodSystemAbilityProxy::displayOptionalInputMethod(MessageParcel& data)
{
MessageParcel reply;
MessageOption option;
auto ret = Remote()->SendRequest(DISPLAY_OPTIONAL_INPUT_METHOD, data, reply, option);
if (ret != NO_ERROR) {
IMSA_HILOGI("InputMethodSystemAbilityProxy::displayOptionalInputMethod SendRequest failed");
return ret;
}
ret = reply.ReadInt32();
if (ret != NO_ERROR) {
IMSA_HILOGI("InputMethodSystemAbilityProxy::displayOptionalInputMethod reply failed");
return ret;
}
return ErrorCode::NO_ERROR;
IMSA_HILOGI("InputMethodSystemAbilityProxy::displayOptionalInputMethod");
return SendRequestToService(data, DISPLAY_OPTIONAL_INPUT_METHOD);
}
void InputMethodSystemAbilityProxy::releaseInput(MessageParcel& data)
@ -119,60 +106,26 @@ namespace MiscServices {
}
}
void InputMethodSystemAbilityProxy::SetCoreAndAgent(MessageParcel& data)
void InputMethodSystemAbilityProxy::SetCoreAndAgent(MessageParcel &data)
{
IMSA_HILOGI("InputMethodSystemAbilityProxy::SetCoreAndAgent");
auto remote = Remote();
if (!remote) {
return;
}
MessageParcel reply;
MessageOption option {
MessageOption::TF_SYNC
};
Remote()->SendRequest(SET_CORE_AND_AGENT, data, reply, option);
MessageOption option{ MessageOption::TF_SYNC };
if (Remote()->SendRequest(SET_CORE_AND_AGENT, data, reply, option) != NO_ERROR) {
IMSA_HILOGE("SendRequest failed");
}
}
int32_t InputMethodSystemAbilityProxy::HideCurrentInput(MessageParcel& data)
{
IMSA_HILOGI("InputMethodSystemAbilityProxy::HideCurrentInput");
MessageParcel reply;
MessageOption option;
auto ret = Remote()->SendRequest(HIDE_CURRENT_INPUT, data, reply, option);
if (ret != NO_ERROR) {
IMSA_HILOGI("InputMethodSystemAbilityProxy::HideCurrentInput SendRequest failed");
return ErrorCode::ERROR_KBD_HIDE_FAILED;
}
ret = reply.ReadInt32();
if (ret != NO_ERROR) {
IMSA_HILOGI("InputMethodSystemAbilityProxy::HideCurrentInput reply failed");
return ErrorCode::ERROR_KBD_HIDE_FAILED;
}
return ErrorCode::NO_ERROR;
return SendRequestToService(data, HIDE_CURRENT_INPUT);
}
int32_t InputMethodSystemAbilityProxy::ShowCurrentInput(MessageParcel &data)
{
IMSA_HILOGI("InputMethodSystemAbilityProxy::ShowCurrentInput");
MessageParcel reply;
MessageOption option;
auto ret = Remote()->SendRequest(SHOW_CURRENT_INPUT, data, reply, option);
if (ret != NO_ERROR) {
IMSA_HILOGI("InputMethodSystemAbilityProxy::ShowCurrentInput SendRequest failed");
return ErrorCode::ERROR_KBD_SHOW_FAILED;
}
ret = reply.ReadInt32();
if (ret != NO_ERROR) {
IMSA_HILOGI("InputMethodSystemAbilityProxy::ShowCurrentInput reply failed");
return ErrorCode::ERROR_KBD_SHOW_FAILED;
}
return ErrorCode::NO_ERROR;
return SendRequestToService(data, SHOW_CURRENT_INPUT);
}
int32_t InputMethodSystemAbilityProxy::Prepare(int32_t displayId, sptr<InputClientStub> &client,
@ -462,7 +415,6 @@ namespace MiscServices {
IMSA_HILOGI("InputMethodSystemAbilityProxy::SwitchInputMethod");
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
return ERROR_EX_PARCELABLE;
}
@ -475,5 +427,50 @@ namespace MiscServices {
ret = reply.ReadInt32();
return ret;
}
int32_t InputMethodSystemAbilityProxy::ShowCurrentInputDeprecated(MessageParcel &data)
{
IMSA_HILOGI("InputMethodSystemAbilityProxy::ShowCurrentInputDeprecated");
return SendRequestToService(data, SHOW_CURRENT_INPUT_DEPRECATED);
}
int32_t InputMethodSystemAbilityProxy::HideCurrentInputDeprecated(MessageParcel &data)
{
IMSA_HILOGI("InputMethodSystemAbilityProxy::HideCurrentInputDeprecated");
return SendRequestToService(data, HIDE_CURRENT_INPUT_DEPRECATED);
}
int32_t InputMethodSystemAbilityProxy::DisplayOptionalInputMethodDeprecated(MessageParcel &data)
{
IMSA_HILOGI("InputMethodSystemAbilityProxy::DisplayOptionalInputMethodDeprecated");
return SendRequestToService(data, DISPLAY_OPTIONAL_INPUT_METHOD_DEPRECATED);
}
void InputMethodSystemAbilityProxy::SetCoreAndAgentDeprecated(MessageParcel &data)
{
IMSA_HILOGI("InputMethodSystemAbilityProxy::SetCoreAndAgentDeprecated");
MessageParcel reply;
MessageOption option{ MessageOption::TF_SYNC };
if (Remote()->SendRequest(SET_CORE_AND_AGENT_DEPRECATED, data, reply, option) != NO_ERROR) {
IMSA_HILOGE("SendRequest failed");
}
}
int32_t InputMethodSystemAbilityProxy::SendRequestToService(MessageParcel &data, uint32_t code)
{
IMSA_HILOGI("InputMethodSystemAbilityProxy::SendRequestToService");
MessageParcel reply;
MessageOption option{ MessageOption::TF_SYNC };
auto ret = Remote()->SendRequest(code, data, reply, option);
if (ret != NO_ERROR) {
IMSA_HILOGE("SendRequest failed");
return ret;
}
ret = reply.ReadInt32();
if (ret != NO_ERROR) {
IMSA_HILOGE("reply error");
}
return ret;
}
} // namespace MiscServices
} // namespace OHOS

View File

@ -118,12 +118,8 @@ ohos_shared_library("inputmethod_extension") {
]
public_deps = [
"//base/global/i18n/frameworks/intl:intl_util",
"//base/global/resource_management/frameworks/resmgr:global_resmgr",
"//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog",
"//foundation/arkui/napi:ace_napi",
"//foundation/window/window_manager/interfaces/kits/napi/window_runtime:windowstage_kit",
"//foundation/window/window_manager/wm:libwm",
]
subsystem_name = "inputmethod"

View File

@ -361,7 +361,7 @@ private:
sptr<JSInputMethodExtensionConnection> connection = nullptr;
napi_get_value_int64(
reinterpret_cast<napi_env>(&engine), reinterpret_cast<napi_value>(info.argv[INDEX_ZERO]), &connectId);
IMSA_HILOGI("OnDisconnectAbility connection:%{public}d", (int32_t)connectId);
IMSA_HILOGI("OnDisconnectAbility connection:%{public}d", static_cast<int32_t>(connectId));
auto item = std::find_if(connects_.begin(), connects_.end(),
[&connectId](const std::map<ConnecttionKey,
sptr<JSInputMethodExtensionConnection>>::value_type &obj) {

View File

@ -42,26 +42,16 @@ ohos_shared_library("inputmethod") {
configs = [ ":imf_config" ]
deps = [
"${ability_runtime_inner_api_path}/ability_manager:ability_manager",
"${ability_runtime_inner_api_path}/app_manager:app_manager",
"${ability_runtime_path}/frameworks/native/ability/native:abilitykit_native",
"${inputmethod_path}/services/dfx:inputmethod_dfx_static",
"//base/global/resource_management/frameworks/resmgr:global_resmgr",
"//base/inputmethod/imf/frameworks/inputmethod_ability:inputmethod_ability",
"//foundation/arkui/napi/:ace_napi",
"//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core",
"//foundation/communication/ipc/interfaces/innerkits/ipc_single:ipc_single",
"//foundation/multimodalinput/input/frameworks/proxy:libmmi-client",
"//foundation/systemabilitymgr/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
]
external_deps = [
"ability_base:want",
"ability_runtime:runtime",
"bundle_framework:appexecfwk_base",
"bundle_framework:appexecfwk_core",
"c_utils:utils",
"eventhandler:libeventhandler",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
]

View File

@ -10,6 +10,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//base/inputmethod/imf/inputmethod.gni")
import("//build/ohos.gni")
@ -19,6 +20,13 @@ config("inputmethodengine_native_config") {
"include",
"${inputmethod_path}/frameworks/inputmethod_ability/include",
"${inputmethod_path}/frameworks/inputmethod_controller/include",
"//foundation/multimodalinput/input/interfaces/native/innerkits/event/include",
]
ldflags = [ "-Wl,--exclude-libs=ALL" ]
cflags = [
"-fdata-sections",
"-ffunction-sections",
"-fvisibility=hidden",
]
}
@ -47,25 +55,12 @@ ohos_shared_library("inputmethodengine") {
configs = [ ":inputmethodengine_native_config" ]
deps = [
"${ability_runtime_inner_api_path}/ability_manager:ability_manager",
"${ability_runtime_inner_api_path}/app_manager:app_manager",
"${ability_runtime_path}/frameworks/native/ability/native:abilitykit_native",
"//base/global/resource_management/frameworks/resmgr:global_resmgr",
"//base/inputmethod/imf/frameworks/inputmethod_ability:inputmethod_ability",
"//foundation/arkui/napi/:ace_napi",
"//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core",
"//foundation/communication/ipc/interfaces/innerkits/ipc_single:ipc_single",
"//foundation/multimodalinput/input/frameworks/proxy:libmmi-client",
"//foundation/systemabilitymgr/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
]
external_deps = [
"ability_base:want",
"ability_runtime:runtime",
"bundle_framework:appexecfwk_base",
"bundle_framework:appexecfwk_core",
"ability_runtime:abilitykit_native",
"c_utils:utils",
"eventhandler:libeventhandler",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
]

View File

@ -29,6 +29,10 @@ constexpr size_t ARGC_TWO = 2;
constexpr size_t ARGC_MAX = 6;
const std::string JsInputMethodEngineSetting::IMES_CLASS_NAME = "InputMethodEngine";
thread_local napi_ref JsInputMethodEngineSetting::IMESRef_ = nullptr;
std::mutex JsInputMethodEngineSetting::engineMutex_;
std::shared_ptr<JsInputMethodEngineSetting> JsInputMethodEngineSetting::inputMethodEngine_ { nullptr };
napi_value JsInputMethodEngineSetting::Init(napi_env env, napi_value exports)
{
napi_property_descriptor descriptor[] = {
@ -48,7 +52,7 @@ napi_value JsInputMethodEngineSetting::Init(napi_env env, napi_value exports)
GetJsConstProperty(env, static_cast<uint32_t>(EnterKeyType::PREVIOUS))),
DECLARE_NAPI_PROPERTY("PATTERN_NULL",
GetJsConstProperty(env, static_cast<uint32_t>(TextInputType::NONE))),
GetIntJsConstProperty(env, static_cast<int32_t>(TextInputType::NONE))),
DECLARE_NAPI_PROPERTY("PATTERN_TEXT",
GetJsConstProperty(env, static_cast<uint32_t>(TextInputType::TEXT))),
DECLARE_NAPI_PROPERTY("PATTERN_NUMBER",
@ -83,30 +87,54 @@ napi_value JsInputMethodEngineSetting::Init(napi_env env, napi_value exports)
};
napi_value JsInputMethodEngineSetting::GetJsConstProperty(napi_env env, uint32_t num)
{
napi_value jsNumber = nullptr;
napi_create_uint32(env, num, &jsNumber);
return jsNumber;
}
napi_value JsInputMethodEngineSetting::GetIntJsConstProperty(napi_env env, int32_t num)
{
napi_value jsNumber = nullptr;
napi_create_int32(env, num, &jsNumber);
return jsNumber;
}
std::shared_ptr<JsInputMethodEngineSetting> JsInputMethodEngineSetting::GetInputMethodEngineSetting()
{
if (inputMethodEngine_ == nullptr) {
std::lock_guard<std::mutex> lock(engineMutex_);
if (inputMethodEngine_ == nullptr) {
auto engine = std::make_shared<JsInputMethodEngineSetting>();
if (engine == nullptr) {
IMSA_HILOGE("input method engine nullptr");
return nullptr;
}
inputMethodEngine_ = engine;
InputMethodAbility::GetInstance()->setImeListener(inputMethodEngine_);
}
}
return inputMethodEngine_;
}
napi_value JsInputMethodEngineSetting::JsConstructor(napi_env env, napi_callback_info info)
{
napi_value thisVar = nullptr;
IMSA_HILOGI("run in JsConstructor");
napi_value thisVar = nullptr;
NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
std::shared_ptr<JsInputMethodEngineSetting> obj = std::make_shared<JsInputMethodEngineSetting>();
InputMethodAbility::GetInstance()->setImeListener(obj);
if (obj == nullptr) {
auto delegate = GetInputMethodEngineSetting();
if (delegate == nullptr) {
IMSA_HILOGE("get delegate nullptr");
napi_value result = nullptr;
napi_get_null(env, &result);
return result;
}
napi_wrap(env, thisVar, obj.get(), [](napi_env env, void *data, void *hint) {
IMSA_HILOGE("run in IMESobject delete");
napi_wrap(env, thisVar, delegate.get(), [](napi_env env, void *nativeObject, void *hint) {
IMSA_HILOGE("delete JsInputMethodEngineSetting");
}, nullptr, nullptr);
napi_get_uv_event_loop(env, &obj->loop_);
if (delegate->loop_ == nullptr) {
napi_get_uv_event_loop(env, &delegate->loop_);
}
return thisVar;
};
@ -160,7 +188,7 @@ std::string JsInputMethodEngineSetting::GetStringProperty(napi_env env, napi_val
}
void JsInputMethodEngineSetting::RegisterListener(napi_value callback, std::string type,
std::shared_ptr<JSCallbackObject> JSCallbackObject)
std::shared_ptr<JSCallbackObject> callbackObj)
{
std::lock_guard<std::recursive_mutex> lock(mutex_);
if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
@ -174,7 +202,7 @@ void JsInputMethodEngineSetting::RegisterListener(napi_value callback, std::stri
}
}
jsCbMap_[type].push_back(std::move(JSCallbackObject));
jsCbMap_[type].push_back(std::move(callbackObj));
}
void JsInputMethodEngineSetting::UnRegisterListener(napi_value callback, std::string type)
@ -543,4 +571,4 @@ void JsInputMethodEngineSetting::OnSetCallingWindow(uint32_t windowId)
});
}
}
}
}

View File

@ -19,6 +19,7 @@
#include <map>
#include <uv.h>
#include <mutex>
#include <memory>
#include "napi/native_api.h"
#include "global.h"
#include "async_call.h"
@ -43,15 +44,17 @@ public:
private:
static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo);
static JsInputMethodEngineSetting *GetNative(napi_env env, napi_callback_info info);
static std::shared_ptr<JsInputMethodEngineSetting> GetInputMethodEngineSetting();
static bool Equals(napi_env env, napi_value value, napi_ref copy);
static napi_value GetJsConstProperty(napi_env env, uint32_t num);
static napi_value GetIntJsConstProperty(napi_env env, int32_t num);
void RegisterListener(napi_value callback, std::string type,
std::shared_ptr<JSCallbackObject> JSCallbackObject);
std::shared_ptr<JSCallbackObject> callbackObj);
void UnRegisterListener(napi_value callback, std::string type);
uv_work_t *GetUVwork(std::string type);
uv_work_t *GetStopInputUVwork(std::string type, std::string imeId);
uv_work_t *GetWindowIDUVwork(std::string type, uint32_t windowid);
static std::string GetStringProperty(napi_env env, napi_value obj);
static std::string GetStringProperty(napi_env env, napi_value jsString);
static constexpr int32_t MAX_VALUE_LEN = 1024;
static const std::string IMES_CLASS_NAME;
static thread_local napi_ref IMESRef_;
@ -59,13 +62,15 @@ private:
std::vector<std::shared_ptr<JSCallbackObject>> vecCopy;
std::string type;
std::string imeid;
uint32_t windowid;
uint32_t windowid = 0;
UvEntry(std::vector<std::shared_ptr<JSCallbackObject>> cbVec, std::string type)
: vecCopy(cbVec), type(type) {}
};
uv_loop_s *loop_ = nullptr;
std::recursive_mutex mutex_;
std::map<std::string, std::vector<std::shared_ptr<JSCallbackObject>>> jsCbMap_;
static std::mutex engineMutex_;
static std::shared_ptr<JsInputMethodEngineSetting> inputMethodEngine_;
};
}
}

View File

@ -29,6 +29,10 @@ constexpr size_t ARGC_THREE = 3;
constexpr size_t ARGC_FOUR = 4;
const std::string JsKeyboardDelegateSetting::KDS_CLASS_NAME = "KeyboardDelegate";
thread_local napi_ref JsKeyboardDelegateSetting::KDSRef_ = nullptr;
std::mutex JsKeyboardDelegateSetting::keyboardMutex_;
std::shared_ptr<JsKeyboardDelegateSetting> JsKeyboardDelegateSetting::keyboardDelegate_ { nullptr };
napi_value JsKeyboardDelegateSetting::Init(napi_env env, napi_value exports)
{
napi_property_descriptor descriptor[] = {
@ -76,23 +80,41 @@ napi_value JsKeyboardDelegateSetting::GetJsConstProperty(napi_env env, uint32_t
return jsNumber;
};
std::shared_ptr<JsKeyboardDelegateSetting> JsKeyboardDelegateSetting::GetKeyboardDelegateSetting()
{
if (keyboardDelegate_ == nullptr) {
std::lock_guard<std::mutex> lock(keyboardMutex_);
if (keyboardDelegate_ == nullptr) {
auto delegate = std::make_shared<JsKeyboardDelegateSetting>();
if (delegate == nullptr) {
IMSA_HILOGE("keyboard delegate nullptr");
return nullptr;
}
keyboardDelegate_ = delegate;
InputMethodAbility::GetInstance()->setKdListener(keyboardDelegate_);
}
}
return keyboardDelegate_;
}
napi_value JsKeyboardDelegateSetting::JsConstructor(napi_env env, napi_callback_info info)
{
IMSA_HILOGI("run in JsConstructor");
napi_value thisVar = nullptr;
NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
std::shared_ptr<JsKeyboardDelegateSetting> obj = std::make_shared<JsKeyboardDelegateSetting>();
InputMethodAbility::GetInstance()->setKdListener(obj);
if (obj == nullptr) {
IMSA_HILOGE("KDSobject == nullptr");
auto delegate = GetKeyboardDelegateSetting();
if (delegate == nullptr) {
IMSA_HILOGE("get delegate nullptr");
napi_value result = nullptr;
napi_get_null(env, &result);
return result;
}
napi_wrap(env, thisVar, obj.get(), [](napi_env env, void *data, void *hint) {
napi_wrap(env, thisVar, delegate.get(), [](napi_env env, void *nativeObject, void *hint) {
IMSA_HILOGE("delete JsKeyboardDelegateSetting");
}, nullptr, nullptr);
napi_get_uv_event_loop(env, &obj->loop_);
if (delegate->loop_ == nullptr) {
napi_get_uv_event_loop(env, &delegate->loop_);
}
return thisVar;
};

View File

@ -86,6 +86,7 @@ public:
private:
static napi_value GetResultOnKeyEvent(napi_env env, int32_t keyCode, int32_t keyStatus);
static napi_value GetJsConstProperty(napi_env env, uint32_t num);
static std::shared_ptr<JsKeyboardDelegateSetting> GetKeyboardDelegateSetting();
static napi_value JsConstructor(napi_env env, napi_callback_info cbinfo);
static JsKeyboardDelegateSetting *GetNative(napi_env env, napi_callback_info info);
static bool Equals(napi_env env, napi_value value, napi_ref copy);
@ -98,20 +99,20 @@ private:
static const std::string KDS_CLASS_NAME;
static thread_local napi_ref KDSRef_;
struct CursorPara {
int32_t positionX;
int32_t positionY;
int height;
int32_t positionX = 0;
int32_t positionY = 0;
int height = 0;
};
struct SelectionPara {
int32_t oldBegin;
int32_t oldEnd;
int32_t newBegin;
int32_t newEnd;
int32_t oldBegin = 0;
int32_t oldEnd = 0;
int32_t newBegin = 0;
int32_t newEnd = 0;
};
struct KeyEventPara {
int32_t keyCode;
int32_t keyStatus;
bool isOnKeyEvent;
int32_t keyCode = 0;
int32_t keyStatus = 0;
bool isOnKeyEvent = false;
};
struct UvEntry {
std::vector<std::shared_ptr<JSCallbackObject>> vecCopy;
@ -132,6 +133,8 @@ private:
uv_loop_s *loop_ = nullptr;
std::recursive_mutex mutex_;
std::map<std::string, std::vector<std::shared_ptr<JSCallbackObject>>> jsCbMap_;
static std::mutex keyboardMutex_;
static std::shared_ptr<JsKeyboardDelegateSetting> keyboardDelegate_;
};
} // namespace MiscServices
} // namespace OHOS

View File

@ -24,7 +24,7 @@ namespace OHOS {
namespace MiscServices {
struct SendKeyFunctionContext : public AsyncCall::Context {
bool isSendKeyFunction = false;
int32_t action;
int32_t action = 0;
napi_status status = napi_generic_failure;
SendKeyFunctionContext() : Context(nullptr, nullptr) { };
SendKeyFunctionContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)) { };
@ -66,7 +66,7 @@ struct MoveCursorContext : public AsyncCall::Context {
struct DeleteForwardContext : public AsyncCall::Context {
bool isDeleteForward = false;
int32_t length;
int32_t length = 0;
napi_status status = napi_generic_failure;
DeleteForwardContext() : Context(nullptr, nullptr) { };
DeleteForwardContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)) { };
@ -87,7 +87,7 @@ struct DeleteForwardContext : public AsyncCall::Context {
struct DeleteBackwardContext : public AsyncCall::Context {
bool isDeleteBackward = false;
int32_t length;
int32_t length = 0;
napi_status status = napi_generic_failure;
DeleteBackwardContext() : Context(nullptr, nullptr) { };
DeleteBackwardContext(InputAction input, OutputAction output) : Context(std::move(input), std::move(output)) { };
@ -128,7 +128,7 @@ struct InsertTextContext : public AsyncCall::Context {
};
struct GetForwardContext : public AsyncCall::Context {
int32_t length;
int32_t length = 0;
std::string text;
napi_status status = napi_generic_failure;
GetForwardContext() : Context(nullptr, nullptr) { };
@ -149,7 +149,7 @@ struct GetForwardContext : public AsyncCall::Context {
};
struct GetBackwardContext : public AsyncCall::Context {
int32_t length;
int32_t length = 0;
std::string text;
napi_status status = napi_generic_failure;
GetBackwardContext() : Context(nullptr, nullptr) { };
@ -196,14 +196,14 @@ public:
JsTextInputClientEngine() = default;
~JsTextInputClientEngine() = default;
static napi_value Init(napi_env env, napi_value info);
static napi_value SendKeyFunction(napi_env env, napi_callback_info Info);
static napi_value DeleteForward(napi_env env, napi_callback_info Info);
static napi_value DeleteBackward(napi_env env, napi_callback_info Info);
static napi_value InsertText(napi_env env, napi_callback_info Info);
static napi_value GetForward(napi_env env, napi_callback_info Info);
static napi_value GetBackward(napi_env env, napi_callback_info Info);
static napi_value SendKeyFunction(napi_env env, napi_callback_info info);
static napi_value DeleteForward(napi_env env, napi_callback_info info);
static napi_value DeleteBackward(napi_env env, napi_callback_info info);
static napi_value InsertText(napi_env env, napi_callback_info info);
static napi_value GetForward(napi_env env, napi_callback_info info);
static napi_value GetBackward(napi_env env, napi_callback_info info);
static napi_value MoveCursor(napi_env env, napi_callback_info info);
static napi_value GetEditorAttribute(napi_env env, napi_callback_info Info);
static napi_value GetEditorAttribute(napi_env env, napi_callback_info info);
static napi_value GetTextInputClientInstance(napi_env env);
private:
static napi_status GetAction(napi_env env, napi_value argv,

View File

@ -21,18 +21,17 @@ config("imf_config") {
config("imf_public_config") {
visibility = []
include_dirs = [
"include",
"${inputmethod_path}/frameworks/inputmethod_controller/include",
"${inputmethod_path}/services/dfx/include",
include_dirs = [ "include" ]
ldflags = [ "-Wl,--exclude-libs=ALL" ]
cflags = [
"-fdata-sections",
"-ffunction-sections",
"-fvisibility=hidden",
]
}
ohos_shared_library("inputmethod") {
sources = [
"${inputmethod_path}/frameworks/inputmethod_controller/src/input_client_stub.cpp",
"${inputmethod_path}/frameworks/inputmethod_controller/src/input_data_channel_stub.cpp",
"${inputmethod_path}/frameworks/inputmethod_controller/src/input_method_controller.cpp",
"async_call.cpp",
"input_method_module.cpp",
"js_get_input_method_controller.cpp",
@ -43,28 +42,13 @@ ohos_shared_library("inputmethod") {
configs = [ ":imf_config" ]
deps = [
"${ability_runtime_inner_api_path}/ability_manager:ability_manager",
"${ability_runtime_inner_api_path}/app_manager:app_manager",
"${ability_runtime_path}/frameworks/native/ability/native:abilitykit_native",
"${inputmethod_path}/services/dfx:inputmethod_dfx_static",
"//base/global/resource_management/frameworks/resmgr:global_resmgr",
"//base/inputmethod/imf/frameworks/inputmethod_ability:inputmethod_ability",
"//foundation/arkui/napi/:ace_napi",
"//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core",
"//foundation/communication/ipc/interfaces/innerkits/ipc_single:ipc_single",
"//foundation/multimodalinput/input/frameworks/proxy:libmmi-client",
"//foundation/systemabilitymgr/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
"${inputmethod_path}/frameworks/inputmethod_controller:inputmethod_client",
]
external_deps = [
"ability_base:want",
"ability_runtime:runtime",
"bundle_framework:appexecfwk_base",
"bundle_framework:appexecfwk_core",
"ability_runtime:abilitykit_native",
"c_utils:utils",
"eventhandler:libeventhandler",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
]
public_configs = [ ":imf_public_config" ]

View File

@ -46,7 +46,7 @@ public:
JsGetInputMethodController() = default;
~JsGetInputMethodController() = default;
static napi_value Init(napi_env env, napi_value info);
static napi_value GetInputMethodController(napi_env env, napi_callback_info info);
static napi_value GetInputMethodController(napi_env env, napi_callback_info cbInfo);
static napi_value HandleSoftKeyboard(
napi_env env, napi_callback_info info, std::function<int32_t()> callback, bool isOutput);
static napi_value HideSoftKeyboard(napi_env env, napi_callback_info info);

View File

@ -116,10 +116,7 @@ napi_value JsGetInputMethodSetting::ListInputMethod(napi_env env, napi_callback_
} else {
ctxt->properties = InputMethodController::GetInstance()->ListInputMethod(ctxt->inputMethodStatus == ENABLE);
}
if (!ctxt->properties.empty()) {
IMSA_HILOGE("exec ---- ListInputMethod success");
ctxt->status = napi_ok;
}
ctxt->status = napi_ok;
};
ctxt->SetAction(std::move(input), std::move(output));
AsyncCall asyncCall(env, info, std::dynamic_pointer_cast<AsyncCall::Context>(ctxt));

View File

@ -23,7 +23,7 @@
namespace OHOS {
namespace MiscServices {
struct ListInputContext : public AsyncCall::Context {
InputMethodStatus inputMethodStatus;
InputMethodStatus inputMethodStatus = InputMethodStatus::ALL;
std::vector<Property> properties;
napi_status status = napi_generic_failure;
ListInputContext() : Context(nullptr, nullptr) { };

View File

@ -56,7 +56,7 @@ public:
static napi_value GetJSInputMethodProperties(napi_env env, const std::vector<Property> &properties);
private:
static std::string GetStringProperty(napi_env env, napi_value result);
static std::string GetStringProperty(napi_env env, napi_value obj);
static napi_status GetInputMethodProperty(napi_env env, napi_value argv,
std::shared_ptr<SwitchInputMethodContext> ctxt);
static constexpr std::int32_t MAX_VALUE_LEN = 4096;

View File

@ -42,25 +42,13 @@ ohos_shared_library("inputmethodengine") {
configs = [ ":inputmethodengine_native_config" ]
deps = [
"${ability_runtime_inner_api_path}/ability_manager:ability_manager",
"${ability_runtime_inner_api_path}/app_manager:app_manager",
"${ability_runtime_path}/frameworks/native/ability/native:abilitykit_native",
"//base/global/resource_management/frameworks/resmgr:global_resmgr",
"//base/inputmethod/imf/frameworks/inputmethod_ability:inputmethod_ability",
"//foundation/arkui/napi/:ace_napi",
"//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core",
"//foundation/communication/ipc/interfaces/innerkits/ipc_single:ipc_single",
"//foundation/multimodalinput/input/frameworks/proxy:libmmi-client",
"//foundation/systemabilitymgr/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
]
external_deps = [
"ability_base:want",
"ability_runtime:runtime",
"bundle_framework:appexecfwk_base",
"bundle_framework:appexecfwk_core",
"c_utils:utils",
"eventhandler:libeventhandler",
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
]

View File

@ -22,6 +22,7 @@ config("inputmethod_services_native_config") {
"${inputmethod_path}/frameworks/inputmethod_controller/include",
"//base/notification/common_event_service/frameworks/core/include",
"//base/notification/common_event_service/interfaces/innerkits/native/include",
"//foundation/multimodalinput/input/interfaces/native/innerkits/event/include",
"${inputmethod_path}/services/dfx/include",
]
@ -57,24 +58,20 @@ ohos_shared_library("inputmethod_service") {
deps = [
"${ability_runtime_inner_api_path}/ability_manager:ability_manager",
"${ability_runtime_inner_api_path}/app_manager:app_manager",
"${ability_runtime_services_path}/abilitymgr:abilityms",
"${inputmethod_path}/services/dfx:inputmethod_dfx_static",
"//base/global/resource_management/frameworks/resmgr:global_resmgr",
"//base/inputmethod/imf/etc/para:inputmethod_para",
"//base/inputmethod/imf/frameworks/inputmethod_ability:inputmethod_ability",
"//foundation/arkui/ace_engine/interfaces/inner_api/ui_service_manager:ui_service_mgr",
"//foundation/arkui/napi/:ace_napi",
"//foundation/arkui/napi/:ace_napi",
"//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core",
"//foundation/communication/ipc/interfaces/innerkits/ipc_single:ipc_single",
"//foundation/multimodalinput/input/frameworks/proxy:libmmi-client",
"//foundation/systemabilitymgr/safwk/interfaces/innerkits/safwk:system_ability_fwk",
"//foundation/systemabilitymgr/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
]
external_deps = [
"ability_base:want",
"access_token:libaccesstoken_sdk",
"bundle_framework:appexecfwk_base",
"bundle_framework:appexecfwk_core",
"c_utils:utils",

View File

@ -30,7 +30,7 @@ constexpr int32_t SUB_CMD_NAME = 0;
constexpr int32_t CMD_ONE_PARAM = 1;
constexpr const char *CMD_HELP = "-h";
constexpr const char *CMD_ALL_DUMP = "-a";
static const std::string illegalInfo = "input dump parameter error,enter '-h' for usage.\n";
static const std::string ILLEGAL_INFO = "input dump parameter error,enter '-h' for usage.\n";
void InputmethodDump::AddDumpAllMethod(const DumpNoParamFunc dumpAllMethod)
{
@ -86,7 +86,7 @@ void InputmethodDump::ShowHelp(int fd)
void InputmethodDump::ShowIllealInfomation(int fd)
{
dprintf(fd, "%s\n", illegalInfo.c_str());
dprintf(fd, "%s\n", ILLEGAL_INFO.c_str());
}
} // namespace MiscServices
} // namespace OHOS

View File

@ -53,6 +53,10 @@ namespace MiscServices {
SET_CORE_AND_AGENT,
DISPLAY_OPTIONAL_INPUT_METHOD,
SWITCH_INPUT_METHOD,
SHOW_CURRENT_INPUT_DEPRECATED,
HIDE_CURRENT_INPUT_DEPRECATED,
DISPLAY_OPTIONAL_INPUT_METHOD_DEPRECATED,
SET_CORE_AND_AGENT_DEPRECATED,
};
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.inputmethod.IInputMethodSystemAbility");
@ -72,6 +76,13 @@ namespace MiscServices {
virtual int32_t getCurrentKeyboardType(KeyboardType *retType) = 0;
virtual std::vector<InputMethodProperty> ListInputMethod(InputMethodStatus stauts) = 0;
virtual int32_t listKeyboardType(const std::u16string& imeId, std::vector<KeyboardType*> *types) = 0;
virtual int32_t SwitchInputMethod(const InputMethodProperty &target) = 0;
// Deprecated because of no permission check, kept for compatibility
virtual void SetCoreAndAgentDeprecated(MessageParcel &data) = 0;
virtual int32_t HideCurrentInputDeprecated(MessageParcel &data) = 0;
virtual int32_t ShowCurrentInputDeprecated(MessageParcel &data) = 0;
virtual int32_t DisplayOptionalInputMethodDeprecated(MessageParcel &data) = 0;
};
} // namespace MiscServices
} // namespace OHOS

View File

@ -16,6 +16,7 @@
#ifndef SERVICES_INCLUDE_INPUT_METHOD_SYSTEM_ABILITY_H
#define SERVICES_INCLUDE_INPUT_METHOD_SYSTEM_ABILITY_H
#include <atomic>
#include <thread>
#include <map>
#include "system_ability.h"
@ -57,6 +58,7 @@ namespace MiscServices {
std::vector<InputMethodProperty> ListInputMethod(InputMethodStatus stauts) override;
std::vector<InputMethodProperty> ListInputMethodByUserId(int32_t userId, InputMethodStatus status) override;
int32_t listKeyboardType(const std::u16string &imeId, std::vector<KeyboardType *> *types) override;
int32_t SwitchInputMethod(const InputMethodProperty &target) override;
int Dump(int fd, const std::vector<std::u16string> &args) override;
void DumpAllMethod(int fd);
@ -103,6 +105,7 @@ namespace MiscServices {
std::string GetInputMethodParam(const std::vector<InputMethodProperty> &properties);
ServiceRunningState state_;
void InitServiceHandler();
std::atomic_flag dialogLock_ = ATOMIC_FLAG_INIT;
static std::mutex instanceLock_;
static sptr<InputMethodSystemAbility> instance_;
static std::shared_ptr<AppExecFwk::EventHandler> serviceHandler_;

View File

@ -40,9 +40,17 @@ namespace MiscServices {
void OnGetCurrentInputMethod(MessageParcel &reply);
void OnListInputMethod(MessageParcel &data, MessageParcel &reply);
virtual std::vector<InputMethodProperty> ListInputMethodByUserId(int32_t userId, InputMethodStatus status) = 0;
int32_t SwitchInputMethod(MessageParcel &data);
int32_t OnSwitchInputMethod(MessageParcel &data);
// Deprecated because of no permission check, kept for compatibility
int32_t DisplayOptionalInputMethodDeprecated(MessageParcel &data) override;
int32_t HideCurrentInputDeprecated(MessageParcel &data) override;
int32_t ShowCurrentInputDeprecated(MessageParcel &data) override;
void SetCoreAndAgentDeprecated(MessageParcel &data) override;
protected:
bool CheckPermission(const std::string &permission);
int32_t SendMessageToService(int32_t code, std::function<bool(MessageParcel &)> callback);
int32_t getUserId(int32_t uid);
int USER_ID_CHANGE_VALUE = 200000; // user range
};

View File

@ -58,6 +58,7 @@ namespace MessageID {
MSG_ID_DISPLAY_OPTIONAL_INPUT_METHOD,
MSG_ID_ADVANCE_TO_NEXT, // switch to next
MSG_ID_SET_DISPLAY_MODE, // set display mode
MSG_ID_START_INPUT_SERVICE,
MSG_ID_SHELL_COMMAND, // shell command
MSG_ID_EXIT_SERVICE, // exit service

View File

@ -54,36 +54,20 @@ namespace MiscServices {
int msgId_; // the message id can be MessageID::MSG_ID_CLIENT_DIED and MessageID::MSG_ID_IMS_DIED
};
/*! \class ClientInfo
\brief The class defines the details of an input client.
*/
class ClientInfo {
public:
int pid; // the process id of the process in which the input client is running
int uid; // the uid of the process in which the input client is running
int userId; // the user if of the user under which the input client is running
int displayId; // the display id on which the input client is showing
sptr<IInputClient> client; // the remote object handler for the service to callback to the input client
struct ClientInfo {
int pid; // the process id of the process in which the input client is running
int uid; // the uid of the process in which the input client is running
int userId; // the user if of the user under which the input client is running
int displayId; // the display id on which the input client is showing
sptr<IInputClient> client; // the remote object handler for the service to callback to the input client
sptr<IInputDataChannel> channel; // the remote object handler for IMSA callback to input client
sptr<RemoteObjectDeathRecipient> deathRecipient;
InputAttribute attribute; // the input attribute of the input client
};
ClientInfo(int pid, int uid, int userId, int displayId, const sptr<IInputClient>& client,
const sptr<IInputDataChannel>& channel, const InputAttribute& attribute)
{
this->pid = pid;
this->uid = uid;
this->userId = userId;
this->displayId = displayId;
this->client = client;
this->channel = channel;
this->attribute = attribute;
};
~ClientInfo()
{
this->client = nullptr;
this->channel = nullptr;
};
struct ResetManager {
uint32_t num {0};
time_t last {};
};
/*! \class PerUserSession
@ -92,11 +76,11 @@ namespace MiscServices {
This class manages the sessions between input clients and input method engines for each unlocked user.
*/
class PerUserSession {
enum {
DEFAULT_IME = 0, // index for default input method service
SECURITY_IME = 1, // index for security input method service
MAX_IME = 2, // the maximum count of ims started for a user
};
enum : uint32_t {
DEFAULT_IME = 0, // index for default input method service
SECURITY_IME, // index for security input method service
MAX_IME // the maximum count of ims started for a user
};
public:
explicit PerUserSession(int userId);
@ -123,11 +107,12 @@ namespace MiscServices {
int userState; // the state of the user to whom the object is linking
int displayId; // the id of the display screen on which the user is
int currentIndex;
std::map<sptr<IRemoteObject>, ClientInfo*> mapClients;
int MIN_IME = 2;
int IME_ERROR_CODE = 3;
int COMMON_COUNT_THREE_HUNDRED = 300;
int SLEEP_TIME = 300000;
std::map<IRemoteObject *, ClientInfo *> mapClients;
static const int MIN_IME = 2;
static const int MAX_RESTART_NUM = 3;
static const int IME_RESET_TIME_OUT = 300;
static const int MAX_RESET_WAIT_TIME = 1600000;
static const int SLEEP_TIME = 300000;
InputMethodProperty *currentIme[MAX_IME]; // 0 - the default ime. 1 - security ime
@ -142,21 +127,22 @@ namespace MiscServices {
sptr<IInputMethodAgent> imsAgent;
InputChannel *imsChannel; // the write channel created by input method service
std::mutex clientLock_;
sptr<IInputClient> currentClient; // the current input client
sptr<IInputClient> needReshowClient; // the input client for which keyboard need to re-show
sptr<RemoteObjectDeathRecipient> clientDeathRecipient; // remote object death monitor for input client
sptr<RemoteObjectDeathRecipient> imsDeathRecipient;
MessageHandler *msgHandler = nullptr; // message handler working with Work Thread
std::thread workThreadHandler; // work thread handler
std::mutex mtx; // mutex to lock the operations among multi work threads
sptr<AAFwk::AbilityConnectionProxy> connCallback;
std::mutex resetLock;
ResetManager manager[MAX_IME];
PerUserSession(const PerUserSession&);
PerUserSession& operator =(const PerUserSession&);
PerUserSession(const PerUserSession&&);
PerUserSession& operator =(const PerUserSession&&);
int IncreaseOrResetImeError(bool resetFlag, int imeIndex);
KeyboardType *GetKeyboardType(int imeIndex, int typeIndex);
void ResetCurrentKeyboardType(int imeIndex);
int OnCurrentKeyboardTypeChanged(int index, const std::u16string& value);
@ -168,18 +154,16 @@ namespace MiscServices {
void OnStartInput(Message *msg);
void OnStopInput(Message *msg);
void SetCoreAndAgent(Message *msg);
void OnClientDied(const wptr<IRemoteObject>& who);
void OnImsDied(const wptr<IRemoteObject>& who);
void OnClientDied(IRemoteObject *who);
void OnImsDied(IRemoteObject *who);
void OnHideKeyboardSelf(int flags);
void OnShowKeyboardSelf();
void OnAdvanceToNext();
void OnSetDisplayMode(int mode);
void OnRestartIms(int index, const std::u16string& imeId);
void OnUserLocked();
int AddClient(int pid, int uid, int displayId, const sptr<IInputClient>& inputClient,
const sptr<IInputDataChannel>& channel,
const InputAttribute& attribute);
int RemoveClient(const sptr<IInputClient>& inputClient, int retClientNum);
int AddClient(const ClientInfo &clientInfo);
void RemoveClient(IRemoteObject *inputClient);
int StartInputMethod(int index);
int StopInputMethod(int index);
int ShowKeyboard(const sptr<IInputClient>& inputClient, bool isShowKeyboard);
@ -190,6 +174,11 @@ namespace MiscServices {
void SendAgentToSingleClient(const sptr<IInputClient>& inputClient);
void InitInputControlChannel();
void SendAgentToAllClients();
void ResetImeError(uint32_t index);
bool IsRestartIme(uint32_t index);
void ClearImeData(uint32_t index);
void SetCurrentClient(sptr<IInputClient> client);
sptr<IInputClient> GetCurrentClient();
};
} // namespace MiscServices
} // namespace OHOS

View File

@ -31,6 +31,7 @@ namespace OHOS {
namespace MiscServices {
class Utils {
public:
static constexpr int USER_ID_CHANGE_VALUE = 200000;
static std::string to_utf8(std::u16string str16)
{
return std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(str16);
@ -47,6 +48,10 @@ namespace MiscServices {
}
return props;
}
static uint32_t ToUserId(uint32_t uid)
{
return uid / USER_ID_CHANGE_VALUE;
}
};
} // namespace MiscServices
} // namespace OHOS

View File

@ -471,6 +471,11 @@ namespace MiscServices {
return properties;
}
int32_t InputMethodSystemAbility::SwitchInputMethod(const InputMethodProperty &target)
{
return ErrorCode::NO_ERROR;
}
/*! Get all of the input method engine list installed in the system
\n Run in binder thread
\param[out] properties input method engine list returned to the caller
@ -483,9 +488,11 @@ namespace MiscServices {
IMSA_HILOGI("InputMethodSystemAbility::ListInputMethodByUserId");
if (status == InputMethodStatus::ALL) {
return ListAllInputMethod(userId);
} else if (status == InputMethodStatus::ENABLE) {
}
if (status == InputMethodStatus::ENABLE) {
return ListEnabledInputMethod();
} else if (status == InputMethodStatus::DISABLE) {
}
if (status == InputMethodStatus::DISABLE) {
return ListDisabledInputMethod(userId);
}
return {};
@ -550,18 +557,19 @@ namespace MiscServices {
IMSA_HILOGI("InputMethodSystemAbility::GetCurrentInputMethod");
std::string ime = ParaHandle::GetDefaultIme(MAIN_USER_ID);
if (ime.empty()) {
IMSA_HILOGE("InputMethodSystemAbility::GetCurrentInputMethod propertyStr is empty");
IMSA_HILOGE("InputMethodSystemAbility::GetCurrentInputMethod ime is empty");
return nullptr;
}
int pos = ime.find('/');
std::string::size_type pos = ime.find('/');
if (pos == -1) {
IMSA_HILOGE("InputMethodSystemAbility::GetCurrentInputMethod propertyStr can not find '/'");
IMSA_HILOGE("InputMethodSystemAbility::GetCurrentInputMethod ime can not find '/'");
return nullptr;
}
auto property = std::make_shared<InputMethodProperty>();
if (property == nullptr) {
IMSA_HILOGE("InputMethodSystemAbility property is nullptr");
return nullptr;
}
property->mPackageName = Str8ToStr16(ime.substr(0, pos));
@ -690,6 +698,12 @@ namespace MiscServices {
delete target;
break;
}
case MSG_ID_START_INPUT_SERVICE: {
MessageParcel *data = msg->msgContent_;
const auto &ime = data->ReadString();
StartInputService(ime);
break;
}
default: {
break;
}

View File

@ -17,12 +17,16 @@
#include <memory>
#include "access_token.h"
#include "accesstoken_kit.h"
#include "ipc_skeleton.h"
#include "message_handler.h"
namespace OHOS {
namespace MiscServices {
using namespace MessageID;
using namespace Security::AccessToken;
static const std::string PERMISSION_CONNECT_IME_ABILITY = "ohos.permission.CONNECT_IME_ABILITY";
/*! Handle the transaction from the remote binder
\n Run in binder thread
\param code transaction code number
@ -65,9 +69,7 @@ namespace MiscServices {
break;
}
case SET_CORE_AND_AGENT: {
MessageParcel *msgParcel = (MessageParcel*) &data;
SetCoreAndAgent(*msgParcel);
reply.WriteInt32(NO_ERROR);
SetCoreAndAgent(data);
break;
}
case GET_DISPLAY_MODE: {
@ -132,13 +134,13 @@ namespace MiscServices {
break;
}
case DISPLAY_OPTIONAL_INPUT_METHOD: {
displayOptionalInputMethod(data);
reply.WriteInt32(NO_ERROR);
int32_t ret = displayOptionalInputMethod(data);
reply.WriteInt32(ret);
break;
}
case HIDE_CURRENT_INPUT: {
HideCurrentInput(data);
reply.WriteInt32(NO_ERROR);
int32_t ret = HideCurrentInput(data);
reply.WriteInt32(ret);
break;
}
case SHOW_CURRENT_INPUT: {
@ -147,7 +149,7 @@ namespace MiscServices {
break;
}
case SWITCH_INPUT_METHOD: {
int32_t ret = SwitchInputMethod(data);
int32_t ret = OnSwitchInputMethod(data);
reply.WriteInt32(ret);
break;
}
@ -155,6 +157,25 @@ namespace MiscServices {
OnGetCurrentInputMethod(reply);
break;
}
case SHOW_CURRENT_INPUT_DEPRECATED: {
int32_t ret = ShowCurrentInputDeprecated(data);
reply.WriteInt32(ret);
break;
}
case HIDE_CURRENT_INPUT_DEPRECATED: {
int32_t ret = HideCurrentInputDeprecated(data);
reply.WriteInt32(ret);
break;
}
case DISPLAY_OPTIONAL_INPUT_METHOD_DEPRECATED: {
int ret = DisplayOptionalInputMethodDeprecated(data);
reply.WriteInt32(ret);
break;
}
case SET_CORE_AND_AGENT_DEPRECATED: {
SetCoreAndAgentDeprecated(data);
break;
}
default: {
return BRemoteObject::OnRemoteRequest(code, data, reply, option);
}
@ -190,17 +211,17 @@ namespace MiscServices {
int32_t InputMethodSystemAbilityStub::displayOptionalInputMethod(MessageParcel& data)
{
IMSA_HILOGI("InputMethodSystemAbilityStub::displayOptionalInputMethod");
if (!CheckPermission(PERMISSION_CONNECT_IME_ABILITY)) {
IMSA_HILOGE("Permission denied");
return ErrorCode::ERROR_STATUS_PERMISSION_DENIED;
}
int32_t pid = IPCSkeleton::GetCallingPid();
int32_t uid = IPCSkeleton::GetCallingUid();
int32_t userId = getUserId(uid);
MessageParcel *parcel = new MessageParcel();
parcel->WriteInt32(userId);
parcel->WriteInt32(pid);
parcel->WriteInt32(uid);
Message *msg = new Message(MSG_ID_DISPLAY_OPTIONAL_INPUT_METHOD, parcel);
MessageHandler::Instance()->SendMessage(msg);
return ErrorCode::NO_ERROR;
return SendMessageToService(
MSG_ID_DISPLAY_OPTIONAL_INPUT_METHOD, [pid, uid, userId](MessageParcel &parcel) -> bool {
return parcel.WriteInt32(userId) && parcel.WriteInt32(pid) && parcel.WriteInt32(uid);
});
}
/*! Release input
@ -268,6 +289,10 @@ namespace MiscServices {
void InputMethodSystemAbilityStub::SetCoreAndAgent(MessageParcel& data)
{
IMSA_HILOGI("InputMethodSystemAbilityStub::SetCoreAndAgent");
if (!CheckPermission(PERMISSION_CONNECT_IME_ABILITY)) {
IMSA_HILOGE("Permission denied");
return;
}
int32_t uid = IPCSkeleton::GetCallingUid();
int32_t userId = getUserId(uid);
MessageParcel *parcel = new MessageParcel();
@ -279,42 +304,33 @@ namespace MiscServices {
MessageHandler::Instance()->SendMessage(msg);
}
int32_t InputMethodSystemAbilityStub::HideCurrentInput(MessageParcel& data)
int32_t InputMethodSystemAbilityStub::HideCurrentInput(MessageParcel &data)
{
IMSA_HILOGI("InputMethodSystemAbilityStub::HideCurrentInput");
int32_t uid = IPCSkeleton::GetCallingUid();
int32_t userId = getUserId(uid);
MessageParcel *parcel = new MessageParcel();
parcel->WriteInt32(userId);
Message *msg = new Message(MSG_HIDE_CURRENT_INPUT, parcel);
MessageHandler::Instance()->SendMessage(msg);
return ErrorCode::NO_ERROR;
if (!CheckPermission(PERMISSION_CONNECT_IME_ABILITY)) {
IMSA_HILOGE("Permission denied");
return ErrorCode::ERROR_STATUS_PERMISSION_DENIED;
}
int userId = getUserId(IPCSkeleton::GetCallingUid());
return SendMessageToService(
MSG_HIDE_CURRENT_INPUT, [userId](MessageParcel &parcel) -> bool { return parcel.WriteInt32(userId); });
}
int32_t InputMethodSystemAbilityStub::ShowCurrentInput(MessageParcel &data)
{
IMSA_HILOGI("InputMethodSystemAbilityStub::ShowCurrentInput");
int32_t uid = IPCSkeleton::GetCallingUid();
int32_t userId = getUserId(uid);
auto *parcel = new (std::nothrow) MessageParcel();
if (parcel == nullptr) {
return ErrorCode::ERROR_EX_NULL_POINTER;
if (!CheckPermission(PERMISSION_CONNECT_IME_ABILITY)) {
IMSA_HILOGE("Permission denied");
return ErrorCode::ERROR_STATUS_PERMISSION_DENIED;
}
parcel->WriteInt32(userId);
auto *msg = new (std::nothrow) Message(MSG_SHOW_CURRENT_INPUT, parcel);
if (msg == nullptr) {
return ErrorCode::ERROR_EX_NULL_POINTER;
}
MessageHandler::Instance()->SendMessage(msg);
return ErrorCode::NO_ERROR;
int userId = getUserId(IPCSkeleton::GetCallingUid());
return SendMessageToService(
MSG_SHOW_CURRENT_INPUT, [userId](MessageParcel &parcel) -> bool { return parcel.WriteInt32(userId); });
}
int32_t InputMethodSystemAbilityStub::SwitchInputMethod(MessageParcel &data)
int32_t InputMethodSystemAbilityStub::OnSwitchInputMethod(MessageParcel &data)
{
IMSA_HILOGI("InputMethodSystemAbilityStub::switchInputMethod");
IMSA_HILOGI("InputMethodSystemAbilityStub::OnSwitchInputMethod");
int32_t uid = IPCSkeleton::GetCallingUid();
int32_t userId = getUserId(uid);
@ -329,6 +345,7 @@ namespace MiscServices {
auto *msg = new (std::nothrow) Message(MSG_ID_SWITCH_INPUT_METHOD, parcel);
if (msg == nullptr) {
delete parcel;
return ErrorCode::ERROR_EX_NULL_POINTER;
}
MessageHandler::Instance()->SendMessage(msg);
@ -354,11 +371,6 @@ namespace MiscServices {
int32_t userId = getUserId(uid);
uint32_t status = data.ReadUint32();
const auto &properties = ListInputMethodByUserId(userId, InputMethodStatus(status));
if (properties.empty()) {
IMSA_HILOGE("InputMethodSystemAbilityStub ListInputMethodByUserId failed");
reply.WriteInt32(ErrorCode::ERROR_LIST_IME);
return;
}
reply.WriteInt32(NO_ERROR);
uint32_t size = properties.size();
reply.WriteUint32(size);
@ -367,6 +379,85 @@ namespace MiscServices {
}
}
int32_t InputMethodSystemAbilityStub::ShowCurrentInputDeprecated(MessageParcel &data)
{
IMSA_HILOGI("InputMethodSystemAbilityStub::ShowCurrentInputDeprecated");
int userId = getUserId(IPCSkeleton::GetCallingUid());
return SendMessageToService(
MSG_SHOW_CURRENT_INPUT, [userId](MessageParcel &parcel) -> bool { return parcel.WriteInt32(userId); });
}
int32_t InputMethodSystemAbilityStub::HideCurrentInputDeprecated(MessageParcel &data)
{
IMSA_HILOGI("InputMethodSystemAbilityStub::HideCurrentInputDeprecated");
int userId = getUserId(IPCSkeleton::GetCallingUid());
return SendMessageToService(
MSG_HIDE_CURRENT_INPUT, [userId](MessageParcel &parcel) -> bool { return parcel.WriteInt32(userId); });
}
int32_t InputMethodSystemAbilityStub::DisplayOptionalInputMethodDeprecated(MessageParcel &data)
{
IMSA_HILOGI("InputMethodSystemAbilityStub::DisplayOptionalInputMethodDeprecated");
int32_t pid = IPCSkeleton::GetCallingPid();
int32_t uid = IPCSkeleton::GetCallingUid();
int32_t userId = getUserId(uid);
return SendMessageToService(
MSG_ID_DISPLAY_OPTIONAL_INPUT_METHOD, [pid, uid, userId](MessageParcel &parcel) -> bool {
return parcel.WriteInt32(userId) && parcel.WriteInt32(pid) && parcel.WriteInt32(uid);
});
}
void InputMethodSystemAbilityStub::SetCoreAndAgentDeprecated(MessageParcel &data)
{
IMSA_HILOGI("InputMethodSystemAbilityStub::SetCoreAndAgentDeprecated");
int32_t userId = getUserId(IPCSkeleton::GetCallingUid());
int32_t ret = SendMessageToService(MSG_ID_SET_CORE_AND_AGENT, [userId, &data](MessageParcel &parcel) -> bool {
return parcel.WriteInt32(userId) && parcel.WriteRemoteObject(data.ReadRemoteObject())
&& parcel.WriteRemoteObject(data.ReadRemoteObject());
});
if (ret != NO_ERROR) {
IMSA_HILOGE("send message to service failed: %{public}s", ErrorCode::ToString(ret));
}
}
bool InputMethodSystemAbilityStub::CheckPermission(const std::string &permission)
{
IMSA_HILOGI("Check Permission");
AccessTokenID tokenId = IPCSkeleton::GetCallingTokenID();
TypeATokenTypeEnum tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
if (tokenType == TOKEN_INVALID) {
IMSA_HILOGE("invalid token id %{public}d", tokenId);
return false;
}
int result = AccessTokenKit::VerifyAccessToken(tokenId, permission);
IMSA_HILOGI("CheckPermission result: %{public}s", result == PERMISSION_GRANTED ? "success" : "failed");
return result == PERMISSION_GRANTED;
}
int32_t InputMethodSystemAbilityStub::SendMessageToService(
int32_t code, std::function<bool(MessageParcel &)> callback)
{
auto parcel = new (std::nothrow) MessageParcel();
if (parcel == nullptr) {
IMSA_HILOGE("parcel is nullptr");
return ErrorCode::ERROR_NULL_POINTER;
}
bool ret = callback(*parcel);
if (!ret) {
IMSA_HILOGE("failed to write parcel");
delete parcel;
return ErrorCode::ERROR_STATUS_FAILED_TRANSACTION;
}
auto msg = new Message(code, parcel);
if (msg == nullptr) {
IMSA_HILOGE("msg is nullptr");
delete parcel;
return ErrorCode::ERROR_NULL_POINTER;
}
MessageHandler::Instance()->SendMessage(msg);
return ErrorCode::NO_ERROR;
}
/*! Get user id from uid
\param uid the uid from which the remote call is
\return return user id of the remote caller

View File

@ -33,6 +33,7 @@
#include "ipc_skeleton.h"
#include "input_method_core_proxy.h"
#include "input_method_agent_proxy.h"
#include "para_handle.h"
namespace OHOS {
namespace MiscServices {
@ -56,12 +57,21 @@ namespace MiscServices {
\n It's called when the linked remote object died.
\param who the IRemoteObject handler of the remote object died.
*/
void RemoteObjectDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& who)
void RemoteObjectDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &who)
{
MessageParcel *parcel = new MessageParcel();
auto parcel = new (std::nothrow) MessageParcel();
if (parcel == nullptr) {
IMSA_HILOGE("parcel is nullptr");
return;
}
parcel->WriteInt32(userId_);
parcel->WriteRemoteObject(who.promote());
Message *msg = new Message(msgId_, parcel);
parcel->WritePointer(reinterpret_cast<uintptr_t>(who.GetRefPtr()));
auto msg = new (std::nothrow) Message(msgId_, parcel);
if (msg == nullptr) {
IMSA_HILOGE("msg is nullptr");
delete parcel;
return;
}
MessageHandler::Instance()->SendMessage(msg);
}
@ -77,7 +87,6 @@ namespace MiscServices {
needReshowClient = nullptr;
clientDeathRecipient = new RemoteObjectDeathRecipient(userId, MSG_ID_CLIENT_DIED);
imsDeathRecipient = new RemoteObjectDeathRecipient(userId, MSG_ID_IMS_DIED);
}
@ -88,7 +97,6 @@ namespace MiscServices {
if (userState == UserState::USER_STATE_UNLOCKED) {
OnUserLocked();
}
clientDeathRecipient = nullptr;
imsDeathRecipient = nullptr;
if (workThreadHandler.joinable()) {
workThreadHandler.join();
@ -153,12 +161,20 @@ namespace MiscServices {
break;
}
case MSG_ID_CLIENT_DIED: {
wptr<IRemoteObject> who = msg->msgContent_->ReadRemoteObject();
auto *who = reinterpret_cast<IRemoteObject *>(msg->msgContent_->ReadPointer());
if (who == nullptr) {
IMSA_HILOGE("who is nullptr");
break;
}
OnClientDied(who);
break;
}
case MSG_ID_IMS_DIED: {
wptr<IRemoteObject> who = msg->msgContent_->ReadRemoteObject();
auto *who = reinterpret_cast<IRemoteObject *>(msg->msgContent_->ReadPointer());
if (who == nullptr) {
IMSA_HILOGE("who is nullptr");
break;
}
OnImsDied(who);
break;
}
@ -250,7 +266,7 @@ namespace MiscServices {
if (imsCore[i]) {
StopInputMethod(i);
}
IncreaseOrResetImeError(true, i);
ResetImeError(i);
currentIme[i] = ime[i];
if (!currentIme[i]) {
if (needReshowClient && GetImeIndex(needReshowClient) == i) {
@ -259,9 +275,8 @@ namespace MiscServices {
continue;
}
std::map<sptr<IRemoteObject>, ClientInfo*>::const_iterator it;
bool flag = false;
for (it = mapClients.cbegin(); it != mapClients.cend(); ++it) {
for (auto it = mapClients.cbegin(); it != mapClients.cend(); ++it) {
if ((i == DEFAULT_IME && !it->second->attribute.GetSecurityFlag()) ||
(i == SECURITY_IME && it->second->attribute.GetSecurityFlag())) {
flag = true;
@ -292,10 +307,11 @@ namespace MiscServices {
bool flag = false;
std::unique_lock<std::mutex> lock(mtx);
for (int i = 0; i < MAX_IME; i++) {
sptr<IInputClient> client = GetCurrentClient();
if (currentIme[i] && currentIme[i]->mPackageName == packageName) {
if (currentClient && GetImeIndex(currentClient) == i) {
needReshowClient = currentClient;
HideKeyboard(currentClient);
if (client != nullptr && GetImeIndex(client) == i) {
needReshowClient = client;
HideKeyboard(client);
}
StopInputMethod(i);
currentIme[i] = nullptr;
@ -326,69 +342,49 @@ namespace MiscServices {
\return \li ErrorCode::NO_ERROR no error
\return \li ErrorCode::ERROR_CLIENT_DUPLICATED client is duplicated
*/
int PerUserSession::AddClient(int pid, int uid, int displayId, const sptr<IInputClient>& inputClient,
const sptr<IInputDataChannel>& channel,
const InputAttribute& attribute)
int PerUserSession::AddClient(const ClientInfo &clientInfo)
{
IMSA_HILOGI("PerUserSession::AddClient");
ClientInfo *clientInfo = GetClientInfo(inputClient);
if (clientInfo) {
IMSA_HILOGE("PerUserSession::AddClient clientInfo is exist, not need add.");
ClientInfo *info = GetClientInfo(clientInfo.client);
if (info != nullptr) {
IMSA_HILOGE("PerUserSession::AddClient info is exist, not need add.");
return ErrorCode::NO_ERROR;
}
sptr<IRemoteObject> obj = clientInfo.client->AsObject();
if (obj == nullptr) {
IMSA_HILOGE("PerUserSession::AddClient inputClient AsObject is nullptr");
return ErrorCode::ERROR_REMOTE_CLIENT_DIED;
}
bool ret = obj->AddDeathRecipient(clientInfo.deathRecipient);
IMSA_HILOGI("Add death recipient %{public}s", ret ? "success" : "failed");
sptr<IRemoteObject> obj = inputClient->AsObject();
if (!obj) {
IMSA_HILOGE("PerUserSession::AddClient inputClient AsObject is nullptr");
return ErrorCode::ERROR_REMOTE_CLIENT_DIED;
}
clientInfo = new ClientInfo(pid, uid, userId_, displayId, inputClient, channel, attribute);
mapClients.insert(std::pair<sptr<IRemoteObject>, ClientInfo*>(obj, clientInfo));
int ret = obj->AddDeathRecipient(clientDeathRecipient);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("PerUserSession::AddClient AddDeathRecipient return : %{public}s", ErrorCode::ToString(ret));
info = new (std::nothrow) ClientInfo(clientInfo);
if (info == nullptr) {
IMSA_HILOGE("info is nullptr");
return ErrorCode::ERROR_NULL_POINTER;
}
mapClients.insert({ obj, info });
return ErrorCode::NO_ERROR;
}
/*! Remove an input client
\param inputClient remote object handler of the input client
\param[out] remainClientNum remained count of the same kinds of clients for this user
\n (i.e. if inputClient is an normal client, remainClientNum is the count of remained normal clients.
\n if inputClient is a security client, remainClientNum is the count of remained security clients.)
\return ErrorCode::NO_ERROR no error
\return ErrorCode::ERROR_CLIENT_NOT_FOUND client is not found
*/
int PerUserSession::RemoveClient(const sptr<IInputClient>& inputClient, int remainClientNum)
void PerUserSession::RemoveClient(IRemoteObject *inputClient)
{
IMSA_HILOGE("PerUserSession::RemoveClient");
sptr<IRemoteObject> b = inputClient->AsObject();
std::map<sptr<IRemoteObject>, ClientInfo*>::iterator it = mapClients.find(b);
auto it = mapClients.find(inputClient);
if (it == mapClients.end()) {
IMSA_HILOGE("PerUserSession::RemoveClient ErrorCode::ERROR_CLIENT_NOT_FOUND");
return ErrorCode::ERROR_CLIENT_NOT_FOUND;
IMSA_HILOGE("PerUserSession::RemoveClient client not found");
return;
}
ClientInfo *clientInfo = it->second;
bool flag = clientInfo->attribute.GetSecurityFlag();
int ret = b->RemoveDeathRecipient(clientDeathRecipient);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("PerUserSession::RemoveClient RemoveDeathRecipient fail %{public}s", ErrorCode::ToString(ret));
}
ret = clientInfo->client->onInputReleased(0);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("PerUserSession::RemoveClient onInputReleased fail %{public}s", ErrorCode::ToString(ret));
}
inputClient->RemoveDeathRecipient(clientInfo->deathRecipient);
delete clientInfo;
clientInfo = nullptr;
mapClients.erase(it);
remainClientNum = 0;
for (it = mapClients.begin(); it != mapClients.end(); ++it) {
if (it->second->attribute.GetSecurityFlag() == flag) {
remainClientNum++;
}
}
return ErrorCode::NO_ERROR;
}
/*! Start input method service
@ -487,19 +483,19 @@ namespace MiscServices {
IMSA_HILOGI("PerUserSession::ShowKeyboard");
ClientInfo *clientInfo = GetClientInfo(inputClient);
int index = GetImeIndex(inputClient);
if (index == -1 || !clientInfo) {
if (index == -1 || clientInfo == nullptr) {
IMSA_HILOGE("PerUserSession::ShowKeyboard Aborted! index = -1 or clientInfo is nullptr");
return ErrorCode::ERROR_CLIENT_NOT_FOUND;
}
if (!imsCore[0]) {
if (imsCore[0] == nullptr) {
IMSA_HILOGE("PerUserSession::ShowKeyboard Aborted! imsCore[%{public}d] is nullptr", index);
return ErrorCode::ERROR_NULL_POINTER;
}
imsCore[0]->showKeyboard(clientInfo->channel, isShowKeyboard);
currentClient = inputClient;
SetCurrentClient(inputClient);
return ErrorCode::NO_ERROR;
}
@ -521,10 +517,10 @@ namespace MiscServices {
return ErrorCode::ERROR_CLIENT_NOT_FOUND;
}
ClientInfo *clientInfo = GetClientInfo(inputClient);
if (!clientInfo) {
if (clientInfo == nullptr) {
IMSA_HILOGE("PerUserSession::HideKeyboard GetClientInfo pointer nullptr");
}
if (!imsCore[0]) {
if (imsCore[0] == nullptr) {
IMSA_HILOGE("PerUserSession::HideKeyboard imsCore[index] is nullptr");
return ErrorCode::ERROR_IME_NOT_STARTED;
}
@ -600,78 +596,67 @@ namespace MiscServices {
It's called when a remote input client died
\param who the remote object handler of the input client died.
*/
void PerUserSession::OnClientDied(const wptr<IRemoteObject>& who)
void PerUserSession::OnClientDied(IRemoteObject *who)
{
IMSA_HILOGI("PerUserSession::OnClientDied Start...[%{public}d]\n", userId_);
bool flag = false;
std::map<sptr<IRemoteObject>, ClientInfo*>::iterator it;
for (it = mapClients.begin(); it != mapClients.end(); ++it) {
if (it->first == who) {
flag = true;
break;
}
}
if (!flag) {
IMSA_HILOGW("Aborted! The client died is not found! [%{public}d]\n", userId_);
auto it = mapClients.find(who);
if (it == mapClients.end()) {
IMSA_HILOGE("PerUserSession::RemoveClient client not found");
return;
}
sptr<IInputClient> client = it->second->client;
int remainClientNum = 0;
if (currentClient) {
HideKeyboard(client);
sptr<IInputClient> client = GetCurrentClient();
if (client == nullptr) {
IMSA_HILOGE("current client is nullptr");
RemoveClient(it->first);
return;
}
RemoveClient(client, remainClientNum);
if (client->AsObject().GetRefPtr() == who) {
int ret = HideKeyboard(client);
IMSA_HILOGI("hide keyboard ret: %{public}s", ErrorCode::ToString(ret));
}
RemoveClient(it->first);
}
/*! Handle the situation a input method service died\n
It's called when an input method service died
\param who the remote object handler of input method service who died.
*/
void PerUserSession::OnImsDied(const wptr<IRemoteObject>& who)
void PerUserSession::OnImsDied(IRemoteObject *who)
{
(void)who; // temporary void it, as we will add support for security IME.
(void)who;
IMSA_HILOGI("Start...[%{public}d]\n", userId_);
int index = 0;
for (int i = 0; i < MAX_IME; i++) {
if (!imsCore[i]) {
if (imsCore[i] == nullptr) {
continue;
}
sptr<IRemoteObject> b = imsCore[i]->AsObject();
if (b == who) {
auto b = imsCore[i]->AsObject();
if (b.GetRefPtr() == who) {
index = i;
break;
}
}
if (currentClient && (GetImeIndex(currentClient) == index ||
currentIme[index] == currentIme[1 - index])) {
needReshowClient = currentClient;
HideKeyboard(currentClient);
ClearImeData(index);
if (!IsRestartIme(index)) {
IMSA_HILOGI("Restart ime over max num");
return;
}
StopInputMethod(index);
if (currentIme[index] == currentIme[1 - index]) {
StopInputMethod(1 - index);
IMSA_HILOGI("IME died. Restart input method...[%{public}d]\n", userId_);
const auto &ime = ParaHandle::GetDefaultIme(userId_);
auto *parcel = new (std::nothrow) MessageParcel();
if (parcel == nullptr) {
IMSA_HILOGE("parcel is nullptr");
return;
}
if (IncreaseOrResetImeError(false, index) == IME_ERROR_CODE) {
// call to disable the current input method.
MessageParcel *parcel = new MessageParcel();
parcel->WriteInt32(userId_);
parcel->WriteString16(currentIme[index]->mImeId);
Message *msg = new Message(MSG_ID_DISABLE_IMS, parcel);
MessageHandler::Instance()->SendMessage(msg);
} else {
// restart current input method.
IMSA_HILOGI("IME died. Restart input method ! [%{public}d]\n", userId_);
MessageParcel *parcel = new MessageParcel();
parcel->WriteInt32(userId_);
parcel->WriteInt32(index);
parcel->WriteString16(currentIme[index]->mImeId);
Message *msg = new Message(MSG_ID_RESTART_IMS, parcel);
usleep(1600*1000); // wait that PACKAGE_REMOVED message is received if this ime has been removed
MessageHandler::Instance()->SendMessage(msg);
parcel->WriteString(ime);
auto *msg = new (std::nothrow) Message(MSG_ID_START_INPUT_SERVICE, parcel);
if (msg == nullptr) {
IMSA_HILOGE("msg is nullptr");
delete parcel;
return;
}
usleep(MAX_RESET_WAIT_TIME);
MessageHandler::Instance()->SendMessage(msg);
IMSA_HILOGI("End...[%{public}d]\n", userId_);
}
@ -698,30 +683,29 @@ namespace MiscServices {
IMSA_HILOGI("End...[%{public}d]\n", userId_);
return ErrorCode::ERROR_SETTING_SAME_VALUE;
}
sptr<IInputClient> client = GetCurrentClient();
if (key == InputMethodSetting::CURRENT_KEYBOARD_TYPE_TAG) {
return OnCurrentKeyboardTypeChanged(DEFAULT_IME, value);
} else if (key == InputMethodSetting::CURRENT_SYS_KEYBOARD_TYPE_TAG) {
return OnCurrentKeyboardTypeChanged(SECURITY_IME, value);
} else if (key == InputMethodSetting::CURRENT_INPUT_METHOD_TAG) {
if (!currentIme[DEFAULT_IME] ||
value == currentIme[DEFAULT_IME]->mImeId) {
if (currentIme[DEFAULT_IME] == nullptr || value == currentIme[DEFAULT_IME]->mImeId) {
return ErrorCode::NO_ERROR;
}
if (currentClient && GetImeIndex(currentClient) == DEFAULT_IME) {
needReshowClient = currentClient;
HideKeyboard(currentClient);
if (client != nullptr && GetImeIndex(client) == DEFAULT_IME) {
needReshowClient = client;
HideKeyboard(client);
}
StopInputMethod(DEFAULT_IME);
currentIme[DEFAULT_IME] = nullptr;
currentKbdIndex[DEFAULT_IME] = 0;
inputMethodSetting->SetCurrentKeyboardType(-1);
} else if (key == InputMethodSetting::ENABLED_INPUT_METHODS_TAG) {
if (currentIme[DEFAULT_IME] && currentIme[DEFAULT_IME] != currentIme[SECURITY_IME]
if (currentIme[DEFAULT_IME] != nullptr && currentIme[DEFAULT_IME] != currentIme[SECURITY_IME]
&& value.find(currentIme[DEFAULT_IME]->mImeId) == std::string::npos) {
if (currentClient && GetImeIndex(currentClient) == DEFAULT_IME) {
needReshowClient = currentClient;
HideKeyboard(currentClient);
if (client != nullptr && GetImeIndex(client) == DEFAULT_IME) {
needReshowClient = client;
HideKeyboard(client);
}
StopInputMethod(DEFAULT_IME);
currentIme[DEFAULT_IME] = nullptr;
@ -774,7 +758,8 @@ namespace MiscServices {
}
KeyboardType *type = GetKeyboardType(index, currentKbdIndex[index]);
if (type) {
if (currentClient) {
sptr<IInputClient> client = GetCurrentClient();
if (client != nullptr) {
int ret = imsCore[index]->setKeyboardType(*type);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("setKeyboardType return : %{public}s [%{public}d]\n", ErrorCode::ToString(ret), userId_);
@ -800,20 +785,35 @@ namespace MiscServices {
{
IMSA_HILOGW("PerUserSession::OnHideKeyboardSelf");
(void) flags;
HideKeyboard(currentClient);
sptr<IInputClient> client = GetCurrentClient();
if (client == nullptr) {
IMSA_HILOGE("current client is nullptr");
return;
}
HideKeyboard(client);
}
void PerUserSession::OnShowKeyboardSelf()
{
IMSA_HILOGI("PerUserSession::OnShowKeyboardSelf");
ShowKeyboard(currentClient, true);
sptr<IInputClient> client = GetCurrentClient();
if (client == nullptr) {
IMSA_HILOGE("current client is nullptr");
return;
}
ShowKeyboard(client, true);
}
/*! Switch to next keyboard type
*/
void PerUserSession::OnAdvanceToNext()
{
int index = GetImeIndex(currentClient);
sptr<IInputClient> client = GetCurrentClient();
if (client == nullptr) {
IMSA_HILOGE("current client is nullptr");
return;
}
int index = GetImeIndex(client);
if (index == -1) {
IMSA_HILOGW("%{public}s [%{public}d]\n", ErrorCode::ToString(ErrorCode::ERROR_CLIENT_NOT_FOUND), userId_);
return;
@ -836,7 +836,7 @@ namespace MiscServices {
num %= size;
}
KeyboardType *type = GetKeyboardType(index, num);
if (!type) {
if (type == nullptr) {
IMSA_HILOGW("No next keyboard is available. [%{public}d]\n", userId_);
return;
}
@ -860,8 +860,13 @@ namespace MiscServices {
void PerUserSession::OnSetDisplayMode(int mode)
{
currentDisplayMode = mode;
ClientInfo *clientInfo = GetClientInfo(currentClient);
if (!clientInfo) {
sptr<IInputClient> client = GetCurrentClient();
if (client == nullptr) {
IMSA_HILOGE("current client is nullptr");
return;
}
ClientInfo *clientInfo = GetClientInfo(client);
if (clientInfo == nullptr) {
IMSA_HILOGE("%{public}s [%{public}d]\n", ErrorCode::ToString(ErrorCode::ERROR_CLIENT_NOT_FOUND), userId_);
return;
}
@ -904,20 +909,20 @@ namespace MiscServices {
}
userState = UserState::USER_STATE_STARTED;
// hide current keyboard
if (currentClient) {
HideKeyboard(currentClient);
sptr<IInputClient> client = GetCurrentClient();
if (client != nullptr) {
HideKeyboard(client);
}
for (int i = 0; i < MIN_IME; i++) {
StopInputMethod(i);
currentIme[i] = nullptr;
}
// disconnect all clients.
std::map<sptr<IRemoteObject>, ClientInfo*>::iterator it;
for (it = mapClients.begin(); it != mapClients.end();) {
sptr<IRemoteObject> b = it->first;
b->RemoveDeathRecipient(clientDeathRecipient);
for (auto it = mapClients.begin(); it != mapClients.end();) {
auto b = it->first;
ClientInfo *clientInfo = it->second;
if (clientInfo) {
if (clientInfo != nullptr) {
b->RemoveDeathRecipient(clientInfo->deathRecipient);
int ret = clientInfo->client->onInputReleased(0);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("2-onInputReleased return : %{public}s", ErrorCode::ToString(ret));
@ -932,39 +937,10 @@ namespace MiscServices {
// reset values
inputMethodSetting = nullptr;
currentClient = nullptr;
SetCurrentClient(nullptr);
needReshowClient = nullptr;
}
/*! Increase or reset ime error number
\param resetFlag the flag to increase or reset number.
\n resetFlag=true, reset error number to 0;
\n resetFlag=false, increase error number.
\param imeIndex index = 0 default ime; index=1 security ime
\return return the error count value. It is less or equal 3.
*/
int PerUserSession::IncreaseOrResetImeError(bool resetFlag, int imeIndex)
{
static int errorNum[2] = {0, 0};
static time_t past[2] = {time(0), time(0)};
if (resetFlag) {
errorNum[imeIndex] = 0;
past[imeIndex] = 0;
return 0;
}
errorNum[imeIndex]++;
time_t now = time(0);
double diffSeconds = difftime(now, past[imeIndex]);
// time difference is more than 5 minutes, reset time and error num;
if (diffSeconds > COMMON_COUNT_THREE_HUNDRED) {
past[imeIndex] = now;
errorNum[imeIndex] = 1;
}
return errorNum[imeIndex];
}
/*! Get keyboard type
\param imeIndex it can be 0 or 1. 0 - default ime, 1 - security ime
\param typeIndex the index of keyboard type.
@ -1071,13 +1047,13 @@ namespace MiscServices {
*/
int PerUserSession::GetImeIndex(const sptr<IInputClient>& inputClient)
{
if (!inputClient) {
if (inputClient == nullptr) {
IMSA_HILOGW("PerUserSession::GetImeIndex inputClient is nullptr");
return -1;
}
ClientInfo *clientInfo = GetClientInfo(inputClient);
if (!clientInfo) {
if (clientInfo == nullptr) {
IMSA_HILOGW("PerUserSession::GetImeIndex clientInfo is nullptr");
return -1;
}
@ -1121,19 +1097,19 @@ namespace MiscServices {
\n null if client is not found
\note the clientInfo pointer should not be freed by caller
*/
ClientInfo *PerUserSession::GetClientInfo(const sptr<IInputClient>& inputClient)
ClientInfo *PerUserSession::GetClientInfo(const sptr<IInputClient> &inputClient)
{
if (!inputClient) {
if (inputClient == nullptr) {
IMSA_HILOGE("PerUserSession::GetClientInfo inputClient is nullptr");
return nullptr;
}
sptr<IRemoteObject> b = Platform::RemoteBrokerToObject(inputClient);
std::map<sptr<IRemoteObject>, ClientInfo*>::iterator it = mapClients.find(b);
auto it = mapClients.find(b);
if (it == mapClients.end()) {
IMSA_HILOGE("PerUserSession::GetClientInfo client not found");
return nullptr;
}
return (ClientInfo*) it->second;
return it->second;
}
bool PerUserSession::StartInputService()
@ -1180,24 +1156,32 @@ namespace MiscServices {
int displayId = data->ReadInt32();
sptr<IRemoteObject> clientObject = data->ReadRemoteObject();
if (!clientObject) {
if (clientObject == nullptr) {
IMSA_HILOGI("PerUserSession::OnPrepareInput clientObject is null");
return;
}
sptr<InputClientProxy> client = new InputClientProxy(clientObject);
sptr<IRemoteObject> channelObject = data->ReadRemoteObject();
if (!channelObject) {
if (channelObject == nullptr) {
IMSA_HILOGI("PerUserSession::OnPrepareInput channelObject is null");
return;
}
sptr<InputDataChannelProxy> channel = new InputDataChannelProxy(channelObject);
InputAttribute *attribute = data->ReadParcelable<InputAttribute>();
if (!attribute) {
if (attribute == nullptr) {
IMSA_HILOGI("PerUserSession::OnPrepareInput attribute is nullptr");
return;
}
int ret = AddClient(pid, uid, displayId, client, channel, *attribute);
sptr<RemoteObjectDeathRecipient> clientDeathRecipient = new (std::nothrow)
RemoteObjectDeathRecipient(Utils::ToUserId(uid), MSG_ID_CLIENT_DIED);
if (clientDeathRecipient == nullptr) {
IMSA_HILOGE("clientDeathRecipient is nullptr");
}
int ret = AddClient({ pid, uid, userId_, displayId, client, channel, clientDeathRecipient, *attribute });
delete attribute;
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("PerUserSession::OnPrepareInput Aborted! %{public}s", ErrorCode::ToString(ret));
@ -1237,15 +1221,11 @@ namespace MiscServices {
sptr<IRemoteObject> clientObject = data->ReadRemoteObject();
sptr<InputClientProxy> client = new InputClientProxy(clientObject);
sptr<IInputClient> interface = client;
int remainClientNum = 0;
if (imsCore[0]) {
if (imsCore[0] != nullptr) {
imsCore[0]->SetClientState(false);
}
HideKeyboard(client);
int ret = RemoveClient(client, remainClientNum);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("PerUserSession::OnReleaseInput Aborted! Failed to RemoveClient [%{public}d]\n", userId_);
}
RemoveClient(clientObject.GetRefPtr());
IMSA_HILOGI("PerUserSession::OnReleaseInput End...[%{public}d]\n", userId_);
}
@ -1270,18 +1250,33 @@ namespace MiscServices {
void PerUserSession::SetCoreAndAgent(Message *msg)
{
IMSA_HILOGI("PerUserSession::SetCoreAndAgent Start...[%{public}d]\n", userId_);
MessageParcel *data = msg->msgContent_;
auto data = msg->msgContent_;
sptr<IRemoteObject> coreObject = data->ReadRemoteObject();
sptr<InputMethodCoreProxy> core = new InputMethodCoreProxy(coreObject);
if (imsCore[0]) {
auto coreObject = data->ReadRemoteObject();
if (coreObject == nullptr) {
IMSA_HILOGE("coreObject is nullptr");
return;
}
auto core = new (std::nothrow) InputMethodCoreProxy(coreObject);
if (core == nullptr) {
IMSA_HILOGE("core is nullptr");
return;
}
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);
bool ret = coreObject->AddDeathRecipient(imsDeathRecipient);
IMSA_HILOGI("Add death recipient %{public}s", ret ? "success" : "failed");
auto agentObject = data->ReadRemoteObject();
auto proxy = new (std::nothrow) InputMethodAgentProxy(agentObject);
if (proxy == nullptr) {
IMSA_HILOGE("proxy is nullptr");
return;
}
imsAgent = proxy;
InitInputControlChannel();
@ -1292,15 +1287,14 @@ namespace MiscServices {
void PerUserSession::SendAgentToAllClients()
{
IMSA_HILOGI("PerUserSession::SendAgentToAllClients");
if (!imsAgent) {
if (imsAgent == nullptr) {
IMSA_HILOGI("PerUserSession::SendAgentToAllClients imsAgent is nullptr");
return;
}
for (std::map<sptr<IRemoteObject>, ClientInfo*>::iterator it = mapClients.begin();
it != mapClients.end(); ++it) {
ClientInfo *clientInfo = (ClientInfo*) it->second;
if (clientInfo) {
for (auto it = mapClients.begin(); it != mapClients.end(); ++it) {
auto clientInfo = it->second;
if (clientInfo != nullptr) {
clientInfo->client->onInputReady(imsAgent);
}
}
@ -1334,9 +1328,57 @@ namespace MiscServices {
void PerUserSession::StopInputService(std::string imeId)
{
IMSA_HILOGI("PerUserSession::StopInputService");
if (imsCore[0]) {
imsCore[0]->StopInputService(imeId);
if (imsCore[0] == nullptr) {
IMSA_HILOGE("imsCore[0] is nullptr");
return;
}
IMSA_HILOGI("Remove death recipient");
imsCore[0]->AsObject()->RemoveDeathRecipient(imsDeathRecipient);
imsCore[0]->StopInputService(imeId);
}
bool PerUserSession::IsRestartIme(uint32_t index)
{
IMSA_HILOGI("PerUserSession::IsRestartIme");
std::lock_guard<std::mutex> lock(resetLock);
auto now = time(nullptr);
if (difftime(now, manager[index].last) > IME_RESET_TIME_OUT) {
manager[index] = { 0, now };
}
++manager[index].num;
return manager[index].num <= MAX_RESTART_NUM;
}
void PerUserSession::ResetImeError(uint32_t index)
{
IMSA_HILOGI("PerUserSession::ResetImeError index = %{public}d", index);
std::lock_guard<std::mutex> lock(resetLock);
manager[index] = { 0, 0 };
}
void PerUserSession::ClearImeData(uint32_t index)
{
IMSA_HILOGI("Clear ime...index = %{public}d", index);
if (imsCore[index] != nullptr) {
imsCore[index]->AsObject()->RemoveDeathRecipient(imsDeathRecipient);
imsCore[index] = nullptr;
}
inputControlChannel[index] = nullptr;
localControlChannel[index] = nullptr;
inputMethodToken[index] = nullptr;
}
void PerUserSession::SetCurrentClient(sptr<IInputClient> client)
{
IMSA_HILOGI("set current client");
std::lock_guard<std::mutex> lock(clientLock_);
currentClient = client;
}
sptr<IInputClient> PerUserSession::GetCurrentClient()
{
std::lock_guard<std::mutex> lock(clientLock_);
return currentClient;
}
} // namespace MiscServices
} // namespace OHOS

View File

@ -15,6 +15,7 @@
import app from '@system.app'
import inputMethod from '@ohos.inputmethod'
import inputMethodEngine from '@ohos.inputmethodengine'
import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from 'deccjsunit/index'
describe("InputMethodTest", function () {
@ -33,19 +34,927 @@ describe("InputMethodTest", function () {
afterEach(function () {
console.info('afterEach called')
})
let mKeyboardDelegate = null;
let inputMethodEngineObject = inputMethodEngine.getInputMethodEngine();
let textInputClient = null;
let kbController = null;
let KeyboardDelegate = null;
/*
* @tc.name:appInfoTest001
* @tc.desc:verify app info is not null
* @tc.type: FUNC
* @tc.require: issueNumber.
* @tc.number inputmethod_test_MAX_TYPE_NUM_001
* @tc.name Test MAX_TYPE_NUM.
* @tc.desc Function test
* @tc.level 2
*/
it("appInfoTest001", 0, function () {
inputMethod.getInputMethodSetting().listInputMethod().then((properties) => {
let len = properties.length()
expect(len > 0).assertEqual(true)
})
it('inputmethod_test_MAX_TYPE_NUM_001', 0, async function (done) {
console.info("************* inputmethod_test_MAX_TYPE_NUM_001 Test start*************");
let MAX_NUM = 128;
let inputMethodSetting = inputMethod.MAX_TYPE_NUM;
console.info("inputmethod_test_001 result:" + inputMethodSetting);
expect(inputMethodSetting == MAX_NUM).assertTrue();
console.info("************* inputmethod_test_MAX_TYPE_NUM_001 Test end*************");
done();
});
/*
* @tc.number inputmethod_test_getInputMethodController_001
* @tc.name Test to get an InputMethodController instance.
* @tc.desc Function test
* @tc.level 2
*/
it('inputmethod_test_getInputMethodController_001', 0, async function (done) {
console.info("************* inputmethod_test_getInputMethodController_001 Test start*************");
let controller = inputMethod.getInputMethodController();
expect(controller != undefined).assertTrue();
console.info("************* inputmethod_test_getInputMethodController_001 Test end*************");
done();
});
/*
* @tc.number inputmethod_test_getInputMethodSetting_001
* @tc.name Test to get an InputMethodSetting instance.
* @tc.desc Function test
* @tc.level 2
*/
it('inputmethod_test_getInputMethodSetting_001', 0, async function (done) {
console.info("************* inputmethod_test_getInputMethodSetting_001 Test start*************");
let setting = inputMethod.getInputMethodSetting();
expect(setting != undefined).assertTrue();
console.info("************* inputmethod_test_getInputMethodSetting_001 Test end*************");
done();
});
})
/*
* @tc.number inputmethod_test_switchInputMethod_001
* @tc.name Test Indicates the input method which will replace the current one.
* @tc.desc Function test
* @tc.level 2
*/
it('inputmethod_test_switchInputMethod_001', 0, async function (done) {
console.info("************* inputmethod_test_switchInputMethod_001 Test start*************");
let inputMethodProperty = {
packageName:"com.example.kikakeyboard",
methodId:"ServiceExtAbility"
}
inputMethod.switchInputMethod(inputMethodProperty).then(data => {
console.info("inputmethod_test_switchInputMethod_001 data:" + data)
expect(data == true).assertTrue();
}).catch( err=> {
console.info("inputmethod_test_switchInputMethod_001 err:" + JSON.stringify(err.msg))
})
console.info("************* inputmethod_test_switchInputMethod_001 Test end*************");
done();
});
/*
* @tc.number inputmethod_test_switchInputMethod_002
* @tc.name Test Indicates the input method which will replace the current one.
* @tc.desc Function test
* @tc.level 2
*/
it('inputmethod_test_switchInputMethod_002', 0, async function (done) {
console.info("************* inputmethod_test_switchInputMethod_002 Test start*************");
let inputMethodProperty = {
packageName:"com.example.kikakeyboard",
methodId:"ServiceExtAbility"
}
inputMethod.switchInputMethod(inputMethodProperty, (err, data)=>{
if(err){
console.info("inputmethod_test_switchInputMethod_002 error:" + JSON.stringify(err.msg));
expect().assertFail();
}
console.info("inputmethod_test_switchInputMethod_002 data:" + data)
expect(data == true).assertTrue();
});
console.info("************* inputmethod_test_switchInputMethod_002 Test end*************");
done();
});
/*
* @tc.number inputmethod_test_showSoftKeyboard_001
* @tc.name Test get current input method.
* @tc.desc Function test
* @tc.level 2
*/
it('inputmethod_test_getCurrentInputMethod_001', 0, async function (done) {
console.info("************* inputmethod_test_getCurrentInputMethod_001 Test start*************");
let property = inputMethod.getCurrentInputMethod();
console.info("getCurrentInputMethod_test_001 result property:" + property.packageName);
console.info("getCurrentInputMethod_test_001 result property:" + property.methodId);
expect(property != undefined).assertTrue();
console.info("************* inputmethod_test_getCurrentInputMethod_001 Test end*************");
done();
});
/*
* @tc.number inputmethod_test_listInputMethod_001
* @tc.name Test list input methods.
* @tc.desc Function test
* @tc.level 2
*/
it('inputmethod_test_listInputMethod_001', 0, async function (done) {
console.info("************* inputmethod_test_listInputMethod_001 Test start*************");
let inputMethodSetting = inputMethod.getInputMethodSetting();
console.info("listInputMethod_001 result:" + JSON.stringify(inputMethodSetting));
inputMethodSetting.listInputMethod((err, data) => {
if (err) {
console.error("listInputMethod callback result---err: " + JSON.stringify(err.msg));
expect().assertFail();
}
console.info("listInputMethod_001 listInputMethod result" + JSON.stringify(data));
expect(err == undefined).assertTrue();
});
console.info("************* inputmethod_test_listInputMethod_001 Test end*************");
done();
});
/*
* @tc.number inputmethod_test_listInputMethod_002
* @tc.name Test list input methods.
* @tc.desc Function test
* @tc.level 2
*/
it('inputmethod_test_listInputMethod_002', 0, async function (done) {
console.info("************* inputmethod_test_listInputMethod_002 Test start*************");
let inputMethodSetting = inputMethod.getInputMethodSetting();
console.info("inputmethod_test_listInputMethod_003 result:" + JSON.stringify(inputMethodSetting));
await inputMethodSetting.listInputMethod().then((data)=>{
console.info("inputmethod_test_listInputMethod_002 listInputMethod result" + JSON.stringify(data));
expect(data.length > 0).assertTrue();
}).catch((err) => {
console.info('inputmethod_test_listInputMethod_002 listInputMethod err ' + JSON.stringify(err.msg));
expect(null).assertFail();
});
console.info("************* inputmethod_test_listInputMethod_002 Test end*************");
done();
});
/*
* @tc.number inputmethod_test_listInputMethod_003
* @tc.name Test list input methods.
* @tc.desc Function test
* @tc.level 2
*/
it('inputmethod_test_listInputMethod_003', 0, async function (done) {
console.info("************* inputmethod_test_listInputMethod_003 Test start*************");
let inputMethodSetting = inputMethod.getInputMethodSetting();
console.info("inputmethod_test_listInputMethod_003 result:" + JSON.stringify(inputMethodSetting));
await inputMethodSetting.listInputMethod(true).then((data)=>{
console.info("inputmethod_test_listInputMethod_003 listInputMethod result" + JSON.stringify(data));
expect(data.length > 0).assertTrue();
}).catch((err) => {
console.info('inputmethod_test_listInputMethod_003 listInputMethod err ' + JSON.stringify(err.msg));
expect(null).assertFail();
});
done();
console.info("************* inputmethod_test_listInputMethod_003 Test end*************");
});
/*
* @tc.number inputmethod_test_listInputMethod_004
* @tc.name Test list input methods.
* @tc.desc Function test
* @tc.level 2
*/
it('inputmethod_test_listInputMethod_004', 0, async function (done) {
console.info("************* inputmethod_test_listInputMethod_004 Test start*************");
let inputMethodSetting = inputMethod.getInputMethodSetting();
console.info("inputmethoh_test_004 result:" + JSON.stringify(inputMethodSetting));
inputMethodSetting.listInputMethod(true, (err, data) => {
if (err) {
console.error("listInputMethod callback result---err: " + JSON.stringify(err.msg));
expect().assertFail();
}
console.info("inputmethoh_test_004 listInputMethod result" + JSON.stringify(data));
expect(err == undefined).assertTrue();
});
console.info("************* inputmethod_test_listInputMethod_004 Test end*************");
done();
});
/*
* @tc.number inputmethod_test_displayOptionalInputMethod_001
* @tc.name Test displays a dialog box for selecting an input method.
* @tc.desc Function test
* @tc.level 2
*/
it('inputmethod_test_displayOptionalInputMethod_001', 0, async function (done) {
console.info("************* inputmethod_test_displayOptionalInputMethod_001 Test start*************");
let inputMethodSetting = inputMethod.getInputMethodSetting();
console.info("inputmethod_test_displayOptionalInputMethod_001 result:" + JSON.stringify(inputMethodSetting));
inputMethodSetting.displayOptionalInputMethod((err) => {
console.info("inputmethod_test_displayOptionalInputMethod_001 err:" + JSON.stringify(err.msg));
expect(err == undefined).assertTrue();
});
console.info("************* inputmethod_test_displayOptionalInputMethod_001 Test end*************");
done();
});
/*
* @tc.number inputmethod_test_displayOptionalInputMethod_002
* @tc.name Test displays a dialog box for selecting an input method.
* @tc.desc Function test
* @tc.level 2
*/
it('inputmethod_test_displayOptionalInputMethod_002', 0, async function (done) {
console.info("************* inputmethod_test_displayOptionalInputMethod_002 Test start*************");
let inputMethodSetting = inputMethod.getInputMethodSetting();
console.info("inputmethod_test_displayOptionalInputMethod_002 result:" + JSON.stringify(inputMethodSetting));
await inputMethodSetting.displayOptionalInputMethod().then(()=>{
console.info("inputmethod_test_displayOptionalInputMethod_002 displayOptionalInputMethod result");
expect(true).assertTrue();
}).catch((err) => {
console.info('inputmethod_test_displayOptionalInputMethod_002 listInputMethod err ' + JSON.stringify(err.msg));
expect(null).assertFail();
});
console.info("************* inputmethod_test_displayOptionalInputMethod_002 Test end*************");
done();
});
/*
* @tc.number inputmethod_test_stopInput_001
* @tc.name Test Indicates the input method which will hides the keyboard.
* @tc.desc Function test
* @tc.level 2
*/
it('inputmethod_test_stopInput_001', 0, function (done) {
console.info("************* inputmethod_test_stopInput_001 Test start*************");
let inputMethodCtrl = inputMethod.getInputMethodController();
console.info("inputmethod_test_stopInput_001 result:" + JSON.stringify(inputMethodCtrl));
inputMethodCtrl.stopInput((err, res) => {
if (err) {
console.info("inputmethod_test_stopInput_001 stopInput result" + JSON.stringify(err.msg));
expect().assertFail();
}
console.info("inputmethod_test_stopInput_001 callback success" );
expect(res == true).assertTrue();
});
console.info("************* inputmethod_test_stopInput_001 Test end*************");
done();
});
/*
* @tc.number inputmethod_test_stopInput_002
* @tc.name Test Indicates the input method which will hides the keyboard.
* @tc.desc Function test
* @tc.level 2
*/
it('inputmethod_test_stopInput_002', 0, async function (done) {
console.info("************* inputmethod_test_stopInput_002 Test start*************");
let inputMethodCtrl = inputMethod.getInputMethodController();
console.info("inputmethod_test_stopInput_003 result:" + JSON.stringify(inputMethodCtrl));
await inputMethodCtrl.stopInput().then((res)=>{
console.info('inputmethod_test_stopInput_003 stopInput result' + res);
expect(res == true).assertTrue();
}).catch((err) => {
console.info('inputmethod_test_stopInput_003 stopInput err ' + JSON.stringify(err.msg));
expect(null).assertFail();
});
console.info("************* inputmethod_test_stopInput_002 Test end*************");
done();
});
/*
* @tc.number inputmethod_test_showSoftKeyboard_001
* @tc.name Test Indicates the input method which will show softboard with calback.
* @tc.desc Function test
* @tc.level 2
*/
it('inputmethod_test_showSoftKeyboard_001', 0, async function (done) {
console.info("************* inputmethod_test_showSoftKeyboard_001 Test start*************");
let inputMethodCtrl = inputMethod.getInputMethodController()
inputMethodCtrl.showSoftKeyboard((err)=>{
if (err == undefined) {
console.info("showSoftKeyboard callbace success" );
} else {
console.info('showSoftKeyboard callbace failed : ' + JSON.stringify(err.msg));
expect().assertFail();
}
});
console.info("************* inputmethod_test_showSoftKeyboard_001 Test end*************");
done();
});
/*
* @tc.number inputmethod_test_showSoftKeyboard_002
* @tc.name Test Indicates the input method which will show softboard with Promise.
* @tc.desc Function test
* @tc.level 2
*/
it('inputmethod_test_showSoftKeyboard_002', 0, async function (done) {
console.info("************* inputmethod_test_showSoftKeyboard_002 Test start*************");
let inputMethodCtrl = inputMethod.getInputMethodController()
inputMethodCtrl.showSoftKeyboard().then((data) =>{
console.info("showSoftKeyboard promise success" );
}).catch((err) => {
console.info('showSoftKeyboard promise failed : ' + JSON.stringify(err.msg));
expect().assertFail();
})
console.info("************* inputmethod_test_showSoftKeyboard_002 Test end*************");
done();
});
/*
* @tc.number inputmethod_test_hideSoftKeyboard_001
* @tc.name Test Indicates the input method which will hide softboard with calback.
* @tc.desc Function test
* @tc.level 2
*/
it('inputmethod_test_hideSoftKeyboard_001', 0, async function (done) {
console.info("************* inputmethod_test_hideSoftKeyboard_001 Test start*************");
let inputMethodCtrl = inputMethod.getInputMethodController()
inputMethodCtrl.hideSoftKeyboard((data)=>{
if(data == undefined){
console.info("hideSoftKeyboard callbace success" );
}else{
console.info('hideSoftKeyboard callbace failed : ' + JSON.stringify(err.msg))
expect().assertFail();
}
});
console.info("************* inputmethod_test_hideSoftKeyboard_001 Test end*************");
done();
});
/*
* @tc.number inputmethod_test_hideSoftKeyboard_002
* @tc.name Test Indicates the input method which will hide softboard with Promise.
* @tc.desc Function test
* @tc.level 2
*/
it('inputmethod_test_hideSoftKeyboard_002', 0, async function (done) {
console.info("************* inputmethod_test_hideSoftKeyboard_002 Test start*************");
let inputMethodCtrl = inputMethod.getInputMethodController()
inputMethodCtrl.hideSoftKeyboard().then((data) =>{
console.info("hideSoftKeyboard promise success" );
}).catch((err) => {
console.info('hideSoftKeyboard promise failed : ' + JSON.stringify(err.msg));
expect().assertFail();
})
console.info("************* inputmethod_test_hideSoftKeyboard_002 Test end*************");
done();
});
it('inputMethodEngine_test_Off_000', 0 , async function (done) {
inputMethodEngineObject.off('inputStart', (kbController, textInputClient) => {
console.info("inputMethodEngine beforeEach inputStart:" + JSON.stringify(kbController));
console.info("inputMethodEngine beforeEach inputStart:" + JSON.stringify(textInputClient));
});
inputMethodEngineObject.off('keyboardShow', (err) => {
console.info("inputMethodEngine beforeEach keyboardShow:" + err);
});
inputMethodEngineObject.off('keyboardHide', (err) => {
console.info("inputMethodEngine beforeEach keyboardHide:" + err);
});
KeyboardDelegate = inputMethodEngine.createKeyboardDelegate();
KeyboardDelegate.off('keyDown', (keyEvent) => {
console.info("inputMethodEngine beforeEach keyDown:" + keyEvent.keyCode);
expect(keyEvent.keyCode).assertEqual('1');
console.info("inputMethodEngine beforeEach keyDown:" + keyEvent.keyAction);
expect(keyEvent.keyAction).assertEqual('1');
});
KeyboardDelegate.off('keyUp', (keyEvent) => {
console.info("inputMethodEngine beforeEach keyUp:" + keyEvent.keyCode);
expect(keyEvent.keyCode).assertEqual('1');
console.info("inputMethodEngine beforeEach keyDown:" + keyEvent.keyAction);
expect(keyEvent.keyAction).assertEqual('0');
});
KeyboardDelegate.off('cursorContextChange', (x, y, height) => {
console.info("inputMethodEngine beforeEach cursorContextChange x:" + x);
console.info("inputMethodEngine beforeEach cursorContextChange y:" + y);
console.info("inputMethodEngine beforeEach cursorContextChange height:" + height);
});
KeyboardDelegate.off('selectionChange', (oldBegin, oldEnd, newBegin, newEnd) => {
console.info("inputMethodEngine beforeEach selectionChange oldBegin:" + oldBegin);
console.info("inputMethodEngine beforeEach selectionChange oldEnd:" + oldEnd);
console.info("inputMethodEngine beforeEach selectionChange newBegin:" + newBegin);
console.info("inputMethodEngine beforeEach selectionChange newEnd:" + newEnd);
});
KeyboardDelegate.off('textChange', (text) => {
console.info("inputMethodEngine beforeEach textChange:" + text);
});
done();
});
it('inputMethodEngine_test_000', 0, async function (done) {
inputMethodEngineObject.on('inputStart', (controller, client) => {
console.info("inputMethodEngine beforeEach inputStart:" + JSON.stringify(controller));
console.info("inputMethodEngine beforeEach inputStart:" + JSON.stringify(client));
textInputClient = client;
kbController = controller;
});
inputMethodEngineObject.on('keyboardShow', (err) => {
console.info("inputMethodEngine beforeEach keyboardShow:" + err);
});
inputMethodEngineObject.on('keyboardHide', (err) => {
console.info("inputMethodEngine beforeEach keyboardHide:" + err);
});
mKeyboardDelegate = inputMethodEngine.createKeyboardDelegate();
mKeyboardDelegate.on('keyDown', (keyEvent) => {
console.info("inputMethodEngine beforeEach keyDown:" + keyEvent.keyCode);
expect(keyEvent.keyCode).assertEqual('1');
console.info("inputMethodEngine beforeEach keyDown:" + keyEvent.keyAction);
expect(keyEvent.keyAction).assertEqual('1');
});
mKeyboardDelegate.on('keyUp', (keyEvent) => {
console.info("inputMethodEngine beforeEach keyUp:" + keyEvent.keyCode);
expect(keyEvent.keyCode).assertEqual('1');
console.info("inputMethodEngine beforeEach keyDown:" + keyEvent.keyAction);
expect(keyEvent.keyAction).assertEqual('0');
});
mKeyboardDelegate.on('cursorContextChange', (x, y, height) => {
console.info("inputMethodEngine beforeEach cursorContextChange x:" + x);
console.info("inputMethodEngine beforeEach cursorContextChange y:" + y);
console.info("inputMethodEngine beforeEach cursorContextChange height:" + height);
});
mKeyboardDelegate.on('selectionChange', (oldBegin, oldEnd, newBegin, newEnd) => {
console.info("inputMethodEngine beforeEach selectionChange oldBegin:" + oldBegin);
console.info("inputMethodEngine beforeEach selectionChange oldEnd:" + oldEnd);
console.info("inputMethodEngine beforeEach selectionChange newBegin:" + newBegin);
console.info("inputMethodEngine beforeEach selectionChange newEnd:" + newEnd);
});
mKeyboardDelegate.on('textChange', (text) => {
console.info("inputMethodEngine beforeEach textChange:" + text);
});
done();
});
it('inputMethodEngine_test_001', 0, async function (done) {
let keyType = inputMethodEngine.ENTER_KEY_TYPE_UNSPECIFIED;
console.info("inputMethodEngine_test_001 result:" + keyType);
expect(keyType).assertEqual(0);
done();
});
it('inputMethodEngine_test_002', 0, async function (done) {
let keyType = inputMethodEngine.ENTER_KEY_TYPE_GO;
console.info("inputMethodEngine_test_002 result:" + keyType);
expect(keyType).assertEqual(2);
done();
});
it('inputMethodEngine_test_003', 0, async function (done) {
let keyType = inputMethodEngine.ENTER_KEY_TYPE_SEARCH;
console.info("inputMethodEngine_test_003 result:" + keyType);
expect(keyType).assertEqual(3);
done();
});
it('inputMethodEngine_test_004', 0, async function (done) {
let keyType = inputMethodEngine.ENTER_KEY_TYPE_SEND;
console.info("inputMethodEngine_test_004 result:" + keyType);
expect(keyType).assertEqual(4);
done();
});
it('inputMethodEngine_test_005', 0, async function (done) {
let keyType = inputMethodEngine.ENTER_KEY_TYPE_NEXT;
console.info("inputMethodEngine_test_005 result:" + keyType);
expect(keyType).assertEqual(5);
done();
});
it('inputMethodEngine_test_006', 0, async function (done) {
let keyType = inputMethodEngine.ENTER_KEY_TYPE_DONE;
console.info("inputMethodEngine_test_006 result:" + keyType);
expect(keyType).assertEqual(6);
done();
});
it('inputMethodEngine_test_007', 0, async function (done) {
let keyType = inputMethodEngine.ENTER_KEY_TYPE_PREVIOUS;
console.info("inputMethodEngine_test_007 result:" + keyType);
expect(keyType).assertEqual(7);
done();
});
it('inputMethodEngine_test_008', 0, async function (done) {
let keyType = inputMethodEngine.PATTERN_NULL;
console.info("inputMethodEngine_test_008 result:" + keyType);
expect(keyType).assertEqual(-1);
done();
});
it('inputMethodEngine_test_009', 0, async function (done) {
let keyType = inputMethodEngine.PATTERN_TEXT;
console.info("inputMethodEngine_test_009 result:" + keyType);
expect(keyType).assertEqual(0);
done();
});
it('inputMethodEngine_test_010', 0, async function (done) {
let keyType = inputMethodEngine.PATTERN_NUMBER;
console.info("inputMethodEngine_test_010 result:" + keyType);
expect(keyType).assertEqual(2);
done();
});
it('inputMethodEngine_test_011', 0, async function (done) {
let keyType = inputMethodEngine.PATTERN_PHONE;
console.info("inputMethodEngine_test_011 result:" + keyType);
expect(keyType).assertEqual(3);
done();
});
it('inputMethodEngine_test_012', 0, async function (done) {
let keyType = inputMethodEngine.PATTERN_DATETIME;
console.info("inputMethodEngine_test_012 result:" + keyType);
expect(keyType).assertEqual(4);
done();
});
it('inputMethodEngine_test_013', 0, async function (done) {
let keyType = inputMethodEngine.PATTERN_EMAIL;
console.info("inputMethodEngine_test_013 result:" + keyType);
expect(keyType).assertEqual(5);
done();
});
it('inputMethodEngine_test_014', 0, async function (done) {
let keyType = inputMethodEngine.PATTERN_URI;
console.info("inputMethodEngine_test_014 result:" + keyType);
expect(keyType).assertEqual(6);
done();
});
it('inputMethodEngine_test_015', 0, async function (done) {
let keyType = inputMethodEngine.PATTERN_PASSWORD;
console.info("inputMethodEngine_test_015 result:" + keyType);
expect(keyType).assertEqual(7);
done();
});
it('inputMethodEngine_test_016', 0, async function (done) {
let keyType = inputMethodEngine.FLAG_SELECTING;
console.info("inputMethodEngine_test_016 result:" + keyType);
expect(keyType).assertEqual(2);
done();
});
it('inputMethodEngine_test_017', 0, async function (done) {
let keyType = inputMethodEngine.FLAG_SINGLE_LINE;
console.info("inputMethodEngine_test_017 result:" + keyType);
expect(keyType).assertEqual(1);
done();
});
it('inputMethodEngine_test_018', 0, async function (done) {
let keyType = inputMethodEngine.DISPLAY_MODE_PART;
console.info("inputMethodEngine_test_018 result:" + keyType);
expect(keyType).assertEqual(0);
done();
});
it('inputMethodEngine_test_019', 0, async function (done) {
let keyType = inputMethodEngine.DISPLAY_MODE_FULL;
console.info("inputMethodEngine_test_019 result:" + keyType);
expect(keyType).assertEqual(1);
done();
});
it('inputMethodEngine_test_020', 0, async function (done) {
let keyType = inputMethodEngine.OPTION_ASCII;
console.info("inputMethodEngine_test_020 result:" + keyType);
expect(keyType).assertEqual(20);
done();
});
it('inputMethodEngine_test_021', 0, async function (done) {
let keyType = inputMethodEngine.OPTION_NONE;
console.info("inputMethodEngine_test_021 result:" + keyType);
expect(keyType).assertEqual(0);
done();
});
it('inputMethodEngine_test_022', 0, async function (done) {
let keyType = inputMethodEngine.OPTION_AUTO_CAP_CHARACTERS;
console.info("inputMethodEngine_test_022 result:" + keyType);
expect(keyType).assertEqual(2);
done();
});
it('inputMethodEngine_test_023', 0, async function (done) {
let keyType = inputMethodEngine.OPTION_AUTO_CAP_SENTENCES;
console.info("inputMethodEngine_test_023 result:" + keyType);
expect(keyType).assertEqual(8);
done();
});
it('inputMethodEngine_test_024', 0, async function (done) {
let keyType = inputMethodEngine.OPTION_AUTO_WORDS;
console.info("inputMethodEngine_test_024 result:" + keyType);
expect(keyType).assertEqual(4);
done();
});
it('inputMethodEngine_test_025', 0, async function (done) {
let keyType = inputMethodEngine.OPTION_MULTI_LINE;
console.info("inputMethodEngine_test_025 result:" + keyType);
expect(keyType).assertEqual(1);
done();
});
it('inputMethodEngine_test_026', 0, async function (done) {
let keyType = inputMethodEngine.OPTION_NO_FULLSCREEN;
console.info("inputMethodEngine_test_026 result:" + keyType);
expect(keyType).assertEqual(10);
done();
});
it('inputMethodEngine_test_027', 0, async function (done) {
if (textInputClient == null) {
expect(textInputClient == null).assertEqual(true);
} else {
textInputClient.sendKeyFunction(0, (value) => {
console.info("inputMethodEngine_test_027 textInputClient sendKeyFunction:" + value);
expect(value).assertEqual(true);
});
}
done();
});
it('inputMethodEngine_test_028', 0, async function (done) {
if (textInputClient == null) {
expect(textInputClient == null).assertEqual(true);
} else {
let promise = textInputClient.sendKeyFunction(0);
promise.then(res => {
console.info("inputMethodEngine_test_028 listInputMethod promise result-----" + JSON.stringify(res));
expect(res).assertEqual(true);
}).catch(err => {
console.info("inputMethodEngine_test_028 listInputMethod promise error----" + JSON.stringify(err));
expect().assertFail();
});
}
done();
});
it('inputMethodEngine_test_029', 0, async function (done) {
if (textInputClient == null) {
expect(textInputClient == null).assertEqual(true);
} else {
textInputClient.deleteForward(1, (value) => {
console.info("inputMethodEngine_test_029 deleteForward:" + value);
expect(value).assertEqual(true);
});
}
done();
});
it('inputMethodEngine_test_030', 0, async function (done) {
if (textInputClient == null) {
expect(textInputClient == null).assertEqual(true);
} else {
let promise = textInputClient.deleteForward(1);
promise.then(res => {
console.info("inputMethodEngine_test_030 deleteForward promise result-----" + JSON.stringify(res));
expect(res).assertEqual(true);
}).catch(err => {
console.info("inputMethodEngine_test_030 deleteForward promise error----" + JSON.stringify(err));
expect().assertFail();
});
}
done();
});
it('inputMethodEngine_test_031', 0, async function (done) {
if (textInputClient == null) {
expect(textInputClient == null).assertEqual(true);
} else {
textInputClient.deleteBackward(1, (value) => {
console.info("inputMethodEngine_test_031 deleteBackward:" + value);
expect(value).assertEqual(true);
});
}
done();
});
it('inputMethodEngine_test_032', 0, async function (done) {
if (textInputClient == null) {
expect(textInputClient == null).assertEqual(true);
} else {
let promise = textInputClient.deleteBackward(1);
promise.then(res => {
console.info("inputMethodEngine_test_032 deleteBackward promise result-----" + JSON.stringify(res));
expect(res).assertEqual(true);
}).catch(err => {
console.info("inputMethodEngine_test_032 deleteBackward promise error----" + JSON.stringify(err));
expect().assertFail();
});
}
done();
});
it('inputMethodEngine_test_033', 0, async function (done) {
if (textInputClient == null) {
expect(textInputClient == null).assertEqual(true);
} else {
textInputClient.InsertText('test', (value) => {
console.info("inputMethodEngine_test_033 InsertText:" + value);
expect(value).assertEqual(true);
});
}
done();
});
it('inputMethodEngine_test_034', 0, async function (done) {
if (textInputClient == null) {
expect(textInputClient == null).assertEqual(true);
} else {
let promise = textInputClient.InsertText('test');
promise.then(res => {
console.info("inputMethodEngine_test_034 InsertText promise result-----" + JSON.stringify(res));
expect(res).assertEqual(true);
}).catch(err => {
console.info("inputMethodEngine_test_034 InsertText promise error----" + JSON.stringify(err));
expect().assertFail();
});
}
done();
});
it('inputMethodEngine_test_035', 0, async function (done) {
if (textInputClient == null) {
expect(textInputClient == null).assertEqual(true);
} else {
textInputClient.getForward(1, (value) => {
console.info("inputMethodEngine_test_035 getForward:" + value);
expect(value).assertEqual(true);
});
}
done();
});
it('inputMethodEngine_test_036', 0, async function (done) {
if (textInputClient == null) {
expect(textInputClient == null).assertEqual(true);
} else {
let promise = textInputClient.getForward(1);
promise.then(res => {
console.info("inputMethodEngine_test_036 getForward promise result-----" + JSON.stringify(res));
expect(res).assertEqual(true);
}).catch(err => {
console.info("inputMethodEngine_test_036 getForward promise error----" + JSON.stringify(err));
expect().assertFail();
});
}
done();
});
it('inputMethodEngine_test_037', 0, async function (done) {
if (textInputClient == null) {
expect(textInputClient == null).assertEqual(true);
} else {
textInputClient.getEditorAttribute(1, (editorAttribute) => {
console.info("inputMethodEngine_test_037 getEditorAttribute:" + value);
expect(editorAttribute.inputPattern).assertEqual(1);
expect(editorAttribute.enterKeyType).assertEqual(1);
});
}
done();
});
it('inputMethodEngine_test_038', 0, async function (done) {
if (textInputClient == null) {
expect(textInputClient == null).assertEqual(true);
} else {
let promise = textInputClient.getEditorAttribute();
promise.then(res => {
console.info("inputMethodEngine_test_038 getEditorAttribute promise result-----" + JSON.stringify(res));
expect(res.inputPattern).assertEqual(1);
expect(res.enterKeyType).assertEqual(1);
}).catch(err => {
console.info("inputMethodEngine_test_038 getEditorAttribute promise error----" + JSON.stringify(err));
expect().assertFail();
});
}
done();
});
it('inputMethodEngine_test_039', 0, async function (done) {
if (kbController == null) {
expect(kbController == null).assertEqual(true);
} else {
kbController.hideKeyboard((err) => {
if (err == undefined) {
console.info("inputMethodEngine_test_039 hideKeyboard success.");
} else {
console.info('inputMethodEngine_test_039 hideKeyboard callbace failed : ' + JSON.stringify(err.msg));
expect().assertFail();
}
});
}
done();
});
it('inputMethodEngine_test_040', 0, async function (done) {
if (kbController == null) {
expect(kbController == null).assertEqual(true);
} else {
let promise = kbController.hideKeyboard();
promise.then(res => {
console.info("inputMethodEngine_test_040 hideKeyboard promise success.");
}).catch(err => {
console.info("inputMethodEngine_test_040 hideKeyboard promise error----" + JSON.stringify(err));
expect().assertFail();
});
}
done();
});
it('inputMethodEngine_test_041', 0, async function (done) {
if (textInputClient == null) {
expect(textInputClient == null).assertEqual(true);
} else {
textInputClient.getBackward(1, (value) => {
console.info("inputMethodEngine_test_041 getBackward:" + value);
expect(value).assertEqual(true);
});
}
done();
});
it('inputMethodEngine_test_042', 0, async function (done) {
if (textInputClient == null) {
expect(textInputClient == null).assertEqual(true);
} else {
let promise = textInputClient.getBackward(1);
promise.then(res => {
console.info("inputMethodEngine_test_042 getBackward promise result-----" + JSON.stringify(res));
expect(res).assertEqual(true);
}).catch(err => {
console.info("inputMethodEngine_test_042 getBackward promise error----" + JSON.stringify(err));
expect().assertFail();
});
}
done();
});
it('inputMethodEngine_test_043', 0, async function (done) {
let keyType = inputMethodEngine.WINDOW_TYPE_INPUT_METHOD_FLOAT;
console.error("inputMethodEngine_test_043 result:" + keyType);
expect(keyType == 2105).assertTrue();
done();
});
it('inputMethodEngine_test_044', 0, async function (done) {
if (textInputClient == null) {
expect(textInputClient == null).assertEqual(true);
} else {
textInputClient.moveCursor(inputMethodEngine.CURSOR_UP, (value) => {
console.info("inputMethodEngine_test_044 moveCursor:" + value);
expect(value == null).assertEqual(true);
});
}
done();
});
it('inputMethodEngine_test_045', 0, async function (done) {
if (textInputClient == null) {
expect(textInputClient == null).assertEqual(true);
} else {
textInputClient.moveCursor(inputMethodEngine.CURSOR_DOWN, (value) => {
console.info("inputMethodEngine_test_045 moveCursor:" + value);
expect(value == null).assertEqual(true);
});
}
done();
});
it('inputMethodEngine_test_046', 0, async function (done) {
if (textInputClient == null) {
expect(textInputClient == null).assertEqual(true);
} else {
textInputClient.moveCursor(inputMethodEngine.CURSOR_LEFT).then(res => {
console.info("inputMethodEngine_test_046 moveCursor promise result-----" + JSON.stringify(res));
expect(res == null).assertEqual(true);
}).catch(err => {
console.info("inputMethodEngine_test_046 moveCursor promise error----" + JSON.stringify(err));
expect().assertFail();
});
}
done();
});
it('inputMethodEngine_test_047', 0, async function (done) {
if (textInputClient == null) {
expect(textInputClient == null).assertEqual(true);
} else {
textInputClient.moveCursor(inputMethodEngine.CURSOR_RIGHT).then(res => {
console.info("inputMethodEngine_test_047 moveCursor promise result-----" + JSON.stringify(res));
expect(res == null).assertEqual(true);
}).catch(err => {
console.info("inputMethodEngine_test_047 moveCursor promise error----" + JSON.stringify(err));
expect().assertFail();
});
}
done();
});
})

View File

@ -205,6 +205,30 @@ namespace MiscServices {
setting.SetCurrentKeyboardType(curType);
EXPECT_EQ(setting.GetCurrentKeyboardType(), curType);
}
/**
* @tc.name: testIMCdispatchKeyEvent
* @tc.desc: IMC testdispatchKeyEvent.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(InputMethodControllerTest, testIMCdispatchKeyEvent, TestSize.Level0)
{
IMSA_HILOGI("IMC dispatchKeyEvent Test START");
sptr<InputMethodController> imc = InputMethodController::GetInstance();
EXPECT_TRUE(imc != nullptr);
std::shared_ptr<MMI::KeyEvent> keyEvent = MMI::KeyEvent::Create();
EXPECT_TRUE(keyEvent != nullptr);
keyEvent->SetKeyAction(2);
keyEvent->SetKeyCode(2013);
sptr<OnTextChangedListener> textListener = new TextListener();
imc->Attach(textListener);
imc->dispatchKeyEvent(keyEvent);
}
/**
* @tc.name: testInputMethodWholeProcess
@ -250,6 +274,48 @@ namespace MiscServices {
IMSA_HILOGI("IMC TEST OVER");
}
/**
* @tc.name: testShowSoftKeyboard
* @tc.desc: IMC ShowSoftKeyboard
* @tc.type: FUNC
*/
HWTEST_F(InputMethodControllerTest, testShowSoftKeyboard, TestSize.Level0)
{
IMSA_HILOGI("IMC ShowSoftKeyboard Test START");
sptr<InputMethodController> imc = InputMethodController::GetInstance();
EXPECT_NE(imc, nullptr);
int32_t ret = imc->ShowSoftKeyboard();
EXPECT_NE(ret, 0);
}
/**
* @tc.name: testHideSoftKeyboard
* @tc.desc: IMC HideSoftKeyboard
* @tc.type: FUNC
*/
HWTEST_F(InputMethodControllerTest, testHideSoftKeyboard, TestSize.Level0)
{
IMSA_HILOGI("IMC HideSoftKeyboard Test START");
sptr<InputMethodController> imc = InputMethodController::GetInstance();
EXPECT_NE(imc, nullptr);
int32_t ret = imc->HideSoftKeyboard();
EXPECT_NE(ret, 0);
}
/**
* @tc.name: testShowOptionalInputMethod
* @tc.desc: IMC ShowOptionalInputMethod
* @tc.type: FUNC
*/
HWTEST_F(InputMethodControllerTest, testShowOptionalInputMethod, TestSize.Level2)
{
IMSA_HILOGI("IMC ShowOptionalInputMethod Test START");
sptr<InputMethodController> imc = InputMethodController::GetInstance();
EXPECT_NE(imc, nullptr);
int32_t ret = imc->ShowOptionalInputMethod();
EXPECT_NE(ret, 0);
}
/**
* @tc.name: testIMCGetCurrentInputMethod
* @tc.desc: IMC GetCurrentInputMethod
@ -302,25 +368,177 @@ namespace MiscServices {
}
/**
* @tc.name: testIMSAProxyShowCurrentInput
* @tc.desc: IMSAProxy ShowCurrentInput.
* @tc.name: testIMCHideCurrentInput
* @tc.desc: IMC HideCurrentInput.
* @tc.type: FUNC
* @tc.require: issueI5NXHK
* @tc.require:
*/
HWTEST_F(InputMethodControllerTest, testIMSAProxyShowCurrentInput, TestSize.Level0)
HWTEST_F(InputMethodControllerTest, testIMCHideCurrentInput, TestSize.Level0)
{
IMSA_HILOGI("IMSAProxy ShowCurrentInput Test START");
sptr<ISystemAbilityManager> systemAbilityManager =
SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
auto systemAbility = systemAbilityManager->GetSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID, "");
sptr<InputMethodSystemAbilityProxy> imsaProxy = new InputMethodSystemAbilityProxy(systemAbility);
MessageParcel data;
data.WriteInterfaceToken(imsaProxy->GetDescriptor());
int32_t ret = imsaProxy->ShowCurrentInput(data);
IMSA_HILOGI("IMC HideCurrentInput Test START");
sptr<InputMethodController> imc = InputMethodController::GetInstance();
EXPECT_TRUE(imc != nullptr);
int32_t ret = imc->HideCurrentInput();
EXPECT_TRUE(ret == 0);
}
/**
* @tc.name: testIMCGetTextBeforeCursor
* @tc.desc: IMC testGetTextBeforeCursor.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(InputMethodControllerTest, testIMCGetTextBeforeCursor, TestSize.Level2)
{
IMSA_HILOGI("IMC GetTextBeforeCursor Test START");
sptr<InputMethodController> imc = InputMethodController::GetInstance();
EXPECT_TRUE(imc != nullptr);
constexpr int32_t TEXT_LENGTH = 1;
std::u16string ret = imc->GetTextBeforeCursor(TEXT_LENGTH);
EXPECT_TRUE(ret.size() == 0);
}
/**
* @tc.name: testIMCGetTextAfterCursor
* @tc.desc: IMC testGetTextAfterCursor.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(InputMethodControllerTest, testIMCGetTextAfterCursor, TestSize.Level2)
{
IMSA_HILOGI("IMC GetTextAfterCursor Test START");
sptr<InputMethodController> imc = InputMethodController::GetInstance();
EXPECT_TRUE(imc != nullptr);
constexpr int32_t TEXT_LENGTH = 1;
std::u16string ret = imc->GetTextAfterCursor(TEXT_LENGTH);
EXPECT_TRUE(ret.size() == 0);
}
/**
* @tc.name: testIMCDisplayOptionalInputMethod
* @tc.desc: IMC testDisplayOptionalInputMethod.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(InputMethodControllerTest, testIMCDisplayOptionalInputMethod, TestSize.Level2)
{
IMSA_HILOGI("IMC DisplayOptionalInputMethod Test START");
sptr<InputMethodController> imc = InputMethodController::GetInstance();
EXPECT_TRUE(imc != nullptr);
int32_t ret = imc->DisplayOptionalInputMethod();
EXPECT_TRUE(ret == 0);
}
/**
* @tc.name: testIMCGetEnterKeyType
* @tc.desc: IMC testGetEnterKeyType.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(InputMethodControllerTest, testIMCGetEnterKeyType, TestSize.Level0)
{
IMSA_HILOGI("IMC GetEnterKeyType Test START");
sptr<InputMethodController> imc = InputMethodController::GetInstance();
EXPECT_TRUE(imc != nullptr);
int32_t ret = imc->GetEnterKeyType();
EXPECT_TRUE(ret >= static_cast<int32_t>(EnterKeyType::UNSPECIFIED)
&& ret <= static_cast<int32_t>(EnterKeyType::PREVIOUS));
}
/**
* @tc.name: testIMCGetInputPattern
* @tc.desc: IMC testGetInputPattern.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(InputMethodControllerTest, testIMCGetInputPattern, TestSize.Level0)
{
IMSA_HILOGI("IMC GetInputPattern Test START");
sptr<InputMethodController> imc = InputMethodController::GetInstance();
EXPECT_TRUE(imc != nullptr);
int32_t ret = imc->GetInputPattern();
EXPECT_TRUE(ret >= static_cast<int32_t>(TextInputType::NONE)
&& ret <= static_cast<int32_t>(TextInputType::VISIBLE_PASSWORD));
}
/**
* @tc.name: testIMCSwitchInputMethod
* @tc.desc: IMC testSwitchInputMethod.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(InputMethodControllerTest, testIMCSwitchInputMethod, TestSize.Level0)
{
IMSA_HILOGI("IMC SwitchInputMethod Test START");
sptr<InputMethodController> imc = InputMethodController::GetInstance();
EXPECT_TRUE(imc != nullptr);
int32_t ret = imc->SwitchInputMethod({ "com.example.kikakeyboard", "ServiceExtAbility" });
EXPECT_TRUE(ret == 0);
}
/**
* @tc.name: testIMCOnCursorUpdate
* @tc.desc: IMC testOnCursorUpdate
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(InputMethodControllerTest, testIMCOnCursorUpdate, TestSize.Level0)
{
IMSA_HILOGI("IMC OnCursorUpdate Test START");
sptr<InputMethodController> imc = InputMethodController::GetInstance();
EXPECT_TRUE(imc != nullptr);
imc->OnCursorUpdate({});
}
/**
* @tc.name: testIMCOnSelectionChange
* @tc.desc: IMC testOnSelectionChange
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(InputMethodControllerTest, testIMCOnSelectionChange, TestSize.Level0)
{
IMSA_HILOGI("IMC OnSelectionChange Test START");
sptr<InputMethodController> imc = InputMethodController::GetInstance();
EXPECT_TRUE(imc != nullptr);
imc->OnSelectionChange(Str8ToStr16("text"), 1, 1);
}
/**
* @tc.name: testIMCOnConfigurationChange
* @tc.desc: IMC testOnConfigurationChange.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(InputMethodControllerTest, testIMCOnConfigurationChange, TestSize.Level0)
{
IMSA_HILOGI("IMC OnConfigurationChange Test START");
sptr<InputMethodController> imc = InputMethodController::GetInstance();
EXPECT_TRUE(imc != nullptr);
Configuration info;
info.SetEnterKeyType(EnterKeyType::NONE);
info.SetTextInputType(TextInputType::TEXT);
imc->OnConfigurationChange(info);
}
/**
* @tc.name: testIMCSetCallingWindow
* @tc.desc: IMC testSetCallingWindow.
* @tc.type: FUNC
* @tc.require:
*/
HWTEST_F(InputMethodControllerTest, testIMCSetCallingWindow, TestSize.Level0)
{
IMSA_HILOGI("IMC SetCallingWindow Test START");
constexpr uint32_t WINDOW_ID = 0;
sptr<InputMethodController> imc = InputMethodController::GetInstance();
EXPECT_TRUE(imc != nullptr);
imc->SetCallingWindow(WINDOW_ID);
}
} // namespace MiscServices
} // namespace OHOS

View File

@ -71,7 +71,7 @@ HWTEST_F(InputMethodSwitchTest, intputMethodSwitch_sub_001, TestSize.Level0)
target->mImeId = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.from_bytes(imeId);
int32_t ret = InputMethodController::GetInstance()->SwitchInputMethod(target);
delete target;
EXPECT_TRUE(0 == ret);
EXPECT_TRUE(ret == 0);
}
} // namespace MiscServices
} // namespace OHOS