add inputmethod

Signed-off-by: zhouyongfei <zhouyongfei@huawei.com>
This commit is contained in:
zhouyongfei 2021-09-14 20:33:47 +08:00
parent c92108aa00
commit 3e8b13bd33
90 changed files with 10984 additions and 0 deletions

30
BUILD.gn Normal file
View File

@ -0,0 +1,30 @@
# Copyright (C) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
################################################################################
group("inputmethod_native_packages") {
if (is_standard_system) {
deps = [
"etc/init:inputmethodservice.rc",
"services:inputmethod_service",
"frameworks/inputmethod_controller:inputmethod_client",
"frameworks/inputmethod_ability:inputmethod_ability",
"interfaces/kits/js/declaration:inputmethod",
"interfaces/kits/js/napi:inputmethodability",
"profile:miscservices_inputmethod_sa_profiles",
]
}
}

177
LICENSE Normal file
View File

@ -0,0 +1,177 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

27
etc/init/BUILD.gn Normal file
View File

@ -0,0 +1,27 @@
# Copyright (C) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
################################################################################
ohos_prebuilt_etc("inputmethodservice.rc") {
if (use_musl) {
source = "inputmethodservice.cfg"
} else {
source = "inputmethodservice.rc"
}
relative_install_dir = "init"
part_name = "inputmethod_native"
subsystem_name = "miscservices"
}

View File

@ -0,0 +1,17 @@
{
"jobs" : [{
"name" : "boot",
"cmds" : [
"start inputmethod_service"
]
}
],
"services" : [{
"name" : "inputmethod_service",
"path" : ["/system/bin/sa_main", "/system/profile/inputmethod_service.xml"],
"uid" : "system",
"gid" : ["system", "shell"],
"caps" : ["SYS_TIME"]
}
]
}

View File

@ -0,0 +1,21 @@
# Copyright (C) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
on boot
start inputmethod_service
service inputmethod_service /system/bin/sa_main /system/profile/inputmethod_service.xml
class z_core
user system
group system shell
capabilities SYS_TIME
seclabel u:r:time_service:s0

View File

@ -0,0 +1,74 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//base/miscservices/inputmethod/inputmethod.gni")
import("//build/ohos.gni")
config("inputmethod_ability_native_config") {
visibility = [ ":*" ]
include_dirs = [
"include",
"${inputmethod_path}/frameworks/inputmethod_controller/include",
]
}
config("inputmethod_ability_native_public_config") {
visibility = []
include_dirs = [ "include" ]
}
ohos_shared_library("inputmethod_ability") {
sources = [
"src/input_method_ability.cpp",
"src/input_method_agent_proxy.cpp",
"src/input_method_agent_stub.cpp",
"src/input_method_core_stub.cpp",
"src/input_method_core_proxy.cpp",
"src/event_target.cpp",
"../inputmethod_controller/src/input_method_system_ability_proxy.cpp",
]
configs = [ ":inputmethod_ability_native_config" ]
deps = [
"//utils/native/base:utils",
"//base/global/resmgr_standard/frameworks/resmgr:global_resmgr",
"//foundation/aafwk/standard/frameworks/kits/ability/native:abilitykit_native",
"//foundation/aafwk/standard/interfaces/innerkits/ability_manager:ability_manager",
"//foundation/aafwk/standard/interfaces/innerkits/want:want",
"//foundation/aafwk/standard/interfaces/innerkits/base:base",
"//foundation/aafwk/standard/interfaces/innerkits/intent:intent",
"//foundation/ace/napi/:ace_napi",
"//foundation/multimodalinput/input/interfaces/native/innerkits/event:mmi_event",
"//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_base:appexecfwk_base",
"//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_core:appexecfwk_core",
"//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler:libeventhandler",
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
"//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core",
"//foundation/communication/ipc/interfaces/innerkits/ipc_single:ipc_single",
"//foundation/multimodalinput/input/interfaces/native/innerkits/event:mmi_event",
"//foundation/distributedschedule/dmsfwk/interfaces/innerkits/uri:zuri",
"//base/miscservices/inputmethod/services:inputmethod_service",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
]
public_configs = [
":inputmethod_ability_native_config",
"//utils/native/base:utils_config",
]
subsystem_name = "miscservices"
part_name = "inputmethod_native"
}

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FOUNDATION_ACE_NAPI_TEST_NATIVE_MODULE_NETSERVER_EVENT_TARGET_H
#define FOUNDATION_ACE_NAPI_TEST_NATIVE_MODULE_NETSERVER_EVENT_TARGET_H
#include "napi/native_api.h"
#include "global.h"
#include "input_method_ability.h"
namespace OHOS {
namespace MiscServices {
struct EventListener;
class Event {
public:
virtual napi_value ToJsObject() = 0;
};
class EventTarget : public RefBase {
public:
EventTarget(napi_env env, napi_value thisVar);
virtual ~EventTarget();
virtual void On(const char* type, napi_value handler);
virtual void Once(const char* type, napi_value handler);
virtual void Off(const char* type, napi_value handler);
virtual void Off(const char* type);
virtual void Emit(const char* type, Event* event);
protected:
napi_env env_;
napi_ref thisVarRef_;
EventListener* first_;
EventListener* last_;
};
}
}
#endif /* FOUNDATION_ACE_NAPI_TEST_NATIVE_MODULE_NETSERVER_EVENT_TARGET_H */

View File

@ -0,0 +1,40 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_IINPUTMETHODAGENT_H
#define FM_IMMS_PROJECT_IINPUTMETHODAGENT_H
#include "iremote_broker.h"
#include "global.h"
/**
* brief Definition of interface IInputMethodAgent
* It defines the remote calls from input client to input method service
*/
namespace OHOS {
namespace MiscServices {
class IInputMethodAgent : public IRemoteBroker {
public:
enum {
DISPATCH_KEY = FIRST_CALL_TRANSACTION,
};
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.inputmethod.IInputMethodAgent");
virtual int32_t DispatchKey(int32_t key, int32_t status) = 0;
};
}
}
#endif // FM_IMMS_PROJECT_IINPUTMETHODAGENT_H

View File

@ -0,0 +1,60 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_IINPUTMETHODCORE_H
#define FM_IMMS_PROJECT_IINPUTMETHODCORE_H
#include "iremote_broker.h"
#include "i_input_data_channel.h"
#include "i_input_control_channel.h"
#include "ipc_types.h"
#include "input_attribute.h"
#include "keyboard_type.h"
#include "input_channel.h"
#include "global.h"
/**
* brief Definition of interface IInputMethodCore
* It defines the remote calls from input method management service to input method service
*/
namespace OHOS {
namespace MiscServices {
class IInputMethodCore : public IRemoteBroker {
public:
enum {
INITIALIZE_INPUT = FIRST_CALL_TRANSACTION,
START_INPUT,
STOP_INPUT,
SHOW_KEYBOARD,
HIDE_KEYBOARD,
SET_KEYBOARD_TYPE,
GET_KEYBOARD_WINDOW_HEIGHT,
};
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.inputmethod.IInputMethodCore");
virtual int32_t initializeInput(sptr<IRemoteObject>& startInputToken, int32_t displayId,
sptr<IInputControlChannel>& inputControlChannel) = 0;
virtual bool startInput(const sptr<IInputDataChannel>& startInputToken,
const InputAttribute& editorAttribute,
bool supportPhysicalKbd) = 0;
virtual int32_t stopInput() = 0;
virtual bool showKeyboard(int32_t flags) = 0;
virtual bool hideKeyboard(int32_t flags) = 0;
virtual int32_t setKeyboardType(const KeyboardType& type) = 0;
virtual int32_t getKeyboardWindowHeight(int32_t* retHeight) = 0;
};
}
}
#endif // FM_IMMS_PROJECT_IINPUTMETHODCORE_H

View File

@ -0,0 +1,92 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_INPUTMETHODABILITY_H
#define FM_IMMS_PROJECT_INPUTMETHODABILITY_H
#include <thread>
#include "iremote_object.h"
#include "i_input_control_channel.h"
#include "i_input_method_core.h"
#include "i_input_data_channel.h"
#include "i_input_method_agent.h"
#include "input_method_core_stub.h"
#include "input_control_channel_proxy.h"
#include "input_attribute.h"
#include "message_handler.h"
#include "input_channel.h"
#include "message.h"
#include "utils.h"
#include "input_method_system_ability_proxy.h"
namespace OHOS {
namespace MiscServices {
class EventTarget;
class InputMethodAbility : public RefBase {
public:
InputMethodAbility();
~InputMethodAbility();
static sptr<InputMethodAbility> GetInstance();
sptr<IInputMethodCore> OnConnect();
bool InsertText(const std::string text);
void setEventTarget(sptr<EventTarget> &eventTarget);
void DeleteBackward(int32_t length);
void HideKeyboardSelf();
private:
std::thread workThreadHandler;
MessageHandler* msgHandler;
bool mSupportPhysicalKbd = false;
InputAttribute* editorAttribute;
int32_t displyId = 0;
sptr<IRemoteObject> startInputToken;
InputChannel* writeInputChannel;
// communicating with IMSA
sptr<IInputControlChannel> inputControlChannel;
// communicating with IMC
sptr<IInputDataChannel> inputDataChannel;
sptr<IInputMethodAgent> inputMethodAgent;
sptr<EventTarget> eventTarget_;
static std::mutex instanceLock_;
static sptr<InputMethodAbility> instance_;
sptr<InputMethodSystemAbilityProxy> mImms;
sptr<InputMethodSystemAbilityProxy> GetImsaProxy();
void Initialize();
void WorkThread();
void CreateInputMethodAgent(bool supportPhysicalKbd);
// the message from IMSA
void OnInitialInput(Message* msg);
void OnStartInput(Message* msg);
void OnStopInput(Message* msg);
void OnSetKeyboardType(Message* msg);
void OnShowKeyboard(Message* msg);
void OnHideKeyboard(Message* msg);
// the message from IMC
bool DispatchKey(Message* msg);
// control inputwindow
void InitialInputWindow();
void ShowInputWindow();
void DissmissInputWindow();
};
}
}
#endif // FM_IMMS_PROJECT_INPUTMETHODABILITY_H

View File

@ -0,0 +1,36 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMC_PROJECT_INPUTMETHODAGENTPROXY_H
#define FM_IMC_PROJECT_INPUTMETHODAGENTPROXY_H
#include "iremote_proxy.h"
#include "i_input_method_agent.h"
namespace OHOS {
namespace MiscServices {
class InputMethodAgentProxy : public IRemoteProxy<IInputMethodAgent> {
public:
explicit InputMethodAgentProxy(const sptr<IRemoteObject> &object);
~InputMethodAgentProxy() = default;
DISALLOW_COPY_AND_MOVE(InputMethodAgentProxy);
int32_t DispatchKey(int32_t key, int32_t status) override;
private:
static inline BrokerDelegator<InputMethodAgentProxy> delegator_;
};
}
}
#endif // FM_IMC_PROJECT_INPUTMETHODAGENTPROXY_H

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMC_PROJECT_INPUTMETHODAGENTSTUB_H
#define FM_IMC_PROJECT_INPUTMETHODAGENTSTUB_H
#include "iremote_stub.h"
#include "message_parcel.h"
#include "message_option.h"
#include "i_input_method_agent.h"
#include "message_handler.h"
namespace OHOS {
namespace MiscServices {
class InputMethodAgentStub : public IRemoteStub<IInputMethodAgent> {
public:
explicit InputMethodAgentStub();
virtual ~InputMethodAgentStub();
virtual int32_t OnRemoteRequest(uint32_t code,
MessageParcel &data,
MessageParcel &reply,
MessageOption &option) override;
virtual int32_t DispatchKey(int32_t key, int32_t status) override;
void SetMessageHandler(MessageHandler* msgHandler);
private:
MessageHandler* msgHandler_;
};
}
}
#endif // FM_IMC_PROJECT_INPUTMETHODAGENTSTUB_H

View File

@ -0,0 +1,53 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMC_PROJECT_INPUTMETHODCOREPROXY_H
#define FM_IMC_PROJECT_INPUTMETHODCOREPROXY_H
#include "iremote_proxy.h"
#include "iremote_object.h"
#include "message_parcel.h"
#include "message_option.h"
#include "i_input_method_core.h"
#include "i_input_control_channel.h"
#include "i_input_data_channel.h"
#include "input_attribute.h"
namespace OHOS {
namespace MiscServices {
class InputMethodCoreProxy : public IRemoteProxy<IInputMethodCore> {
public:
explicit InputMethodCoreProxy(const sptr<IRemoteObject>& object);
~InputMethodCoreProxy();
DISALLOW_COPY_AND_MOVE(InputMethodCoreProxy);
virtual int32_t initializeInput(sptr<IRemoteObject>& startInputToken, int32_t displayId,
sptr<IInputControlChannel>& inputControlChannel) override;
virtual bool startInput(const sptr<IInputDataChannel>& inputDataChannel,
const InputAttribute& editorAttribute,
bool supportPhysicalKbd) override;
virtual int32_t stopInput() override;
virtual bool showKeyboard(int32_t flags) override;
virtual bool hideKeyboard(int32_t flags) override;
virtual int32_t setKeyboardType(const KeyboardType& type) override;
virtual int32_t getKeyboardWindowHeight(int32_t * retHeight) override;
private:
static inline BrokerDelegator<InputMethodCoreProxy> delegator_;
};
}
}
#endif // FM_IMC_PROJECT_INPUTMETHODCOREPROXY_H

View File

@ -0,0 +1,64 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_INPUTCONTROLCHANNEL_SK_H
#define FM_IMMS_PROJECT_INPUTCONTROLCHANNEL_SK_H
#include "iremote_broker.h"
#include "iremote_stub.h"
#include "i_input_method_agent.h"
#include "input_channel.h"
#include <mutex>
#include <condition_variable>
#include <stdint.h>
#include "message_parcel.h"
#include "input_attribute.h"
#include "i_input_data_channel.h"
#include "i_input_method_core.h"
#include "i_input_control_channel.h"
#include "keyboard_type.h"
#include "message_handler.h"
namespace OHOS {
namespace MiscServices {
class InputMethodCoreStub : public IRemoteStub<IInputMethodCore> {
public:
DISALLOW_COPY_AND_MOVE(InputMethodCoreStub);
explicit InputMethodCoreStub(int userId);
virtual ~InputMethodCoreStub();
virtual int OnRemoteRequest(uint32_t code,
MessageParcel &data,
MessageParcel &reply,
MessageOption &option) override;
virtual int32_t initializeInput(sptr<IRemoteObject>& startInputToken, int32_t displayId,
sptr<IInputControlChannel>& inputControlChannel) override;
virtual bool startInput(const sptr<IInputDataChannel>& inputDataChannel,
const InputAttribute& editorAttribute,
bool supportPhysicalKbd) override;
virtual int32_t stopInput() override;
virtual bool showKeyboard(int32_t flags) override;
virtual bool hideKeyboard(int32_t flags)override;
virtual int32_t setKeyboardType(const KeyboardType& type) override;
virtual int32_t getKeyboardWindowHeight(int32_t * retHeight) override;
void SetMessageHandler(MessageHandler* msgHandler);
private:
int userId_;
MessageHandler* msgHandler_;
};
}
}
#endif // FM_IMMS_PROJECT_INPUTCONTROLCHANNEL_SK_H

View File

@ -0,0 +1,182 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "event_target.h"
#include "securec.h"
#include "utils/log.h"
#include "input_method_ability.h"
#define LISTENER_TYPTE_MAX_LENGTH 64
namespace OHOS {
namespace MiscServices {
struct EventListener {
char type[LISTENER_TYPTE_MAX_LENGTH] = { 0 };
bool isOnce = false;
napi_ref handlerRef = nullptr;
EventListener* back = nullptr;
EventListener* next = nullptr;
};
EventTarget::EventTarget(napi_env env, napi_value thisVar) {
IMSA_HILOGI("EventTarget::EventTarget");
env_ = env;
first_ = last_ = nullptr;
thisVarRef_ = nullptr;
napi_create_reference(env, thisVar, 1, &thisVarRef_);
}
EventTarget::~EventTarget() {
EventListener* temp = nullptr;
for (EventListener* i = first_; i != nullptr; i = temp) {
temp = i->next;
if (i == first_) {
first_ = first_->next;
} else if (i == last_) {
last_ = last_->back;
} else {
i->next->back = i->back;
i->back->next = i->next;
}
napi_delete_reference(env_, i->handlerRef);
delete i;
}
napi_delete_reference(env_, thisVarRef_);
}
void EventTarget::On(const char* type, napi_value handler)
{
IMSA_HILOGI("EventTarget::On");
auto tmp = new EventListener();
if (strncpy_s(tmp->type, LISTENER_TYPTE_MAX_LENGTH, type, strlen(type)) == -1) {
delete tmp;
tmp = nullptr;
return;
}
if (first_ == nullptr) {
first_ = last_ = tmp;
} else {
last_->next = tmp;
last_->next->back = last_;
last_ = last_->next;
}
last_->isOnce = false;
napi_create_reference(env_, handler, 1, &last_->handlerRef);
}
void EventTarget::Once(const char* type, napi_value handler)
{
IMSA_HILOGI("EventTarget::Once");
auto tmp = new EventListener();
if (strncpy_s(tmp->type, LISTENER_TYPTE_MAX_LENGTH, type, strlen(type)) == -1) {
delete tmp;
tmp = nullptr;
return;
}
if (first_ == nullptr) {
first_ = last_ = tmp;
} else {
last_->next = tmp;
last_->next->back = last_;
last_ = last_->next;
}
last_->isOnce = true;
napi_create_reference(env_, handler, 1, &last_->handlerRef);
}
void EventTarget::Off(const char* type, napi_value handler)
{
IMSA_HILOGI("EventTarget::Off");
napi_handle_scope scope = nullptr;
napi_open_handle_scope(env_, &scope);
if (scope == nullptr) {
HILOG_ERROR("scope is nullptr");
return;
}
EventListener* temp = nullptr;
for (EventListener* eventListener = first_; eventListener != nullptr; eventListener = temp) {
temp = eventListener->next;
bool isEquals = false;
napi_value handlerTemp = nullptr;
napi_get_reference_value(env_, eventListener->handlerRef, &handlerTemp);
napi_strict_equals(env_, handlerTemp, handler, &isEquals);
if (strcmp(eventListener->type, type) == 0 && isEquals) {
if (eventListener == first_) {
first_ = first_->next;
} else if (eventListener == last_) {
last_ = last_->back;
} else {
eventListener->next->back = eventListener->back;
eventListener->back->next = eventListener->next;
}
napi_delete_reference(env_, eventListener->handlerRef);
delete eventListener;
eventListener = nullptr;
break;
}
}
napi_close_handle_scope(env_, scope);
}
void EventTarget::Off(const char* type)
{
IMSA_HILOGI("EventTarget::Off");
EventListener* temp = nullptr;
for (EventListener* eventListener = first_; eventListener != nullptr; eventListener = temp) {
temp = eventListener->next;
if (strcmp(eventListener->type, type) == 0) {
if (eventListener == first_) {
first_ = first_->next;
} else if (eventListener == last_) {
last_ = last_->back;
} else {
eventListener->next->back = eventListener->back;
eventListener->back->next = eventListener->next;
}
napi_delete_reference(env_, eventListener->handlerRef);
delete eventListener;
eventListener = nullptr;
}
}
}
void EventTarget::Emit(const char* type, Event* event)
{
IMSA_HILOGI("EventTarget::Emit");
napi_handle_scope scope = nullptr;
napi_open_handle_scope(env_, &scope);
napi_value thisVar = nullptr;
napi_get_reference_value(env_, thisVarRef_, &thisVar);
for (EventListener* eventListener = first_; eventListener != nullptr; eventListener = eventListener->next) {
if (strcmp(eventListener->type, type) == 0) {
napi_value jsEvent = event ? event->ToJsObject() : nullptr;
napi_value handler = nullptr;
napi_value result = nullptr;
napi_get_reference_value(env_, eventListener->handlerRef, &handler);
napi_call_function(env_, thisVar, handler, jsEvent ? 1 : 0, jsEvent ? &jsEvent : nullptr, &result);
if (eventListener->isOnce) {
Off(type, handler);
}
}
}
napi_close_handle_scope(env_, scope);
}
}
}

View File

@ -0,0 +1,254 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "input_method_ability.h"
#include "input_method_core_proxy.h"
#include "input_method_core_stub.h"
#include "input_method_agent_proxy.h"
#include "input_method_agent_stub.h"
#include "message_parcel.h"
#include "event_target.h"
#include "iservice_registry.h"
#include "system_ability_definition.h"
#include "input_data_channel_proxy.h"
namespace OHOS {
namespace MiscServices {
using namespace MessageID;
sptr<InputMethodAbility> InputMethodAbility::instance_;
std::mutex InputMethodAbility::instanceLock_;
InputMethodAbility::InputMethodAbility() {
Initialize();
OnConnect();
}
InputMethodAbility::~InputMethodAbility() {
if (msgHandler != nullptr) {
delete msgHandler;
}
}
sptr<InputMethodAbility> InputMethodAbility::GetInstance() {
IMSA_HILOGI("InputMethodAbility::GetInstance");
if (instance_ == nullptr) {
std::lock_guard<std::mutex> autoLock(instanceLock_);
if (instance_ == nullptr) {
IMSA_HILOGI("InputMethodAbility::GetInstance need new IMA");
instance_ = new InputMethodAbility();
}
}
return instance_;
}
sptr<InputMethodSystemAbilityProxy> InputMethodAbility::GetImsaProxy() {
IMSA_HILOGI("InputMethodAbility::GetImsaProxy");
sptr<ISystemAbilityManager> systemAbilityManager =
SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (systemAbilityManager == nullptr) {
IMSA_HILOGI("InputMethodAbility::GetImsaProxy systemAbilityManager is nullptr");
return nullptr;
}
auto systemAbility = systemAbilityManager->GetSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID, "");
if (systemAbility == nullptr) {
IMSA_HILOGI("InputMethodAbility::GetImsaProxy systemAbility is nullptr");
return nullptr;
}
sptr<InputMethodSystemAbilityProxy> iface = new InputMethodSystemAbilityProxy(systemAbility);
return iface;
}
sptr<IInputMethodCore> InputMethodAbility::OnConnect() {
IMSA_HILOGI("InputMethodAbility::OnConnect");
mImms = GetImsaProxy();
sptr<InputMethodCoreStub> stub = new InputMethodCoreStub(0);
stub->SetMessageHandler(msgHandler);
sptr<IInputMethodCore> stub2=stub;
if (mImms != nullptr) {
mImms->setInputMethodCore(stub2);
}
IMSA_HILOGI("InputMethodAbility::OnConnect() mImms is nullptr");
return nullptr;
}
void InputMethodAbility::Initialize() {
IMSA_HILOGI("InputMethodAbility::Initialize");
InitialInputWindow();
msgHandler = new MessageHandler();
workThreadHandler = std::thread([this]{WorkThread();});
}
void InputMethodAbility::setEventTarget(sptr<EventTarget> &eventTarget) {
IMSA_HILOGI("InputMethodAbility::setEventTarget");
eventTarget_ = eventTarget;
}
void InputMethodAbility::WorkThread() {
while(1){
Message* msg = msgHandler->GetMessage();
switch(msg->msgId_) {
case MSG_ID_INITIALIZE_INPUT: {
OnInitialInput(msg);
break;
}
case MSG_ID_START_INPUT: {
OnStartInput(msg);
break;
}
case MSG_ID_STOP_INPUT: {
OnStopInput(msg);
break;
}
case MSG_ID_SHOW_KEYBOARD: {
OnShowKeyboard(msg);
break;
}
case MSG_ID_HIDE_KEYBOARD: {
OnHideKeyboard(msg);
break;
}
case MSG_ID_DISPATCH_KEY : {
DispatchKey(msg);
break;
}
default:{
break;
}
}
delete msg;
}
}
void InputMethodAbility::OnInitialInput(Message* msg) {
IMSA_HILOGI("InputMethodAbility::OnInitialInput");
MessageParcel* data = msg->msgContent_;
displyId = data->ReadInt32();
sptr<IRemoteObject> channelObject = data->ReadRemoteObject();
if (channelObject == nullptr) {
IMSA_HILOGI("InputMethodAbility::OnInitialInput channelObject is nullptr");
return;
}
sptr<InputControlChannelProxy> channelProxy=new InputControlChannelProxy(channelObject);
inputControlChannel = channelProxy;
if(inputControlChannel == nullptr) {
IMSA_HILOGI("InputMethodAbility::OnInitialInput inputControlChannel is nullptr");
return;
}
InitialInputWindow();
}
void InputMethodAbility::OnStartInput(Message* msg) {
IMSA_HILOGI("InputMethodAbility::OnStartInput");
MessageParcel* data = msg->msgContent_;
sptr<InputDataChannelProxy> channalProxy = new InputDataChannelProxy(data->ReadRemoteObject());
inputDataChannel = channalProxy;
if(inputDataChannel == nullptr) {
IMSA_HILOGI("InputMethodAbility::OnStartInput inputDataChannel is nullptr");
}
editorAttribute = data->ReadParcelable<InputAttribute>();
if(editorAttribute == nullptr) {
IMSA_HILOGI("InputMethodAbility::OnStartInput editorAttribute is nullptr");
}
mSupportPhysicalKbd = data->ReadBool();
CreateInputMethodAgent(mSupportPhysicalKbd);
if (inputControlChannel != nullptr) {
IMSA_HILOGI("InputMethodAbility::OnStartInput inputControlChannel is not nullptr");
inputControlChannel->onAgentCreated(inputMethodAgent, nullptr);
}
}
void InputMethodAbility::OnShowKeyboard(Message* msg) {
IMSA_HILOGI("InputMethodAbility::OnShowKeyboard");
ShowInputWindow();
}
void InputMethodAbility::OnHideKeyboard(Message* msg) {
IMSA_HILOGI("InputMethodAbility::OnHideKeyboard");
DissmissInputWindow();
}
void InputMethodAbility::OnStopInput(Message* msg) {
IMSA_HILOGI("InputMethodAbility::OnStopInput");
if (writeInputChannel != nullptr) {
delete writeInputChannel;
}
}
bool InputMethodAbility::DispatchKey(Message* msg) {
IMSA_HILOGI("InputMethodAbility::DispatchKey");
MessageParcel* data = msg->msgContent_;
int32_t key = data->ReadInt32();
int32_t status = data->ReadInt32();
IMSA_HILOGI("InputMethodAbility::DispatchKey: key = %{public}d, status = %{public}d", key, status);
return true;
}
void InputMethodAbility::CreateInputMethodAgent(bool supportPhysicalKbd) {
IMSA_HILOGI("InputMethodAbility::CreateInputMethodAgent");
sptr<InputMethodAgentStub> inputMethodAgentStub(new InputMethodAgentStub());
inputMethodAgentStub->SetMessageHandler(msgHandler);
inputMethodAgent = sptr(new InputMethodAgentProxy(inputMethodAgentStub));
}
void InputMethodAbility::InitialInputWindow() {
IMSA_HILOGI("InputMethodAbility::InitialInputWindow");
}
void InputMethodAbility::ShowInputWindow() {
IMSA_HILOGI("InputMethodAbility::ShowInputWindow");
eventTarget_->Emit("keyboardShow",nullptr);
}
void InputMethodAbility::DissmissInputWindow() {
IMSA_HILOGI("InputMethodAbility::DissmissInputWindow");
eventTarget_->Emit("keyboardHide",nullptr);
}
bool InputMethodAbility::InsertText(const std::string text) {
IMSA_HILOGI("InputMethodAbility::InsertText");
if (inputDataChannel == nullptr){
IMSA_HILOGI("InputMethodAbility::InsertText inputDataChanel is nullptr");
return false;
}
return inputDataChannel->InsertText(Utils::to_utf16(text));
}
void InputMethodAbility::DeleteBackward(int32_t length) {
IMSA_HILOGI("InputMethodAbility::DeleteBackward");
if (inputDataChannel == nullptr){
IMSA_HILOGI("InputMethodAbility::DeleteBackward inputDataChanel is nullptr");
return;
}
inputDataChannel->DeleteBackward(length);
}
void InputMethodAbility::HideKeyboardSelf() {
IMSA_HILOGI("InputMethodAbility::HideKeyboardSelf");
inputControlChannel->hideKeyboardSelf(1);
}
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "input_method_agent_proxy.h"
namespace OHOS {
namespace MiscServices {
using namespace ErrorCode;
InputMethodAgentProxy::InputMethodAgentProxy(const sptr<IRemoteObject> &object) : IRemoteProxy<IInputMethodAgent>(object) {
}
int32_t InputMethodAgentProxy::DispatchKey(int32_t key, int32_t status) {
IMSA_HILOGI("InputMethodAgentProxy::DispatchKey key = %{public}d, status = %{public}d", key, status);
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
IMSA_HILOGI("InputMethodAgentProxy::DispatchKey descriptor is not match");
return ERROR_EX_PARCELABLE;
}
data.WriteInt32(key);
data.WriteInt32(status);
auto ret = Remote()->SendRequest(DISPATCH_KEY, data, reply, option);
return ret;
}
}
}

View File

@ -0,0 +1,74 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "input_method_agent_stub.h"
#include "global.h"
#include "message_handler.h"
#include "message.h"
namespace OHOS {
namespace MiscServices {
using namespace MessageID;
InputMethodAgentStub::InputMethodAgentStub() {
}
InputMethodAgentStub::~InputMethodAgentStub() {
}
int32_t InputMethodAgentStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) {
IMSA_HILOGI("InputMethodAgentStub::OnRemoteRequest code = %{public}d", code);
auto descriptorToken = data.ReadInterfaceToken();
if (descriptorToken != GetDescriptor()) {
return ErrorCode::ERROR_STATUS_UNKNOWN_TRANSACTION;
}
switch (code) {
case DISPATCH_KEY: {
int32_t key = data.ReadInt32();
int32_t status = data.ReadInt32();
int32_t result = DispatchKey(key, status);
if (result == ErrorCode::NO_ERROR) {
reply.WriteNoException();
} else {
reply.WriteInt32(result);
}
return result;
}
default: {
return IRemoteStub::OnRemoteRequest(code, data, reply, option);
}
}
return ErrorCode::NO_ERROR;
}
int32_t InputMethodAgentStub::DispatchKey(int32_t key, int32_t status) {
IMSA_HILOGI("InputMethodAgentStub::DispatchKey key = %{public}d, status = %{public}d", key, status);
if (msgHandler_ == nullptr) {
return ErrorCode::ERROR_NULL_POINTER;
}
MessageParcel* data = new MessageParcel();
data->WriteInt32(key);
data->WriteInt32(status);
Message* message = new Message(MessageID::MSG_ID_DISPATCH_KEY, data);
msgHandler_->SendMessage(message);
return ErrorCode::NO_ERROR;
}
void InputMethodAgentStub::SetMessageHandler(MessageHandler* msgHandler) {
msgHandler_ = msgHandler;
}
}
}

View File

@ -0,0 +1,180 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "input_method_core_proxy.h"
#include "message_parcel.h"
#include "message_option.h"
#include "input_attribute.h"
namespace OHOS {
namespace MiscServices {
InputMethodCoreProxy::InputMethodCoreProxy(const OHOS::sptr<OHOS::IRemoteObject> &impl) : IRemoteProxy<IInputMethodCore>(impl) {
}
InputMethodCoreProxy::~InputMethodCoreProxy() = default;
int32_t InputMethodCoreProxy::initializeInput(sptr<IRemoteObject> &startInputToken, int32_t displayId, sptr<IInputControlChannel> &inputControlChannel) {
IMSA_HILOGI("InputMethodCoreProxy::initializeInput");
if (startInputToken == nullptr) {
IMSA_HILOGI("InputMethodCoreProxy::initializeInput startInputToken is nullptr");
}
if (inputControlChannel == nullptr) {
IMSA_HILOGI("InputMethodCoreProxy::initializeInput inputControlChannel is nullptr");
}
IMSA_HILOGI("InputMethodCoreProxy::initializeInput displayId = %{public}d", displayId);
MessageParcel data, reply;
data.WriteInterfaceToken(GetDescriptor());
data.WriteInt32(displayId);
sptr<IRemoteObject> channelObject = inputControlChannel->AsObject();
if (channelObject == nullptr) {
IMSA_HILOGI("InputMethodCoreProxy::initializeInput channelObject is nullptr");
}
bool wor = data.WriteRemoteObject(channelObject);
if (wor) {
IMSA_HILOGI("InputMethodCoreProxy::initializeInput Success to write inputControlChannel");
} else {
IMSA_HILOGI("InputMethodCoreProxy::initializeInput Failed to write inputControlChannel");
}
MessageOption option { MessageOption::TF_SYNC };
int32_t status = Remote()->SendRequest(INITIALIZE_INPUT, data, reply, option);
if (status != ErrorCode::NO_ERROR) {
IMSA_HILOGI("InputMethodCoreProxy::initializeInput status = %{public}d", status);
return status;
}
int32_t code = reply.ReadException();
return code;
}
bool InputMethodCoreProxy::startInput(const sptr<IInputDataChannel> &inputDataChannel, const InputAttribute& editorAttribute, bool supportPhysicalKbd) {
IMSA_HILOGI("InputMethodCoreProxy::startInput");
if (inputDataChannel == nullptr) {
IMSA_HILOGI("InputMethodCoreProxy::startInput inputDataChannel is nullptr");
}
MessageParcel data;
if (!(data.WriteInterfaceToken(GetDescriptor())
&& data.WriteRemoteObject(inputDataChannel->AsObject())
&& data.WriteParcelable(&editorAttribute)
&& data.WriteBool(supportPhysicalKbd))) {
IMSA_HILOGI("InputMethodCoreProxy::startInput write error");
return false;
}
MessageParcel reply;
MessageOption option { MessageOption::TF_SYNC };
int32_t status = Remote()->SendRequest(START_INPUT, data, reply, option);
if (status != ErrorCode::NO_ERROR) {
IMSA_HILOGI("InputMethodCoreProxy::startInput status = %{public}d", status);
return false;
}
int32_t code = reply.ReadException();
return code == ErrorCode::NO_ERROR;
}
int32_t InputMethodCoreProxy::stopInput() {
IMSA_HILOGI("InputMethodCoreProxy::stopInput");
MessageParcel data, reply;
data.WriteInterfaceToken(GetDescriptor());
MessageOption option { MessageOption::TF_SYNC };
int32_t status = Remote()->SendRequest(STOP_INPUT, data, reply, option);
if (status != ErrorCode::NO_ERROR) {
IMSA_HILOGI("InputMethodCoreProxy::stopInput status = %{public}d",status);
return status;
}
int code = reply.ReadException();
if (code != ErrorCode::NO_ERROR) {
IMSA_HILOGI("InputMethodCoreProxy::stopInput code = %{public}d",code);
return code;
}
return reply.ReadInt32();
}
bool InputMethodCoreProxy::showKeyboard(int32_t flags) {
IMSA_HILOGI("InputMethodCoreProxy::showKeyboard");
auto remote = Remote();
if (remote == nullptr){
IMSA_HILOGI("InputMethodCoreProxy::showKeyboard remote is nullptr");
return false;
}
MessageParcel data;
if (!(data.WriteInterfaceToken(GetDescriptor()) && data.WriteInt32(flags))) {
return false;
}
MessageParcel reply;
MessageOption option{ MessageOption::TF_SYNC };
int32_t res = remote->SendRequest(SHOW_KEYBOARD, data, reply, option);
if (res != ErrorCode::NO_ERROR) {
return false;
}
return true;
}
bool InputMethodCoreProxy::hideKeyboard(int32_t flags) {
IMSA_HILOGI("InputMethodCoreProxy::hideKeyboard");
auto remote = Remote();
if (remote == nullptr) {
return false;
}
MessageParcel data;
if (!(data.WriteInterfaceToken(GetDescriptor()) && data.WriteInt32(flags))) {
return false;
}
MessageParcel reply;
MessageOption option{ MessageOption::TF_SYNC };
int32_t res = remote->SendRequest(HIDE_KEYBOARD, data, reply, option);
if (res != ErrorCode::NO_ERROR) {
return false;
}
return true;
}
int32_t InputMethodCoreProxy::setKeyboardType(const KeyboardType& type) {
IMSA_HILOGI("InputMethodCoreProxy::setKeyboardType");
MessageParcel data, reply;
data.WriteInterfaceToken(GetDescriptor());
data.WriteParcelable(&type);
MessageOption option{ MessageOption::TF_SYNC };
int32_t status = Remote()->SendRequest(SET_KEYBOARD_TYPE, data, reply, option);
if (status != ErrorCode::NO_ERROR) {
return status;
}
int32_t code = reply.ReadException();
return code;
}
int32_t InputMethodCoreProxy::getKeyboardWindowHeight(int32_t * retHeight) {
IMSA_HILOGI("InputMethodCoreProxy::getKeyboardWindowHeight");
MessageParcel data, reply;
data.WriteInterfaceToken(GetDescriptor());
MessageOption option { MessageOption::TF_SYNC };
int32_t status = Remote()->SendRequest(GET_KEYBOARD_WINDOW_HEIGHT, data, reply, option);
if (status != ErrorCode::NO_ERROR) {
return status;
}
int32_t code = reply.ReadException();
if (code != 0) {
return code;
}
*retHeight = reply.ReadInt32();
return ErrorCode::NO_ERROR;
}
}
}

View File

@ -0,0 +1,221 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <chrono>
#include <stdint.h>
#include "message_handler.h"
#include "i_input_data_channel.h"
#include "input_method_core_stub.h"
#include "input_channel.h"
#include "i_input_method_proxy.h"
#include "platform.h"
#include "message_parcel.h"
#include "input_control_channel_proxy.h"
namespace OHOS {
namespace MiscServices {
using namespace MessageID;
/**
* param userId the id of the user to whom the object is linking
* @param userId
*/
InputMethodCoreStub::InputMethodCoreStub(int userId) {
userId_ = userId;
}
InputMethodCoreStub::~InputMethodCoreStub() {
}
int32_t InputMethodCoreStub::OnRemoteRequest(uint32_t code, MessageParcel & data, MessageParcel & reply, MessageOption & option) {
IMSA_HILOGI("InputMethodCoreStub::OnRemoteRequest");
auto descriptorToken = data.ReadInterfaceToken();
if (descriptorToken != GetDescriptor()) {
IMSA_HILOGI("InputMethodCoreStub::OnRemoteRequest descriptorToken is invalid");
return ErrorCode::ERROR_STATUS_UNKNOWN_TRANSACTION;
}
switch (code) {
case INITIALIZE_INPUT: {
sptr<IRemoteObject> startInputToken = nullptr;
int32_t displayId = data.ReadInt32();
IMSA_HILOGI("InputMethodCoreStub::OnRemoteRequest displayId = %{public}d", displayId);
sptr<IRemoteObject> channelObject = data.ReadRemoteObject();
if (channelObject == nullptr) {
IMSA_HILOGI("InputMethodCoreStub::OnRemoteRequest channelObject is nullptr");
}
sptr<IInputControlChannel> inputControlChannel = new InputControlChannelProxy(channelObject);
if (inputControlChannel == nullptr) {
IMSA_HILOGI("InputMethodCoreStub::OnRemoteRequest inputControlChannel is nullptr");
}
initializeInput(startInputToken, displayId, inputControlChannel);
reply.WriteNoException();
break;
}
case START_INPUT: {
sptr<IInputDataChannel> inputDataChannel = iface_cast<IInputDataChannel>(data.ReadRemoteObject());
InputAttribute* editorAttribute = data.ReadParcelable<InputAttribute>();
bool supportPhysicalKbd = data.ReadBool();
if (inputDataChannel == nullptr) {
IMSA_HILOGI("InputMethodCoreStub::OnRemoteRequest START_INPUT inputDataChannel is nulltpr");
}
startInput(inputDataChannel, *editorAttribute, supportPhysicalKbd);
reply.WriteNoException();
break;
}
case STOP_INPUT: {
stopInput();
reply.WriteNoException();
break;
}
case SHOW_KEYBOARD: {
int32_t flags = data.ReadInt32();
showKeyboard(flags);
reply.WriteNoException();
break;
}
case HIDE_KEYBOARD: {
int32_t flags = data.ReadInt32();
hideKeyboard(flags);
reply.WriteNoException();
break;
}
case SET_KEYBOARD_TYPE: {
KeyboardType* type = data.ReadParcelable<KeyboardType>();
setKeyboardType(*type);
reply.WriteNoException();
break;
}
case GET_KEYBOARD_WINDOW_HEIGHT: {
int32_t* retHeight = nullptr;
getKeyboardWindowHeight(retHeight);
reply.WriteNoException();
break;
}
default: {
return IRemoteStub::OnRemoteRequest(code, data, reply, option);
}
}
return NO_ERROR;
}
int32_t InputMethodCoreStub::initializeInput(sptr<IRemoteObject>& startInputToken, int32_t displayId, sptr<IInputControlChannel>& inputControlChannel) {
IMSA_HILOGI("InputMethodCoreStub::initializeInput");
if (msgHandler_==nullptr) {
return ErrorCode::ERROR_NULL_POINTER;
}
if (startInputToken == nullptr) {
IMSA_HILOGI("InputMethodCoreStub::initializeInput startInputToken is nullptr");
}
MessageParcel* data = new MessageParcel();
data->WriteInt32(displayId);
if (inputControlChannel != nullptr) {
IMSA_HILOGI("InputMethodCoreStub::initializeInput. inputControlChannel is not nullptr");
data->WriteRemoteObject(inputControlChannel->AsObject());
}
Message* msg = new Message(MessageID::MSG_ID_INITIALIZE_INPUT, data);
msgHandler_->SendMessage(msg);
return ErrorCode::NO_ERROR;
}
bool InputMethodCoreStub::startInput(const sptr<IInputDataChannel>& inputDataChannel, const InputAttribute& editorAttribute, bool supportPhysicalKbd) {
IMSA_HILOGI("InputMethodCoreStub::startInput");
if (msgHandler_ == nullptr) {
return ErrorCode::ERROR_NULL_POINTER;
}
MessageParcel* data = new MessageParcel();
if (inputDataChannel !=nullptr) {
IMSA_HILOGI("InputMethodCoreStub::startInput inputDataChannel is not nullptr");
data->WriteRemoteObject(inputDataChannel->AsObject());
}
data->WriteParcelable(&editorAttribute);
data->WriteBool(supportPhysicalKbd);
Message* msg = new Message(MessageID::MSG_ID_START_INPUT, data);
msgHandler_->SendMessage(msg);
return true;
}
int32_t InputMethodCoreStub::stopInput() {
IMSA_HILOGI("InputMethodCoreStub::stopInput");
if (msgHandler_ == nullptr) {
return ErrorCode::ERROR_NULL_POINTER;
}
MessageParcel* data = new MessageParcel();
Message* msg = new Message(MessageID::MSG_ID_STOP_INPUT, data);
msgHandler_->SendMessage(msg);
return ErrorCode::NO_ERROR;
}
bool InputMethodCoreStub::showKeyboard(int32_t flags) {
IMSA_HILOGI("InputMethodCoreStub::showKeyboard");
if (msgHandler_==nullptr) {
return false;
}
MessageParcel* data = new MessageParcel();
data->WriteInt32(userId_);
data->WriteInt32(flags);
Message* msg = new Message(MessageID::MSG_ID_SHOW_KEYBOARD, data);
msgHandler_->SendMessage(msg);
return true;
}
bool InputMethodCoreStub::hideKeyboard(int32_t flags) {
IMSA_HILOGI("InputMethodCoreStub::hideKeyboard");
if (msgHandler_==nullptr) {
return ErrorCode::ERROR_NULL_POINTER;
}
MessageParcel* data = new MessageParcel();
data->WriteInt32(userId_);
data->WriteInt32(flags);
Message* msg = new Message(MessageID::MSG_ID_HIDE_KEYBOARD, data);
msgHandler_->SendMessage(msg);
return true;
}
int32_t InputMethodCoreStub::setKeyboardType(const KeyboardType& type) {
IMSA_HILOGI("InputMethodCoreStub::setKeyboardType");
if (msgHandler_==nullptr) {
return ErrorCode::ERROR_NULL_POINTER;
}
MessageParcel* data = new MessageParcel();
data->WriteParcelable(&type);
Message* msg = new Message(MessageID::MSG_ID_SET_KEYBOARD_TYPE, data);
msgHandler_->SendMessage(msg);
return ErrorCode::NO_ERROR;
}
int32_t InputMethodCoreStub::getKeyboardWindowHeight(int32_t * retHeight) {
IMSA_HILOGI("InputMethodCoreStub::getKeyboardWindowHeight");
if (msgHandler_==nullptr) {
return ErrorCode::ERROR_NULL_POINTER;
}
MessageParcel* data = new MessageParcel();
Message* msg = new Message(MessageID::MSG_ID_GET_KEYBOARD_WINDOW_HEIGHT, data);
msgHandler_->SendMessage(msg);
return ErrorCode::NO_ERROR;
}
void InputMethodCoreStub::SetMessageHandler(MessageHandler* msgHandler) {
msgHandler_=msgHandler;
}
}
}

View File

@ -0,0 +1,69 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//base/miscservices/inputmethod/inputmethod.gni")
import("//build/ohos.gni")
config("inputmethod_client_native_config") {
visibility = [ ":*" ]
include_dirs = [
"include",
"//utils/native/base/include",
]
}
config("inputmethod_client_native_public_config") {
visibility = []
include_dirs = [
"//base/miscservices/inputmethod/frameworks/inputmethod_controller/include",
"//base/miscservices/inputmethod/frameworks/inputmethod_ability/include",
"//foundation/communication/ipc/interfaces/innerkits/ipc_core/include",
"//base/hiviewdfx/hilog/interfaces/native/innerkits/include",
"//base/miscservices/inputmethod/services/include",
"//utils/native/base/include",
]
}
ohos_shared_library("inputmethod_client") {
sources = [
"src/input_data_channel_stub.cpp",
"src/input_data_channel_proxy.cpp",
"src/input_client_proxy.cpp",
"src/input_client_stub.cpp",
"src/input_method_system_ability_proxy.cpp",
"src/input_method_controller.cpp",
]
deps = [
"//utils/native/base:utils",
"//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core",
"//foundation/communication/ipc/interfaces/innerkits/ipc_single:ipc_single",
"//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk",
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
"//base/miscservices/inputmethod/services:inputmethod_service",
"//base/miscservices/inputmethod/frameworks/inputmethod_ability:inputmethod_ability",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
]
configs = [
":inputmethod_client_native_config",
"//utils/native/base:utils_config",
]
public_configs = [ ":inputmethod_client_native_public_config" ]
subsystem_name = "miscservices"
part_name = "inputmethod_native"
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_IINPUTCLIENT_H
#define FM_IMMS_PROJECT_IINPUTCLIENT_H
#include "iremote_broker.h"
#include "i_input_method_agent.h"
#include "input_channel.h"
#include "global.h"
/**
* brief Definition of interface IInputClient
* It defines the remote calls from input method management service to input client.
*/
namespace OHOS {
namespace MiscServices {
class IInputClient : public IRemoteBroker {
public:
enum {
ON_INPUT_READY = 0,
ON_INPUT_RELEASED ,
SET_DISPLAY_MODE ,
};
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.inputmethod.InputClient");
virtual int32_t onInputReady(int32_t retValue, const sptr<IInputMethodAgent>& agent, const InputChannel* channel) = 0;
virtual int32_t onInputReleased(int32_t retValue) = 0;
virtual int32_t setDisplayMode(int32_t mode) = 0;
};
}
}
#endif // FM_IMMS_PROJECT_IINPUTCLIENT_H

View File

@ -0,0 +1,44 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_IINPUTDATACHANNEL_H
#define FM_IMMS_PROJECT_IINPUTDATACHANNEL_H
#include <errors.h>
#include "iremote_broker.h"
#include "global.h"
/**
* brief Definition of interface IInputDataChannel
* It defines the remote calls from input method service to input client
*/
namespace OHOS {
namespace MiscServices {
class IInputDataChannel: public IRemoteBroker {
public:
enum {
INSERT_TEXT = 0,
DELETE_BACKWARD,
CLOSE,
};
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.inputmethod.IInputDataChannel");
virtual bool InsertText(const std::u16string& text) = 0;
virtual bool DeleteBackward(int32_t length) = 0;
virtual void Close() = 0;
};
}
}
#endif // FM_IMMS_PROJECT_IINPUTDATACHANNEL_H

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMC_PROJECT_INPUTCLIENTPROXY_H
#define FM_IMC_PROJECT_INPUTCLIENTPROXY_H
#include "iremote_proxy.h"
#include "i_input_client.h"
namespace OHOS {
namespace MiscServices {
class InputClientProxy : public IRemoteProxy<IInputClient>
{
public:
explicit InputClientProxy(const sptr<IRemoteObject> &object);
~InputClientProxy() = default;
DISALLOW_COPY_AND_MOVE(InputClientProxy);
int32_t onInputReady(int32_t retValue, const sptr<IInputMethodAgent>& agent, const InputChannel* channel) override;
int32_t onInputReleased(int32_t retValue) override;
int32_t setDisplayMode(int32_t mode) override;
private:
static inline BrokerDelegator<InputClientProxy> delegator_;
};
}
}
#endif

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMC_PROJECT_INPUTCLIENTSTUB_H
#define FM_IMC_PROJECT_INPUTCLIENTSTUB_H
#include "iremote_stub.h"
#include "i_input_client.h"
#include "message_handler.h"
namespace OHOS {
namespace MiscServices {
class InputClientStub : public IRemoteStub<IInputClient> {
public:
DISALLOW_COPY_AND_MOVE(InputClientStub);
int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
InputClientStub();
~InputClientStub();
void SetHandler(MessageHandler* handler);
int32_t onInputReady(int32_t retValue, const sptr<IInputMethodAgent>& agent, const InputChannel* channel) override;
int32_t onInputReleased(int32_t retValue) override;
int32_t setDisplayMode(int32_t mode) override;
private:
MessageHandler* msgHandler = nullptr;
};
}
}
#endif

View File

@ -0,0 +1,43 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMC_PROJECT_INPUTDATACHANNELPROXY_H
#define FM_IMC_PROJECT_INPUTDATACHANNELPROXY_H
#include "iremote_proxy.h"
#include "i_input_data_channel.h"
namespace OHOS {
namespace MiscServices {
class InputDataChannelProxy : public IRemoteProxy<IInputDataChannel>
{
public:
explicit InputDataChannelProxy(const sptr<IRemoteObject> &object);
~InputDataChannelProxy() = default;
DISALLOW_COPY_AND_MOVE(InputDataChannelProxy);
bool InsertText(const std::u16string& text) override;
bool DeleteBackward(int32_t length) override;
void Close() override;
private:
static inline BrokerDelegator<InputDataChannelProxy> delegator_;
};
}
}
#endif

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMC_PROJECT_INPUTDATACHANNELSTUB_H
#define FM_IMC_PROJECT_INPUTDATACHANNELSTUB_H
#include "i_input_data_channel.h"
#include "iremote_stub.h"
#include "message_handler.h"
namespace OHOS {
namespace MiscServices {
class InputDataChannelStub : public IRemoteStub<IInputDataChannel> {
public:
DISALLOW_COPY_AND_MOVE(InputDataChannelStub);
int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
InputDataChannelStub();
~InputDataChannelStub();
void SetHandler(MessageHandler* handler);
bool InsertText(const std::u16string& text) override;
bool DeleteBackward(int32_t length) override;
void Close() override;
private:
MessageHandler* msgHandler;
};
}
}
#endif

View File

@ -0,0 +1,84 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMC_PROJECT_INPUTMETHODCONTROLLER_H
#define FM_IMC_PROJECT_INPUTMETHODCONTROLLER_H
//#include "refbase.h"
#include <mutex>
#include <thread>
#include "input_data_channel_stub.h"
#include "input_client_stub.h"
#include "input_method_system_ability_proxy.h"
#include "input_method_agent_proxy.h"
#include "i_input_method_agent.h"
#include "message_handler.h"
#include "iremote_object.h"
namespace OHOS {
namespace MiscServices {
class OnTextChangedListener : public virtual RefBase {
public:
virtual void InsertText(const std::u16string& text) = 0;
virtual void DeleteBackward(int32_t length) = 0;
virtual void SetKeyboardStatus(bool status) = 0;
};
class ImsaDeathRecipient : public IRemoteObject::DeathRecipient {
public:
explicit ImsaDeathRecipient();
~ImsaDeathRecipient() = default;
void OnRemoteDied(const wptr<IRemoteObject> &object) override;
};
class InputMethodController : public RefBase {
public:
static sptr<InputMethodController> GetInstance();
void Attach();
void ShowTextInput(sptr<OnTextChangedListener> &listener);
void HideTextInput();
void Close();
void OnRemoteSaDied(const wptr<IRemoteObject> &object);
private:
InputMethodController();
~InputMethodController();
bool Initialize();
sptr<InputMethodSystemAbilityProxy> GetImsaProxy();
void PrepareInput(int32_t displayId,sptr<InputClientStub> &client,sptr<InputDataChannelStub> &channel,InputAttribute &attribute);
void StartInput(sptr<InputClientStub> &client);
void StopInput(sptr<InputClientStub> &client);
void ReleaseInput(sptr<InputClientStub> &client);
void WorkThread();
sptr<InputDataChannelStub> mInputDataChannel;
sptr<InputClientStub> mClient;
sptr<InputMethodSystemAbilityProxy> mImms;
sptr<ImsaDeathRecipient> deathRecipient_;
sptr<InputMethodAgentProxy> mAgent;
sptr<OnTextChangedListener> textListener;
InputAttribute mAttribute;
static std::mutex instanceLock_;
static sptr<InputMethodController> instance_;
std::thread workThreadHandler;
MessageHandler* msgHandler;
};
}
}
#endif

View File

@ -0,0 +1,64 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMC_PROJECT_INPUTMETHODSYSTEMABILITYPROXY_H
#define FM_IMC_PROJECT_INPUTMETHODSYSTEMABILITYPROXY_H
#include <vector>
#include "iremote_proxy.h"
#include "i_input_method_system_ability.h"
#include "message_parcel.h"
#include "keyboard_type.h"
#include "input_method_property.h"
#include "input_client_stub.h"
#include "input_data_channel_stub.h"
#include "input_attribute.h"
#include "global.h"
namespace OHOS {
namespace MiscServices {
class InputMethodSystemAbilityProxy : public IRemoteProxy<IInputMethodSystemAbility>
{
public:
explicit InputMethodSystemAbilityProxy(const sptr<IRemoteObject> &object);
~InputMethodSystemAbilityProxy() = default;
DISALLOW_COPY_AND_MOVE(InputMethodSystemAbilityProxy);
virtual void prepareInput(MessageParcel& data) override;
virtual void releaseInput(MessageParcel& data) override;
virtual void startInput(MessageParcel& data) override;
virtual void stopInput(MessageParcel& data) override;
virtual int32_t setInputMethodCore(sptr<IInputMethodCore> &core) override;
int32_t Prepare(int32_t displayId, sptr<InputClientStub> &client, sptr<InputDataChannelStub> &channel, InputAttribute &attribute);
int32_t Release(sptr<InputClientStub> &client);
int32_t Start(sptr<InputClientStub> &client);
int32_t Stop(sptr<InputClientStub> &client);
virtual int32_t getDisplayMode(int32_t *retMode) override;
virtual int32_t getKeyboardWindowHeight(int32_t *retHeight) override;
virtual int32_t getCurrentKeyboardType(KeyboardType* retType) override;
virtual int32_t listInputMethodEnabled(std::vector<InputMethodProperty*> *properties) override;
virtual int32_t listInputMethod(std::vector<InputMethodProperty*> *properties) override;
virtual int32_t listKeyboardType(const std::u16string& imeId, std::vector<KeyboardType*> *types) override;
private:
static inline BrokerDelegator<InputMethodSystemAbilityProxy> delegator_;
};
}
}
#endif

View File

@ -0,0 +1,82 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "input_client_proxy.h"
namespace OHOS {
namespace MiscServices {
using namespace ErrorCode;
InputClientProxy::InputClientProxy(const sptr<IRemoteObject> &object) : IRemoteProxy<IInputClient>(object)
{
}
int32_t InputClientProxy::onInputReady(int32_t retValue, const sptr<IInputMethodAgent>& agent, const InputChannel* channel)
{
IMSA_HILOGI("InputClientProxy::onInputReady");
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
return ERROR_EX_PARCELABLE;
}
if (!data.WriteInt32(retValue)){
return ERROR_EX_PARCELABLE;
}
if (agent ==nullptr) {
data.WriteInt32(0);
} else {
data.WriteInt32(1);
data.WriteRemoteObject(agent->AsObject().GetRefPtr());
}
if (channel == nullptr) {
data.WriteInt32(0);
} else {
data.WriteInt32(1);
data.WriteParcelable(channel);
}
auto ret = Remote()->SendRequest(ON_INPUT_READY, data, reply, option);
if (ret != NO_ERROR) {
IMSA_HILOGI("InputClientProxy::onInputReady SendRequest failed");
return ERROR_STATUS_FAILED_TRANSACTION;
}
return NO_ERROR;
}
int32_t InputClientProxy::onInputReleased(int32_t retValue)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteInt32(retValue);
auto status = Remote()->SendRequest(ON_INPUT_RELEASED, data, reply, option);
return status;
}
int32_t InputClientProxy::setDisplayMode(int32_t mode)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteInt32(mode);
auto status = Remote()->SendRequest(SET_DISPLAY_MODE, data, reply, option);
return status;
}
}
}

View File

@ -0,0 +1,105 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "input_client_stub.h"
#include "global.h"
namespace OHOS {
namespace MiscServices {
InputClientStub::InputClientStub()
{
}
InputClientStub::~InputClientStub()
{
}
int32_t InputClientStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
MessageOption &option)
{
IMSA_HILOGI("InputClientStub::OnRemoteRequest. code = %{public}u", code);
auto descriptorToken = data.ReadInterfaceToken();
if (descriptorToken != GetDescriptor()) {
return ErrorCode::ERROR_STATUS_UNKNOWN_TRANSACTION;
}
switch (code) {
case ON_INPUT_READY: {
if (msgHandler == nullptr) {
break;
}
MessageParcel* parcel = new MessageParcel();
parcel->WriteInt32(data.ReadInt32());
if (data.ReadInt32() > 0) {
parcel->WriteRemoteObject(data.ReadRemoteObject());
}
if (data.ReadInt32() > 0) {
parcel->WriteParcelable(data.ReadParcelable<InputChannel>());
}
Message* msg = new Message(MessageID::MSG_ID_ON_INPUT_READY, parcel);
msgHandler->SendMessage(msg);
break;
}
case ON_INPUT_RELEASED: {
if (msgHandler == nullptr) {
break;
}
MessageParcel* parcel = new MessageParcel();
parcel->WriteInt32(data.ReadInt32());
Message* msg = new Message(MessageID::MSG_ID_EXIT_SERVICE, parcel);
msgHandler->SendMessage(msg);
break;
}
case SET_DISPLAY_MODE: {
if (msgHandler == nullptr) {
break;
}
MessageParcel* parcel = new MessageParcel();
parcel->WriteInt32(data.ReadInt32());
Message* msg = new Message(MessageID::MSG_ID_SET_DISPLAY_MODE, parcel);
msgHandler->SendMessage(msg);
break;
}
default:
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
return NO_ERROR;
}
int32_t InputClientStub::onInputReady(int32_t retValue, const sptr<IInputMethodAgent>& agent, const InputChannel* channel)
{
return ErrorCode::NO_ERROR;
}
int32_t InputClientStub::onInputReleased(int32_t retValue)
{
return ErrorCode::NO_ERROR;
}
int32_t InputClientStub::setDisplayMode(int32_t mode)
{
return ErrorCode::NO_ERROR;
}
void InputClientStub::SetHandler(MessageHandler* handler)
{
msgHandler = handler;
}
}
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "input_data_channel_proxy.h"
#include "message_parcel.h"
#include "utils.h"
namespace OHOS {
namespace MiscServices {
InputDataChannelProxy::InputDataChannelProxy(const sptr<IRemoteObject> &object) : IRemoteProxy<IInputDataChannel>(object)
{
}
bool InputDataChannelProxy::InsertText(const std::u16string& text)
{
IMSA_HILOGI("InputDataChannelProxy::InsertText");
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteString16(text);
auto ret = Remote()->SendRequest(INSERT_TEXT, data, reply, option);
if (ret != NO_ERROR) {
return false;
}
auto result = reply.ReadBool();
return result;
}
bool InputDataChannelProxy::DeleteBackward(int32_t length)
{
IMSA_HILOGI("InputDataChannelProxy::DeleteBackward");
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteInt32(length);
auto ret = Remote()->SendRequest(DELETE_BACKWARD, data, reply, option);
if (ret != NO_ERROR) {
return false;
}
auto result = reply.ReadBool();
return result;
}
void InputDataChannelProxy::Close()
{
IMSA_HILOGI("InputDataChannelProxy::Close");
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
auto ret = Remote()->SendRequest(CLOSE, data, reply, option);
if (ret != NO_ERROR) {
}
}
}
}

View File

@ -0,0 +1,98 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "input_data_channel_stub.h"
namespace OHOS {
namespace MiscServices {
InputDataChannelStub::InputDataChannelStub() : msgHandler(nullptr)
{
}
InputDataChannelStub::~InputDataChannelStub()
{
if (msgHandler != nullptr) {
delete msgHandler;
}
}
int32_t InputDataChannelStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
MessageOption &option)
{
IMSA_HILOGI("InputDataChannelStub::OnRemoteRequest code = %{public}d", code);
auto descriptorToken = data.ReadInterfaceToken();
if (descriptorToken != GetDescriptor()) {
return ErrorCode::ERROR_STATUS_UNKNOWN_TRANSACTION;
}
switch (code) {
case INSERT_TEXT: {
auto text = data.ReadString16();
InsertText(text);
break;
}
case DELETE_BACKWARD: {
auto length = data.ReadInt32();
DeleteBackward(length);
break;
}
case CLOSE: {
Close();
break;
}
default:
return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
}
return NO_ERROR;
}
bool InputDataChannelStub::InsertText(const std::u16string& text)
{
IMSA_HILOGI("InputDataChannelStub::InsertText");
if (msgHandler != nullptr) {
MessageParcel* parcel = new MessageParcel;
parcel->WriteString16(text);
Message* msg = new Message(MessageID::MSG_ID_INSERT_CHAR, parcel);
msgHandler->SendMessage(msg);
IMSA_HILOGI("InputDataChannelStub::InsertText return true");
return true;
}
return false;
}
bool InputDataChannelStub::DeleteBackward(int32_t length)
{
IMSA_HILOGI("InputDataChannelStub::DeleteBackward");
if (msgHandler != nullptr) {
MessageParcel* parcel = new MessageParcel;
parcel->WriteInt32(length);
Message* msg = new Message(MessageID::MSG_ID_DELETE_BACKWARD, parcel);
msgHandler->SendMessage(msg);
return true;
}
return false;
}
void InputDataChannelStub::Close()
{
}
void InputDataChannelStub::SetHandler(MessageHandler* handler)
{
msgHandler = handler;
}
}
}

View File

@ -0,0 +1,249 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "input_method_controller.h"
#include "iservice_registry.h"
#include "system_ability_definition.h"
#include "global.h"
namespace OHOS {
namespace MiscServices {
using namespace MessageID;
sptr<InputMethodController> InputMethodController::instance_;
std::mutex InputMethodController::instanceLock_;
InputMethodController::InputMethodController()
{
IMSA_HILOGI("InputMethodController structure");
Initialize();
}
InputMethodController::~InputMethodController()
{
if (msgHandler != nullptr) {
delete msgHandler;
}
}
sptr<InputMethodController> InputMethodController::GetInstance()
{
IMSA_HILOGI("InputMethodController::GetInstance");
if (instance_ == nullptr) {
std::lock_guard<std::mutex> autoLock(instanceLock_);
if (instance_ == nullptr) {
IMSA_HILOGI("InputMethodController::GetInstance instance_ is nullptr");
instance_ = new InputMethodController();
}
}
return instance_;
}
bool InputMethodController::Initialize()
{
mImms = GetImsaProxy();
msgHandler = new MessageHandler();
mClient = new InputClientStub();
mClient->SetHandler(msgHandler);
mInputDataChannel = new InputDataChannelStub();
mInputDataChannel->SetHandler(msgHandler);
workThreadHandler = std::thread([this]{WorkThread();});
mAttribute.SetInputPattern(InputAttribute::PATTERN_TEXT);
return true;
}
sptr<InputMethodSystemAbilityProxy> InputMethodController::GetImsaProxy()
{
IMSA_HILOGI("InputMethodController::GetImsaProxy");
sptr<ISystemAbilityManager> systemAbilityManager =
SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
if (systemAbilityManager == nullptr) {
IMSA_HILOGI("InputMethodController::GetImsaProxy systemAbilityManager is nullptr");
return nullptr;
}
auto systemAbility = systemAbilityManager->GetSystemAbility(INPUT_METHOD_SYSTEM_ABILITY_ID, "");
if (systemAbility == nullptr) {
IMSA_HILOGI("InputMethodController::GetImsaProxy systemAbility is nullptr");
return nullptr;
}
if (deathRecipient_ == nullptr) {
deathRecipient_ = new ImsaDeathRecipient();
}
systemAbility->AddDeathRecipient(deathRecipient_);
sptr<InputMethodSystemAbilityProxy> iface = new InputMethodSystemAbilityProxy(systemAbility);
return iface;
}
void InputMethodController::WorkThread()
{
while(1) {
Message* msg = msgHandler->GetMessage();
switch(msg->msgId_) {
case MSG_ID_INSERT_CHAR:{
MessageParcel* data = msg->msgContent_;
std::u16string text = data->ReadString16();
if(textListener != nullptr){
textListener->InsertText(text);
}
break;
}
case MSG_ID_DELETE_BACKWARD:{
MessageParcel* data = msg->msgContent_;
int32_t length = data->ReadInt32();
if(textListener != nullptr){
textListener->DeleteBackward(length);
}
break;
}
case MSG_ID_SET_DISPLAY_MODE:{
MessageParcel* data = msg->msgContent_;
int32_t ret = data->ReadInt32();
IMSA_HILOGI("MSG_ID_SET_DISPLAY_MODE : %{public}d", ret);
break;
}
case MSG_ID_ON_INPUT_READY:{
MessageParcel* data = msg->msgContent_;
int32_t ret = data->ReadInt32();
if(ret != ErrorCode::NO_ERROR) {
if (textListener != nullptr){
textListener->SetKeyboardStatus(false);
}
mAgent=nullptr;
break;
}
sptr<IRemoteObject> object = data->ReadRemoteObject();
mAgent = new InputMethodAgentProxy(object);
if (textListener != nullptr){
textListener->SetKeyboardStatus(true);
}
break;
}
case MSG_ID_EXIT_SERVICE:{
MessageParcel* data = msg->msgContent_;
int32_t ret = data->ReadInt32();
IMSA_HILOGI("MSG_ID_EXIT_SERVICE : %{public}d", ret);
break;
}
default:{
break;
}
}
delete msg;
}
}
void InputMethodController::Attach()
{
PrepareInput(0,mClient,mInputDataChannel,mAttribute);
}
void InputMethodController::ShowTextInput(sptr<OnTextChangedListener> &listener)
{
IMSA_HILOGI("InputMethodController::ShowTextInput");
textListener=listener;
StartInput(mClient);
}
void InputMethodController::HideTextInput()
{
IMSA_HILOGI("InputMethodController::HideTextInput");
StopInput(mClient);
}
void InputMethodController::Close()
{
ReleaseInput(mClient);
}
void InputMethodController::PrepareInput(int32_t displayId,sptr<InputClientStub> &client,sptr<InputDataChannelStub> &channel,InputAttribute &attribute)
{
IMSA_HILOGI("InputMethodController::PrepareInput");
if(mImms == nullptr){
return;
}
MessageParcel data;
if(!(data.WriteInterfaceToken(mImms->GetDescriptor())
&&data.WriteInt32(displayId)
&&data.WriteRemoteObject(client->AsObject())
&&data.WriteRemoteObject(channel->AsObject())
&&data.WriteParcelable(&attribute))){
return;
}
mImms->prepareInput(data);
}
void InputMethodController::StartInput(sptr<InputClientStub> &client)
{
IMSA_HILOGI("InputMethodController::StartInput");
if(mImms == nullptr){
return;
}
MessageParcel data;
if(!(data.WriteInterfaceToken(mImms->GetDescriptor())
&&data.WriteRemoteObject(client->AsObject()))){
return;
}
mImms->startInput(data);
}
void InputMethodController::ReleaseInput(sptr<InputClientStub> &client)
{
IMSA_HILOGI("InputMethodController::ReleaseInput");
if(mImms == nullptr){
return;
}
MessageParcel data;
if(!(data.WriteInterfaceToken(mImms->GetDescriptor())
&&data.WriteRemoteObject(client->AsObject().GetRefPtr()))) {
return;
}
mImms->releaseInput(data);
}
void InputMethodController::StopInput(sptr<InputClientStub> &client)
{
IMSA_HILOGI("InputMethodController::StopInput");
if(mImms == nullptr){
return;
}
MessageParcel data;
if(!(data.WriteInterfaceToken(mImms->GetDescriptor())
&&data.WriteRemoteObject(client->AsObject().GetRefPtr()))) {
return;
}
mImms->stopInput(data);
}
void InputMethodController::OnRemoteSaDied(const wptr<IRemoteObject> &remote) {
mImms = GetImsaProxy();
}
ImsaDeathRecipient::ImsaDeathRecipient()
{
}
void ImsaDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
{
InputMethodController::GetInstance()->OnRemoteSaDied(object);
}
}
}

View File

@ -0,0 +1,410 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "input_method_system_ability_proxy.h"
namespace OHOS {
namespace MiscServices {
using namespace ErrorCode;
InputMethodSystemAbilityProxy::InputMethodSystemAbilityProxy(const sptr<IRemoteObject> &object)
: IRemoteProxy<IInputMethodSystemAbility>(object)
{
}
void InputMethodSystemAbilityProxy::prepareInput(MessageParcel& data)
{
MessageParcel reply;
MessageOption option;
auto ret = Remote()->SendRequest(PREPARE_INPUT, data, reply, option);
if (ret != NO_ERROR) {
IMSA_HILOGI("InputMethodSystemAbilityProxy::prepareInput SendRequest failed");
return;
}
ret = reply.ReadInt32();
if (ret != NO_ERROR) {
IMSA_HILOGI("InputMethodSystemAbilityProxy::prepareInput reply failed");
return;
}
}
void InputMethodSystemAbilityProxy::releaseInput(MessageParcel& data)
{
MessageParcel reply;
MessageOption option;
auto ret = Remote()->SendRequest(RELEASE_INPUT, data, reply, option);
if (ret != NO_ERROR) {
IMSA_HILOGI("InputMethodSystemAbilityProxy::releaseInput SendRequest failed");
return;
}
ret = reply.ReadInt32();
if (ret != NO_ERROR) {
IMSA_HILOGI("InputMethodSystemAbilityProxy::releaseInput reply failed");
return;
}
}
void InputMethodSystemAbilityProxy::startInput(MessageParcel& data)
{
IMSA_HILOGI("InputMethodSystemAbilityProxy::startInput");
MessageParcel reply;
MessageOption option;
auto ret = Remote()->SendRequest(START_INPUT,data,reply,option);
if (ret != NO_ERROR) {
IMSA_HILOGI("InputMethodSystemAbilityProxy::startInput SendRequest failed");
return;
}
ret = reply.ReadInt32();
if (ret != NO_ERROR) {
IMSA_HILOGI("InputMethodSystemAbilityProxy::startInput reply failed");
return;
}
}
void InputMethodSystemAbilityProxy::stopInput(MessageParcel& data)
{
IMSA_HILOGI("InputMethodSystemAbilityProxy::stopInput");
MessageParcel reply;
MessageOption option;
auto ret = Remote()->SendRequest(STOP_INPUT,data,reply,option);
if (ret != NO_ERROR) {
IMSA_HILOGI("InputMethodSystemAbilityProxy::stopInput SendRequest failed");
return;
}
ret = reply.ReadInt32();
if (ret != NO_ERROR) {
IMSA_HILOGI("InputMethodSystemAbilityProxy::stopInput reply failed");
return;
}
}
int32_t InputMethodSystemAbilityProxy::setInputMethodCore(sptr<IInputMethodCore> &core)
{
IMSA_HILOGI("InputMethodSystemAbilityProxy::setInputMethodCore");
if (core == nullptr) {
IMSA_HILOGI("InputMethodSystemAbilityProxy::setInputMethodCore inputDataChannel is nullptr");
}
auto remote = Remote();
if (remote == nullptr)
return -1;
MessageParcel data;
if (!(data.WriteInterfaceToken(GetDescriptor())
&& data.WriteRemoteObject(core->AsObject())))
return -1;
MessageParcel reply;
MessageOption option { MessageOption::TF_SYNC };
int32_t status = Remote()->SendRequest(SET_INPUT_METHOD_CORE, data, reply, option);
return status;
}
int32_t InputMethodSystemAbilityProxy::Prepare(int32_t displayId, sptr<InputClientStub> &client, sptr<InputDataChannelStub> &channel, InputAttribute &attribute)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
return ERROR_EX_PARCELABLE;
}
if (!(data.WriteInt32(displayId)
&& data.WriteRemoteObject(client->AsObject())
&& data.WriteRemoteObject(channel->AsObject())
&& data.WriteParcelable(&attribute))) {
return ERROR_EX_PARCELABLE;
}
auto ret = Remote()->SendRequest(PREPARE_INPUT, data, reply, option);
if (ret != NO_ERROR) {
return ERROR_STATUS_FAILED_TRANSACTION;
}
ret = reply.ReadInt32();
if (ret != NO_ERROR) {
return ret;
}
return NO_ERROR;
}
int32_t InputMethodSystemAbilityProxy::Release(sptr<InputClientStub> &client)
{
IMSA_HILOGI("InputMethodSystemAbilityProxy::Release");
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
return ERROR_EX_PARCELABLE;
}
if (!data.WriteRemoteObject(client->AsObject().GetRefPtr())) {
return ERROR_EX_PARCELABLE;
}
auto ret = Remote()->SendRequest(RELEASE_INPUT, data, reply, option);
if (ret != NO_ERROR) {
return ERROR_STATUS_FAILED_TRANSACTION;
}
ret = reply.ReadInt32();
if (ret != NO_ERROR) {
return ret;
}
return NO_ERROR;
}
int32_t InputMethodSystemAbilityProxy::Start(sptr<InputClientStub> &client)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
return ERROR_EX_PARCELABLE;
}
if (!data.WriteRemoteObject(client->AsObject().GetRefPtr())) {
return ERROR_EX_PARCELABLE;
}
auto ret = Remote()->SendRequest(START_INPUT, data, reply, option);
if (ret != NO_ERROR) {
return ERROR_STATUS_FAILED_TRANSACTION;
}
ret = reply.ReadInt32();
if (ret != NO_ERROR) {
return ret;
}
return NO_ERROR;
}
int32_t InputMethodSystemAbilityProxy::Stop(sptr<InputClientStub> &client)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
return ERROR_EX_PARCELABLE;
}
if (!data.WriteRemoteObject(client->AsObject().GetRefPtr())) {
return ERROR_EX_PARCELABLE;
}
auto ret = Remote()->SendRequest(STOP_INPUT, data, reply, option);
if (ret != NO_ERROR) {
return ERROR_STATUS_FAILED_TRANSACTION;
}
ret = reply.ReadInt32();
if (ret != NO_ERROR) {
return ret;
}
return NO_ERROR;
}
int32_t InputMethodSystemAbilityProxy::getDisplayMode(int32_t *retMode)
{
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
return ERROR_EX_PARCELABLE;
}
auto ret = Remote()->SendRequest(GET_DISPLAY_MODE, data, reply, option);
if (ret != NO_ERROR) {
return ERROR_STATUS_FAILED_TRANSACTION;
}
ret = reply.ReadInt32();
if (ret != NO_ERROR) {
return ret;
}
if (!reply.ReadInt32(*retMode)) {
return ERROR_STATUS_BAD_VALUE;
}
return NO_ERROR;
}
int32_t InputMethodSystemAbilityProxy::getKeyboardWindowHeight(int32_t *retHeight)
{
if (retHeight == nullptr) {
return ERROR_NULL_POINTER;
}
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
return ERROR_EX_PARCELABLE;
}
auto ret = Remote()->SendRequest(GET_KEYBOARD_WINDOW_HEIGHT, data, reply, option);
if (ret != NO_ERROR) {
return ERROR_STATUS_FAILED_TRANSACTION;
}
ret = reply.ReadInt32();
if (ret != NO_ERROR) {
return ret;
}
if (!reply.ReadInt32(*retHeight)) {
return ERROR_STATUS_BAD_VALUE;
}
return NO_ERROR;
}
int32_t InputMethodSystemAbilityProxy::getCurrentKeyboardType(KeyboardType* retType)
{
if (retType == nullptr) {
return ERROR_NULL_POINTER;
}
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
return ERROR_EX_PARCELABLE;
}
auto ret = Remote()->SendRequest(GET_CURRENT_KEYBOARD_TYPE, data, reply, option);
if (ret != NO_ERROR) {
return ERROR_STATUS_FAILED_TRANSACTION;
}
ret = reply.ReadInt32();
if (ret != NO_ERROR) {
return ret;
}
KeyboardType* keyType = reply.ReadParcelable<KeyboardType>();
*retType = *keyType;
delete keyType;
return NO_ERROR;
}
int32_t InputMethodSystemAbilityProxy::listInputMethodEnabled(std::vector<InputMethodProperty*> *properties)
{
if (properties == nullptr) {
return ERROR_NULL_POINTER;
}
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
return ERROR_EX_PARCELABLE;
}
auto ret = Remote()->SendRequest(LIST_INPUT_METHOD_ENABLED, data, reply, option);
if (ret != NO_ERROR) {
return ERROR_STATUS_FAILED_TRANSACTION;
}
ret = reply.ReadInt32();
if (ret != NO_ERROR) {
return ret;
}
auto size = reply.ReadInt32();
while (size > 0) {
InputMethodProperty* imp = reply.ReadParcelable<InputMethodProperty>();
properties->push_back(imp);
size--;
}
return NO_ERROR;
}
int32_t InputMethodSystemAbilityProxy::listInputMethod(std::vector<InputMethodProperty*> *properties)
{
if (properties == nullptr) {
return ERROR_NULL_POINTER;
}
MessageParcel data, reply;
MessageOption option;
if (!data.WriteInterfaceToken(GetDescriptor())) {
return ERROR_EX_PARCELABLE;
}
auto ret = Remote()->SendRequest(LIST_INPUT_METHOD, data, reply, option);
if (ret != NO_ERROR) {
return ERROR_STATUS_FAILED_TRANSACTION;
}
ret = reply.ReadInt32();
if (ret != NO_ERROR) {
return ret;
}
auto size = reply.ReadInt32();
while (size > 0) {
InputMethodProperty* imp = reply.ReadParcelable<InputMethodProperty>();
properties->push_back(imp);
size--;
}
return NO_ERROR;
}
int32_t InputMethodSystemAbilityProxy::listKeyboardType(const std::u16string& imeId, std::vector<KeyboardType*> *types)
{
if (types == nullptr) {
return ERROR_NULL_POINTER;
}
MessageParcel data, reply;
MessageOption option;
if (!(data.WriteInterfaceToken(GetDescriptor()) && data.WriteString16(imeId))) {
return ERROR_EX_PARCELABLE;
}
auto ret = Remote()->SendRequest(LIST_KEYBOARD_TYPE, data, reply, option);
if (ret != NO_ERROR) {
return ERROR_STATUS_FAILED_TRANSACTION;
}
ret = reply.ReadInt32();
if (ret != NO_ERROR) {
return ret;
}
auto size = reply.ReadInt32();
while (size > 0) {
KeyboardType* kt = reply.ReadParcelable<KeyboardType>();
types->push_back(kt);
size--;
}
return NO_ERROR;
}
}
}

20
inputmethod.gni Normal file
View File

@ -0,0 +1,20 @@
# Copyright (C) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
inputmethod_path = "//base/miscservices/inputmethod"
kits_path = "${inputmethod_path}/interfaces/kits"
innerkits_path = "${inputmethod_path}/interfaces/innerkits"
adapter_path = "${inputmethod_path}/adapter"

View File

@ -0,0 +1,31 @@
# Copyright (C) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
import("//build/ohos/ace/ace.gni")
js_declaration("inputmethod") {
part_name = "inputmethod_native"
sources = [
"./api",
]
}
ohos_copy("inputmethod_declaration") {
sources = [
"./api"
]
outputs = [ target_out_dir + "/$target_name/" ]
module_source_dir = target_out_dir + "/$target_name"
module_install_name = ""
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { AsyncCallback } from './basic';
/**
* inputmethod
*
* @since 6
* @import inputmethod from '@ohos.inputmethod';
* @devices phone, tablet, tv, wearable
*/
declare namespace inputMethodAbility {
function on(type: 'keyboardShow', callback: () => void): void;
function off(type: 'keyboardShow', callback: () => void): void;
function on(type: 'keyboardHide', callback: () => void): void;
function off(type: 'keyboardHide', callback: () => void): void;
function insertText(text: string, callback: AsyncCallback<boolean>): void;
function insertText(text: string): Promise<boolean>;
function DeleteBackward(length: number, callback: () => void): void;
function DeleteBackward(length: number): Promise<void>;
function HideKeyboardSelf(callback: callback: () => void): void;
function HideKeyboardSelf(): Promise<void>;
}
export default inputMethodAbility;

View File

@ -0,0 +1,76 @@
# Copyright (C) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos.gni")
config("inputmethodability_native_config") {
visibility = [ ":*" ]
include_dirs = [
"include",
]
}
config("inputmethodability_native_public_config") {
visibility = []
include_dirs = [ "include" ]
}
ohos_shared_library("inputmethodability") {
include_dirs = [
"//third_party/node/src",
"//foundation/ace/napi/interfaces/kits",
]
cflags = [
"-fPIC",
"-g3",
]
sources = [ "js_input_method_ability.cpp" ]
configs = [ ":inputmethodability_native_config" ]
deps = [
"//base/miscservices/inputmethod/frameworks/inputmethod_ability:inputmethod_ability",
"//foundation/ace/napi/:ace_napi",
"//foundation/aafwk/standard/interfaces/innerkits/want:want",
"//utils/native/base:utils",
"//base/global/resmgr_standard/frameworks/resmgr:global_resmgr",
"//foundation/aafwk/standard/frameworks/kits/ability/native:abilitykit_native",
"//foundation/aafwk/standard/interfaces/innerkits/ability_manager:ability_manager",
"//foundation/aafwk/standard/interfaces/innerkits/want:want",
"//foundation/aafwk/standard/interfaces/innerkits/base:base",
"//foundation/aafwk/standard/interfaces/innerkits/intent:intent",
"//foundation/multimodalinput/input/interfaces/native/innerkits/event:mmi_event",
"//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_base:appexecfwk_base",
"//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_core:appexecfwk_core",
"//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler:libeventhandler",
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
"//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core",
"//foundation/communication/ipc/interfaces/innerkits/ipc_single:ipc_single",
"//foundation/multimodalinput/input/interfaces/native/innerkits/event:mmi_event",
"//foundation/distributedschedule/dmsfwk/interfaces/innerkits/uri:zuri",
"//base/miscservices/inputmethod/services:inputmethod_service",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
"ipc:ipc_core",
]
relative_install_dir = "module"
subsystem_name = "miscservices"
part_name = "inputmethod_native"
}

View File

@ -0,0 +1,218 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "event_target.h"
#include "napi/native_api.h"
#include "napi/native_node_api.h"
#include "global.h"
using namespace OHOS::MiscServices;
napi_value JS_Constructor(napi_env env, napi_callback_info cbInfo)
{
IMSA_HILOGI("JS_Constructor() is called!");
napi_value thisVar = nullptr;
void* data = nullptr;
napi_get_cb_info(env, cbInfo, nullptr, nullptr, &thisVar, &data);
OHOS::MiscServices::EventTarget* imeAbility = new OHOS::MiscServices::EventTarget(env,thisVar);
napi_wrap(env, thisVar, imeAbility,
[](napi_env env, void* data, void* hint){
EventTarget* imeAbility = (EventTarget*)data;
delete imeAbility;
},
nullptr, nullptr);
OHOS::sptr<EventTarget> eventTarget_=imeAbility;
InputMethodAbility::GetInstance()->setEventTarget(eventTarget_);
return thisVar;
}
napi_value JS_InsertText(napi_env env, napi_callback_info cbInfo)
{
IMSA_HILOGI("JS_InsertText() is called!");
size_t argc = 1;
napi_value argv[2] = { 0 };
napi_value thisVar = nullptr;
void* data = nullptr;
napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, &data);
EventTarget* imeAbility = nullptr;
napi_unwrap(env, thisVar, (void **)&imeAbility);
char type[64] = { 0 };
size_t typeLen = 0;
napi_get_value_string_utf8(env, argv[0], type, sizeof(type), &typeLen);
std::string text=type;
InputMethodAbility::GetInstance()->InsertText(text);
napi_value result = nullptr;
napi_get_undefined(env, &result);
IMSA_HILOGI("JS_InsertText() is end!");
return result;
}
napi_value JS_DeleteBackward(napi_env env, napi_callback_info cbInfo)
{
IMSA_HILOGI("JS_DeleteBackward() is called!");
size_t argc = 1;
napi_value argv[2] = { 0 };
napi_value thisVar = nullptr;
void* data = nullptr;
napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, &data);
EventTarget* imeAbility = nullptr;
napi_unwrap(env, thisVar, (void **)&imeAbility);
int32_t value32 = 0;
napi_get_value_int32(env, argv[0], &value32);
InputMethodAbility::GetInstance()->DeleteBackward(value32);
napi_value result = nullptr;
napi_get_undefined(env, &result);
return result;
}
napi_value JS_HideKeyboardSelf(napi_env env, napi_callback_info cbInfo)
{
IMSA_HILOGI("JS_HideKeyboardSelf() is called!");
size_t argc = 1;
napi_value argv[2] = { 0 };
napi_value thisVar = nullptr;
void* data = nullptr;
napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, &data);
EventTarget* imeAbility = nullptr;
napi_unwrap(env, thisVar, (void **)&imeAbility);
InputMethodAbility::GetInstance()->HideKeyboardSelf();
napi_value result = nullptr;
napi_get_undefined(env, &result);
return result;
}
napi_value JS_On(napi_env env, napi_callback_info cbInfo)
{
IMSA_HILOGI("JS_On() is called!");
size_t requireArgc = 2;
size_t argc = 2;
napi_value argv[2] = { 0 };
napi_value thisVar = 0;
void* data = nullptr;
napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, &data);
EventTarget* imeAbility = nullptr;
napi_unwrap(env, thisVar, (void **)&imeAbility);
NAPI_ASSERT(env, argc >= requireArgc, "requires 2 parameter");
napi_valuetype eventValueType;
napi_typeof(env, argv[0], &eventValueType);
NAPI_ASSERT(env, eventValueType == napi_string, "type mismatch for parameter 1");
napi_valuetype eventHandleType;
napi_typeof(env, argv[1], &eventHandleType);
NAPI_ASSERT(env, eventHandleType == napi_function, "type mismatch for parameter 2");
char type[64] = { 0 };
size_t typeLen = 0;
napi_get_value_string_utf8(env, argv[0], type, sizeof(type), &typeLen);
IMSA_HILOGI("call ima on function");
imeAbility->On((const char*)type, argv[1]);
napi_value result = nullptr;
napi_get_undefined(env, &result);
IMSA_HILOGI("JS_On() is end!");
return result;
}
napi_value JS_Off(napi_env env, napi_callback_info cbInfo)
{
size_t requireArgc = 1;
size_t argc = 2;
napi_value argv[2] = { 0 };
napi_value thisVar = 0;
void* data = nullptr;
napi_get_cb_info(env, cbInfo, &argc, argv, &thisVar, &data);
EventTarget* imeAbility = nullptr;
napi_unwrap(env, thisVar, (void **)&imeAbility);
NAPI_ASSERT(env, argc >= requireArgc, "requires 2 parameter");
napi_valuetype eventValueType;
napi_typeof(env, argv[0], &eventValueType);
NAPI_ASSERT(env, eventValueType == napi_string, "type mismatch for parameter 1");
char* type = nullptr;
size_t typeLen = 0;
napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typeLen);
type = new char[typeLen + 1];
napi_get_value_string_utf8(env, argv[0], type, typeLen + 1, &typeLen);
if (argc > requireArgc) {
NAPI_ASSERT(env, eventValueType == napi_function, "type mismatch for parameter 2");
imeAbility->Off(type, argv[1]);
} else {
imeAbility->Off(type);
}
delete type;
delete type;
napi_value result = nullptr;
napi_get_undefined(env, &result);
return result;
}
napi_value InputMethodAbilityInit(napi_env env, napi_value exports)
{
IMSA_HILOGI("InputMethodAbilityInit() is called!");
const char className[] = "EventTarget";
napi_value constructor = nullptr;
napi_property_descriptor desc[] = {
DECLARE_NAPI_FUNCTION("insertText", JS_InsertText),
DECLARE_NAPI_FUNCTION("DeleteBackward", JS_DeleteBackward),
DECLARE_NAPI_FUNCTION("HideKeyboardSelf", JS_HideKeyboardSelf),
DECLARE_NAPI_FUNCTION("on", JS_On),
DECLARE_NAPI_FUNCTION("off", JS_Off),
};
napi_define_class(env, className, sizeof(className),JS_Constructor, nullptr,
sizeof(desc) / sizeof(desc[0]), desc, &constructor);
napi_set_named_property(env, exports, "InputMethodAbility", constructor);
return exports;
}
/*
* module define
*/
static napi_module inputMethodAbilityModule = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = InputMethodAbilityInit,
.nm_modname = "inputMethodAbility",
.nm_priv = ((void*)0),
.reserved = { 0 },
};
/*
* module register
*/
extern "C" __attribute__((constructor)) void RegisterModule()
{
IMSA_HILOGI("RegisterModule() is called!");
napi_module_register(&inputMethodAbilityModule);
}

53
ohos.build Normal file
View File

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

24
profile/3703.xml Normal file
View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2021 Huawei Device Co., Ltd.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<info>
<process>inputmethod_service</process>
<systemability>
<name>3703</name>
<libpath>libinputmethod_service.z.so</libpath>
<run-on-create>true</run-on-create>
<distributed>false</distributed>
<dump-level>1</dump-level>
</systemability>
</info>

19
profile/BUILD.gn Normal file
View File

@ -0,0 +1,19 @@
# Copyright (C) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/ohos/sa_profile/sa_profile.gni")
ohos_sa_profile("miscservices_inputmethod_sa_profiles") {
sources = [ "3703.xml" ]
part_name = "inputmethod_native"
}

96
services/BUILD.gn Normal file
View File

@ -0,0 +1,96 @@
# Copyright (c) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//base/miscservices/inputmethod/inputmethod.gni")
import("//build/ohos.gni")
config("inputmethod_services_native_config") {
visibility = [ ":*" ]
include_dirs = [
"include",
"${inputmethod_path}/frameworks/inputmethod_ability/include",
"${inputmethod_path}/frameworks/inputmethod_controller/include",
]
cflags_cc = [ "-fexceptions" ]
}
ohos_shared_library("inputmethod_service") {
sources = [
"../services/src/input_attribute.cpp",
"../services/src/global.cpp",
"../services/src/input_channel.cpp",
"../services/src/keyboard_type.cpp",
"../services/src/input_method_property.cpp",
"../services/src/message.cpp",
"../services/src/message_handler.cpp",
"../services/src/input_method_system_ability_stub.cpp",
"../services/src/input_method_setting.cpp",
"../services/src/peruser_setting.cpp",
"../services/src/peruser_session.cpp",
"../services/src/input_method_system_ability.cpp",
"../services/src/input_control_channel_proxy.cpp",
"../services/src/input_control_channel_stub.cpp",
"../services/src/platform.cpp",
"../services/src/platform_callback_stub.cpp",
"../services/src/platform_callback_proxy.cpp",
"../services/src/platform_api_proxy.cpp",
"../services/src/input_method_ability_connection_stub.cpp",
"${inputmethod_path}/frameworks/inputmethod_ability/src/input_method_agent_proxy.cpp",
"${inputmethod_path}/frameworks/inputmethod_ability/src/input_method_core_proxy.cpp",
"${inputmethod_path}/frameworks/inputmethod_ability/src/input_method_core_stub.cpp",
"${inputmethod_path}/frameworks/inputmethod_ability/src/input_method_ability.cpp",
"${inputmethod_path}/frameworks/inputmethod_ability/src/input_method_agent_stub.cpp",
"${inputmethod_path}/frameworks/inputmethod_controller/src/input_client_proxy.cpp",
"${inputmethod_path}/frameworks/inputmethod_controller/src/input_data_channel_proxy.cpp",
"${inputmethod_path}/frameworks/inputmethod_controller/src/input_method_system_ability_proxy.cpp",
]
configs = [ ":inputmethod_services_native_config" ]
public_configs = [
":inputmethod_services_native_config",
]
deps = [
"//utils/native/base:utils",
"//base/global/resmgr_standard/frameworks/resmgr:global_resmgr",
"//foundation/aafwk/standard/frameworks/kits/ability/native:abilitykit_native",
"//foundation/aafwk/standard/interfaces/innerkits/ability_manager:ability_manager",
"//foundation/aafwk/standard/interfaces/innerkits/want:want",
"//foundation/aafwk/standard/interfaces/innerkits/base:base",
"//foundation/aafwk/standard/interfaces/innerkits/intent:intent",
"//foundation/ace/napi/:ace_napi",
"//foundation/multimodalinput/input/interfaces/native/innerkits/event:mmi_event",
"//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_base:appexecfwk_base",
"//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_core:appexecfwk_core",
"//foundation/appexecfwk/standard/interfaces/innerkits/libeventhandler:libeventhandler",
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
"//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core",
"//foundation/communication/ipc/interfaces/innerkits/ipc_single:ipc_single",
"//foundation/multimodalinput/input/interfaces/native/innerkits/event:mmi_event",
"//foundation/distributedschedule/dmsfwk/interfaces/innerkits/uri:zuri",
"//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk",
"//foundation/aafwk/standard/services/abilitymgr:abilityms",
"//foundation/ace/napi/:ace_napi",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
]
subsystem_name = "miscservices"
part_name = "inputmethod_native"
}

172
services/include/global.h Normal file
View File

@ -0,0 +1,172 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_GLOBAL_H
#define FM_IMMS_PROJECT_GLOBAL_H
#include <errno.h>
#include <time.h>
#include <sys/time.h>
#include "iremote_broker.h"
#include "peer_holder.h"
#include "ipc_object_stub.h"
#include "refbase.h"
#include "hilog/log.h"
namespace OHOS {
namespace MiscServices {
#define PLATFORM OHOS
using BRemoteObject = IPCObjectStub;
#define INPUTMETHOD_DEBUG 0
#define LOG_INFO(fmt, args...) \
LogTimeStamp();printf("I %s:%d %s - " fmt, basename(__FILE__), __LINE__, __FUNCTION__, ##args)
#define LOG_ERROR(fmt, args...) \
LogTimeStamp();printf("E %s:%d %s - " fmt, basename(__FILE__), __LINE__, __FUNCTION__, ##args)
#define LOG_WARNING(fmt, args...) \
LogTimeStamp();printf("W %s:%d %s - " fmt, basename(__FILE__), __LINE__, __FUNCTION__, ##args)
#if DEBUG
#define LOG_DEBUG(fmt, args...) \
LogTimeStamp();printf("D %s:%d %s - " fmt, basename(__FILE__), __LINE__, __FUNCTION__, ##args)
#else
#define LOG_DEBUG(fmt, args...)
#endif
void LogTimeStamp();
namespace CommonEvent {
//! the events handled in input method management system
enum {
COMMON_EVENT_USER_STARTED = 10001, /*!< a user is started. */
COMMON_EVENT_USER_STOPPED = 10002, /*!< a user is stopped. */
COMMON_EVENT_USER_UNLOCKED = 10003, /*!< a user is unlocked. */
COMMON_EVENT_USER_LOCKED = 10004, /*!< a user is locked. */
COMMON_EVENT_SETTING_CHANGED = 10005, /*!< input method setting data is changed. */
COMMON_EVENT_PACKAGE_ADDED = 10006, /*!< a package is installed. */
COMMON_EVENT_PACKAGE_REMOVED = 10007, /*!< a package is removed */
};
};
//! User State
namespace UserState {
/*! The states of a user in the system. */
enum {
USER_STATE_NOT_AVAILABLE = -1,
USER_STATE_STARTED = 0, /*!< a user is started. */
USER_STATE_UNLOCKED, /*!< a user is unlocked. */
};
};
//! Error Code
namespace ErrorCode {
/*! Error Code definition in the input method management system */
enum {
ERROR_STATUS_UNKNOWN_ERROR = (-2147483647 - 1), //!< unknown error
ERROR_STATUS_NO_MEMORY = -ENOMEM, //!< no memory
ERROR_STATUS_INVALID_OPERATION = -ENOSYS, //!< invalid operation
ERROR_STATUS_BAD_VALUE = -EINVAL, //!< bad value
ERROR_STATUS_BAD_TYPE = ERROR_STATUS_UNKNOWN_ERROR+1, //!< bad type
ERROR_STATUS_NAME_NOT_FOUND = -ENOENT, //!< name not found
ERROR_STATUS_PERMISSION_DENIED = -EPERM, //!< permission denied
ERROR_STATUS_NO_INIT = -ENODEV, //!< no init
ERROR_STATUS_ALREADY_EXISTS = -EEXIST, //!< already exist
ERROR_STATUS_DEAD_OBJECT = -EPIPE, //!< dead object
ERROR_STATUS_FAILED_TRANSACTION = ERROR_STATUS_UNKNOWN_ERROR+2, //!< failed transaction
ERROR_STATUS_BAD_INDEX = -EOVERFLOW, //!< bad index
ERROR_STATUS_NOT_ENOUGH_DATA = -ENODATA, //!< not enough data
ERROR_STATUS_WOULD_BLOCK = -EWOULDBLOCK, //!< would block
ERROR_STATUS_TIMED_OUT = -ETIMEDOUT, //!< time out
ERROR_STATUS_UNKNOWN_TRANSACTION = -EBADMSG, //!< unknown transaction
ERROR_STATUS_FDS_NOT_ALLOWED = ERROR_STATUS_UNKNOWN_ERROR+7, //!< fds not allowed
ERROR_STATUS_UNEXPECTED_NULL = ERROR_STATUS_UNKNOWN_ERROR+8, //!< unexpected null,
// binder exception error code from Status.h
ERROR_EX_ILLEGAL_ARGUMENT = -3, //!< illegal argument exception
ERROR_EX_NULL_POINTER = -4, //!< null pointer exception
ERROR_EX_ILLEGAL_STATE = -5, //!< illegal state exception
ERROR_EX_NETWORK_MAIN_THREAD = -6, //!< network main thread exception
ERROR_EX_UNSUPPORTED_OPERATION = -7, //!< unsupported operation exception
ERROR_EX_SERVICE_SPECIFIC = -8, //!< service specific exception
ERROR_EX_PARCELABLE = -9, //!< parcelable exception
// no error
NO_ERROR = 0, //!< no error
// system service error
ERROR_NULL_POINTER, //!< null pointer
ERROR_BAD_PARAMETERS, //!< bad parameters
ERROR_SERVICE_START_FAILED, //!< failed to start service
ERROR_USER_NOT_STARTED, //!< user is not started
ERROR_USER_ALREADY_STARTED, //!< user has already started
ERROR_USER_NOT_UNLOCKED, //!< user is not unlocked
ERROR_USER_ALREADY_UNLOCKED, //!< user has already unlocked
ERROR_USER_NOT_LOCKED, //!< user is not locked
ERROR_IME_NOT_AVAILABLE, //!< input method engine is not available
ERROR_SECURITY_IME_NOT_AVAILABLE, //!< security input method engine is not available
ERROR_TOKEN_CREATE_FAILED, //!< failed to create window token
ERROR_TOKEN_DESTROY_FAILED, //!< failed to destroy window token
ERROR_IME_BIND_FAILED, //!< failed to bind IME service
ERROR_IME_UNBIND_FAILED, //!< failed to unbind IME service
ERROR_IME_START_FAILED, //!< failed to start IME service
ERROR_IME_STOP_FAILED, //!< failed to stop IME service
ERROR_KBD_SHOW_FAILED, //!< failed to show keyboard
ERROR_KBD_HIDE_FAILED, //!< failed to hide keyboard
ERROR_IME_NOT_STARTED, //!< input method service is not started
ERROR_KBD_IS_OCCUPIED, //!< keyboard is showing by other client
ERROR_KBD_IS_NOT_SHOWING, //!< keyboard is not showing
ERROR_IME_ALREADY_STARTED, //!< input method service has already started
ERROR_NOT_IME_PACKAGE, //!< not an IME package
ERROR_IME_PACKAGE_DUPLICATED, //!< duplicated IME package
ERROR_SETTING_SAME_VALUE, //!< same setting value
ERROR_NO_NEXT_IME, //!< no next ime is available
ERROR_CLIENTWINDOW_NOT_FOCUSED, //!< the input client window is not focused
ERROR_CLIENT_NOT_WINDOW, //!< the input client is not from a valid window
// error from ime
ERROR_REMOTE_IME_DIED, //!< remote input method service died abnormally
ERROR_RESTART_IME_FAILED, //!< failed to restart input method service
// error from client
ERROR_REMOTE_CLIENT_DIED, //!< remote client died abnormally
ERROR_CLIENT_DUPLICATED, //!< duplicated client
ERROR_CLIENT_NOT_FOUND, //!< client is not found
};
const char* ToString(int errorCode);
};
static constexpr HiviewDFX::HiLogLabel g_SMALL_SERVICES_LABEL = {
LOG_CORE,
0xD001C00,
"ImsaKit"
};
#define IMSA_HILOGD(fmt, ...) (void)OHOS::HiviewDFX::HiLog::Debug(OHOS::MiscServices::g_SMALL_SERVICES_LABEL, \
"line: %d, function: %s," fmt, __LINE__, __FUNCTION__, ##__VA_ARGS__)
#define IMSA_HILOGE(fmt, ...) (void)OHOS::HiviewDFX::HiLog::Error(OHOS::MiscServices::g_SMALL_SERVICES_LABEL, \
"line: %d, function: %s," fmt, __LINE__, __FUNCTION__, ##__VA_ARGS__)
#define IMSA_HILOGF(fmt, ...) (void)OHOS::HiviewDFX::HiLog::Fatal(OHOS::MiscServices::g_SMALL_SERVICES_LABEL, \
"line: %d, function: %s," fmt, __LINE__FILE__, __FUNCTION__, ##__VA_ARGS__)
#define IMSA_HILOGI(fmt, ...) (void)OHOS::HiviewDFX::HiLog::Info(OHOS::MiscServices::g_SMALL_SERVICES_LABEL, \
"line: %d, function: %s," fmt, __LINE__, __FUNCTION__, ##__VA_ARGS__)
#define IMSA_HILOGW(fmt, ...) (void)OHOS::HiviewDFX::HiLog::Warn(OHOS::MiscServices::g_SMALL_SERVICES_LABEL, \
"line: %d, function: %s," fmt, __LINE__, __FUNCTION__, ##__VA_ARGS__)
}
}
#endif // FM_IMMS_PROJECT_GLOBAL_H

View File

@ -0,0 +1,47 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_IINPUTCONTROLCHANNEL_H
#define FM_IMMS_PROJECT_IINPUTCONTROLCHANNEL_H
#include "iremote_broker.h"
#include "input_channel.h"
#include "i_input_method_agent.h"
#include "global.h"
namespace OHOS {
namespace MiscServices {
class IInputControlChannel : public IRemoteBroker {
public:
enum {
ON_AGENT_CREATED = FIRST_CALL_TRANSACTION,
HIDE_KEYBOARD_SELF,
ADVANCE_TO_NEXT,
SET_DISPLAY_MODE,
ON_KEYBOARD_SHOWED,
};
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.inputmethod.InputControlChannel");
virtual void onAgentCreated(sptr<IInputMethodAgent>& agent, InputChannel* channel) = 0;
virtual void hideKeyboardSelf(int flags) = 0;
virtual bool advanceToNext(bool isCurrentIme) = 0;
virtual void setDisplayMode(int mode) = 0;
virtual void onKeyboardShowed() = 0;
};
}
}
#endif // FM_IMMS_PROJECT_IINPUTCONTROLCHANNEL_H

View File

@ -0,0 +1,38 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_IINPUTMETHODAGENT_H
#define FM_IMMS_PROJECT_IINPUTMETHODAGENT_H
#include "iremote_broker.h"
#include "iremote_object.h"
#include "global.h"
namespace OHOS {
namespace MiscServices {
class IInputMethodProxy : public IRemoteBroker {
public:
enum {
DISPATCH_KEY = FIRST_CALL_TRANSACTION,
};
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.inputmethod.IInputMethodProxy");
virtual int32_t dispatchKey(int key, int status) = 0;
};
}
}
#endif // FM_IMMS_PROJECT_IINPUTMETHODAGENT_H

View File

@ -0,0 +1,67 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_IINPUTMETHODSYSTEMABILITY_H
#define FM_IMMS_PROJECT_IINPUTMETHODSYSTEMABILITY_H
#include <vector>
#include <errors.h>
#include "iremote_broker.h"
#include "i_input_client.h"
#include "i_input_data_channel.h"
#include "input_attribute.h"
#include "input_method_property.h"
#include "keyboard_type.h"
#include "global.h"
#include "message_parcel.h"
#include "i_input_method_core.h"
namespace OHOS {
namespace MiscServices {
class IInputMethodSystemAbility : public IRemoteBroker {
public:
enum {
PREPARE_INPUT = 0,
RELEASE_INPUT,
START_INPUT,
STOP_INPUT,
SET_INPUT_METHOD_CORE,
GET_DISPLAY_MODE,
GET_KEYBOARD_WINDOW_HEIGHT,
GET_CURRENT_KEYBOARD_TYPE,
LIST_INPUT_METHOD_ENABLED,
LIST_INPUT_METHOD,
LIST_KEYBOARD_TYPE,
};
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.inputmethod.IInputMethodSystemAbility");
virtual void prepareInput(MessageParcel& data) = 0;
virtual void releaseInput(MessageParcel& data) = 0;
virtual void startInput(MessageParcel& data) = 0;
virtual void stopInput(MessageParcel& data) = 0;
virtual int32_t setInputMethodCore(sptr<IInputMethodCore> &core)=0;
virtual int32_t getDisplayMode(int32_t *retMode) = 0;
virtual int32_t getKeyboardWindowHeight(int32_t *retHeight) = 0;
virtual int32_t getCurrentKeyboardType(KeyboardType* retType) = 0;
virtual int32_t listInputMethodEnabled(std::vector<InputMethodProperty*> *properties) = 0;
virtual int32_t listInputMethod(std::vector<InputMethodProperty*> *properties) = 0;
virtual int32_t listKeyboardType(const std::u16string& imeId, std::vector<KeyboardType*> *types) = 0;
};
}
}
#endif // FM_IMMS_PROJECT_IINPUTMETHODSYSTEMABILITY_H

View File

@ -0,0 +1,63 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_IPLATFORMAPI_H
#define FM_IMMS_PROJECT_IPLATFORMAPI_H
#include <vector>
#include <string>
#include "iremote_broker.h"
#include "ipc_types.h"
#include "i_platform_callback.h"
#include "input_method_property.h"
#include "input_method_setting.h"
#include "i_input_method_core.h"
#include "global.h"
namespace OHOS {
namespace MiscServices {
class IPlatformApi : public IRemoteBroker {
public:
enum {
REGISTER_CALLBACK = FIRST_CALL_TRANSACTION,
BIND_IMS,
UNBIND_IMS,
CREATE_WINDOW_TOKEN,
DESTROY_WINDOW_TOKEN,
LIST_INPUT_METHOD,
GET_INPUT_METHOD_PROPERTY,
GET_INPUT_METHOD_SETTING,
SET_INPUT_METHOD_SETTING,
};
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.inputmethod.IPlatformApi");
virtual int32_t registerCallback(const sptr<IPlatformCallback>& cb) = 0;
virtual sptr<IInputMethodCore> bindInputMethodService(const std::u16string& packageName,
const std::u16string& intention, int userId) = 0;
virtual int32_t unbindInputMethodService(int userId, const std::u16string& packageName) = 0;
virtual sptr<IRemoteObject> createWindowToken(int userId, int displayId, const std::u16string& packageName) = 0;
virtual int32_t destroyWindowToken(int userId, const std::u16string& packageName) = 0;
virtual int32_t listInputMethod(int userId, std::vector<InputMethodProperty*> *inputMethodProperties) = 0;
virtual int32_t getInputMethodProperty(int userId, const std::u16string& packageName,
InputMethodProperty *inputMethodProperty) = 0;
virtual int32_t getInputMethodSetting(int userId, InputMethodSetting *inputMethodSetting) = 0;
virtual int32_t setInputMethodSetting(int userId, const InputMethodSetting& inputMethodSetting) = 0;
};
}
}
#endif // FM_IMMS_PROJECT_IPLATFORMAPI_H

View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_IPLATFORMCALLBACK_H
#define FM_IMMS_PROJECT_IPLATFORMCALLBACK_H
#include <vector>
#include <string>
#include "iremote_broker.h"
#include "ipc_types.h"
#include "global.h"
namespace OHOS {
namespace MiscServices {
class IPlatformCallback : public IRemoteBroker {
public:
enum {
NOTIFY_EVENT = OHOS::FIRST_CALL_TRANSACTION,
};
DECLARE_INTERFACE_DESCRIPTOR(u"ohos.miscservices.inputmethod.IPlatformCallback");
virtual void notifyEvent(int eventId, int userId, const std::vector<std::u16string>& eventContent) = 0;
};
}
}
#endif // FM_IMMS_PROJECT_IPLATFORMCALLBACK_H

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_INPUTATTRIBUTE_H
#define FM_IMMS_PROJECT_INPUTATTRIBUTE_H
#include "parcel.h"
namespace OHOS {
namespace MiscServices {
class InputAttribute : public Parcelable {
public:
InputAttribute();
InputAttribute(const InputAttribute& attribute);
InputAttribute& operator=(const InputAttribute& attribute);
~InputAttribute();
virtual bool Marshalling(Parcel &parcel) const override;
static InputAttribute *Unmarshalling(Parcel &parcel);
void SetInputPattern(int32_t pattern);
bool GetSecurityFlag();
static const int32_t PATTERN_TEXT = 0x00000001;
static const int32_t PATTERN_PASSWORD = 0x00000007;
private:
int32_t inputPattern;
int32_t enterKeyType;
int32_t inputOption;
};
}
}
#endif // FM_IMMS_PROJECT_INPUTATTRIBUTE_H

View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT__INPUTCHANNEL_H
#define FM_IMMS_PROJECT__INPUTCHANNEL_H
#include "parcel.h"
#include "global.h"
#include "message_parcel.h"
#include <string>
namespace OHOS {
namespace MiscServices {
class InputChannel : public Parcelable{
public:
InputChannel();
~InputChannel();
virtual bool Marshalling(Parcel &parcel) const override;
static InputChannel *Unmarshalling(Parcel &parcel);
private:
std::u16string name;
MessageParcel inputChannelParcel;
InputChannel(const InputChannel& channel);
InputChannel& operator=(const InputChannel& channel);
};
}
}
#endif // INPUTMETHODSYSTEMSERVICE_INPUTCHANNEL_H

View File

@ -0,0 +1,46 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_INPUTCONTROLCHANNELPROXY_H
#define FM_IMMS_PROJECT_INPUTCONTROLCHANNELPROXY_H
#include "parcel.h"
#include "iremote_broker.h"
#include "message_parcel.h"
#include "message_handler.h"
#include "global.h"
#include "iremote_proxy.h"
#include "i_input_control_channel.h"
#include "i_input_method_agent.h"
namespace OHOS {
namespace MiscServices {
class InputControlChannelProxy : public IRemoteProxy<IInputControlChannel> {
public:
InputControlChannelProxy(const sptr<IRemoteObject> &impl);
~InputControlChannelProxy();
virtual void onAgentCreated(sptr<IInputMethodAgent>& agent, InputChannel* channel) override;
virtual void hideKeyboardSelf(int flags) override;
virtual bool advanceToNext(bool isCurrentIme) override;
virtual void setDisplayMode(int mode) override;
virtual void onKeyboardShowed() override;
};
}
}
#endif // FM_IMMS_PROJECT_INPUTCONTROLCHANNELPROXY_H

View File

@ -0,0 +1,59 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_INPUTCONTROLCHANNEL_SK_H
#define FM_IMMS_PROJECT_INPUTCONTROLCHANNEL_SK_H
#include "iremote_broker.h"
#include "iremote_stub.h"
#include "i_input_method_agent.h"
#include "input_channel.h"
#include <mutex>
#include <condition_variable>
#include "message_parcel.h"
#include "i_input_control_channel.h"
namespace OHOS {
namespace MiscServices {
class InputControlChannelStub : public IRemoteStub<IInputControlChannel> {
public:
explicit InputControlChannelStub(int userId);
virtual ~InputControlChannelStub();
virtual int OnRemoteRequest(uint32_t code,
MessageParcel &data,
MessageParcel &reply,
MessageOption &option) override;
virtual void onAgentCreated(sptr<IInputMethodAgent>& agent, InputChannel* channel) override;
virtual void hideKeyboardSelf(int flags) override;
virtual bool advanceToNext(bool isCurrentIme) override;
virtual void setDisplayMode(int mode) override;
virtual void onKeyboardShowed() override;
void ResetFlag();
bool GetAgentAndChannel(sptr<IInputMethodAgent>* retAgent, InputChannel** retChannel);
bool WaitKeyboardReady();
private:
int userId_;
sptr<IInputMethodAgent> agent = nullptr;
InputChannel* channel = nullptr;
std::mutex mtx;
std::condition_variable cv;
bool agentReadyFlag = false;
bool keyboardReadyFlag = false;
};
}
}
#endif // FM_IMMS_PROJECT_INPUTCONTROLCHANNEL_SK_H

View File

@ -0,0 +1,46 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef SERVICES_INPUTMETHODABILITYCONNECTIONSTUB_H
#define SERVICES_INPUTMETHODABILITYCONNECTIONSTUB_H
#include "ability_connect_callback_stub.h"
#include "want.h"
#include "element_name.h"
#include "message_handler.h"
#include "iremote_object.h"
#include "global.h"
namespace OHOS {
namespace MiscServices {
class InputMethodAbilityConnectionStub : public AAFwk::AbilityConnectionStub {
public:
enum MessageID {
MSG_ID_ABILITY_CONNECT_DONE = 1,
MSG_ID_ABILITY_DISCONNECT_DONE,
};
InputMethodAbilityConnectionStub(const int index);
~InputMethodAbilityConnectionStub();
void OnAbilityConnectDone(const AppExecFwk::ElementName &element, const sptr<IRemoteObject> &remoteObject, int resultCode) override;
void OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode) override;
void SetHandler(MessageHandler* handler);
private:
MessageHandler* messageHandler;
int mIndex;
};
}
}
#endif // SERVICES_INPUTMETHODABILITYCONNECTIONSTUB_H

View File

@ -0,0 +1,44 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_INPUTMETHODPROPERTY_H
#define FM_IMMS_PROJECT_INPUTMETHODPROPERTY_H
#include <vector>
#include "parcel.h"
#include <string>
#include "keyboard_type.h"
namespace OHOS {
namespace MiscServices {
class InputMethodProperty : public Parcelable {
public:
std::u16string mImeId;
std::u16string mPackageName;
std::u16string mAbilityName;
std::u16string mConfigurationPage;
bool isSystemIme;
int32_t mDefaultImeId;
std::vector<KeyboardType*> mTypes;
InputMethodProperty();
~InputMethodProperty();
InputMethodProperty(const InputMethodProperty& property);
InputMethodProperty& operator=(const InputMethodProperty& property);
virtual bool Marshalling(Parcel &parcel) const override;
static InputMethodProperty *Unmarshalling(Parcel &parcel);
};
}
}
#endif // FM_IMMS_PROJECT_INPUTMETHODPROPERTY_H

View File

@ -0,0 +1,73 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_INPUTMETHODSETTING_H
#define FM_IMMS_PROJECT_INPUTMETHODSETTING_H
#include <map>
#include <vector>
#include "global.h"
#include "parcel.h"
#include "string.h"
namespace OHOS {
namespace MiscServices {
class InputMethodSetting : public Parcelable {
public:
const static std::u16string CURRENT_INPUT_METHOD_TAG; //!< the item name of 'default IME' in the system setting
const static std::u16string ENABLED_INPUT_METHODS_TAG; //!< the item name of 'enabled IME list' in the system setting
const static std::u16string CURRENT_KEYBOARD_TYPE_TAG; //!< the item name of 'default keyboard type' in the system setting
const static std::u16string CURRENT_SYS_KEYBOARD_TYPE_TAG;
//!< the item name of 'default keyboard type for security IME in the system setting
const static std::u16string SYSTEM_LOCALE_TAG; //!< the item name of locale list supported in the system
InputMethodSetting();
~InputMethodSetting();
InputMethodSetting(const InputMethodSetting& inputMethodSetting);
InputMethodSetting& operator=(const InputMethodSetting& inputMethodSetting);
void SetValue(const std::u16string& key, const std::u16string& value);
std::u16string GetValue(const std::u16string& key) const;
std::u16string GetCurrentInputMethod() const;
void SetCurrentInputMethod(const std::u16string& imeId);
std::vector<std::u16string> GetEnabledInputMethodList();
bool AddEnabledInputMethod(const std::u16string& imeId, const std::vector<int32_t>& types);
bool RemoveEnabledInputMethod(const std::u16string& imdId);
std::vector<int32_t> GetEnabledKeyboardTypes(const std::u16string& imeId);
int32_t GetCurrentKeyboardType();
void SetCurrentKeyboardType(int32_t type);
int32_t GetCurrentSysKeyboardType();
void SetCurrentSysKeyboardType(int32_t type);
void ClearData();
bool FindKey(const std::u16string& key) const;
virtual bool Marshalling(Parcel &parcel) const override;
static InputMethodSetting *Unmarshalling(Parcel &parcel);
private:
std::map<std::u16string, std::u16string> setting;
const char16_t DELIM_IME = ':';
const char16_t DELIM_KBD_TYPE = ';';
std::vector<std::u16string> Split(const std::u16string& str, char16_t delim);
std::u16string BuildString(const std::vector<std::u16string>& vector, char16_t delim);
};
}
}
#endif // FM_IMMS_PROJECT_INPUTMETHODSETTING_H

View File

@ -0,0 +1,94 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_INPUTMETHODSYSTEMABILITY_H
#define FM_IMMS_PROJECT_INPUTMETHODSYSTEMABILITY_H
#include <thread>
#include <map>
#include "system_ability.h"
#include "input_method_system_ability_stub.h"
#include "peruser_setting.h"
#include "peruser_session.h"
#include "event_handler.h"
#include "input_method_ability.h"
namespace OHOS {
namespace MiscServices {
enum class ServiceRunningState {
STATE_NOT_START,
STATE_RUNNING
};
class InputMethodSystemAbility : public SystemAbility, public InputMethodSystemAbilityStub {
DECLARE_SYSTEM_ABILITY(InputMethodSystemAbility);
public:
DISALLOW_COPY_AND_MOVE(InputMethodSystemAbility);
InputMethodSystemAbility(int32_t systemAbilityId, bool runOnCreate);
InputMethodSystemAbility();
~InputMethodSystemAbility();
static sptr<InputMethodSystemAbility> GetInstance();
int32_t GetUserState(int32_t userId);
int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
virtual int32_t getDisplayMode(int32_t *retMode) override;
virtual int32_t getKeyboardWindowHeight(int32_t *retHeight) override;
virtual int32_t getCurrentKeyboardType(KeyboardType* retType) override;
virtual int32_t listInputMethodEnabled(std::vector<InputMethodProperty*> *properties) override;
virtual int32_t listInputMethod(std::vector<InputMethodProperty*> *properties) override;
virtual int32_t listKeyboardType(const std::u16string& imeId, std::vector<KeyboardType*> *types) override;
int32_t dump(int32_t fd, const std::vector<std::u16string>& args);
virtual int32_t setInputMethodCore(sptr<IInputMethodCore> &core) override;
protected:
void OnStart() override;
void OnStop() override;
private:
int32_t Init();
void Initialize();
std::thread workThreadHandler; /*!< thread handler of the WorkThread */
std::map<int32_t, PerUserSetting*> userSettings;
std::map<int32_t, PerUserSession*> userSessions;
std::map<int32_t, MessageHandler*> msgHandlers;
void WorkThread();
PerUserSetting* GetUserSetting(int32_t userId);
PerUserSession* GetUserSession(int32_t userId);
int32_t OnUserStarted(const Message* msg);
int32_t OnUserStopped(const Message* msg);
int32_t OnUserUnlocked(const Message* msg);
int32_t OnUserLocked(const Message* msg);
int32_t OnPrepareInput(Message* msg);
int32_t OnHandleMessage(Message* msg);
int32_t OnRemotePeerDied(const Message* msg);
int32_t OnSettingChanged(const Message* msg);
int32_t OnPackageRemoved(const Message* msg);
int32_t OnPackageAdded(const Message* msg);
int32_t OnDisableIms(const Message* msg);
int32_t OnAdvanceToNext(const Message* msg);
ServiceRunningState state_;
sptr<InputMethodAbility> inputMethodAbility_;
void InitServiceHandler();
static std::mutex instanceLock_;
static sptr<InputMethodSystemAbility> instance_;
static std::shared_ptr<AppExecFwk::EventHandler> serviceHandler_;
};
}
}
#endif // FM_IMMS_PROJECT_INPUTMETHODSYSTEMABILITY_H

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_INPUTMETHODSYSTEMABILITY_SK_H
#define FM_IMMS_PROJECT_INPUTMETHODSYSTEMABILITY_SK_H
#include <errors.h>
#include "refbase.h"
#include "i_input_method_system_ability.h"
#include "iremote_stub.h"
#include "global.h"
#include "message_parcel.h"
namespace OHOS {
namespace MiscServices {
class InputMethodSystemAbilityStub : public IRemoteStub<IInputMethodSystemAbility> {
public:
int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
virtual void prepareInput(MessageParcel& data) override;
virtual void releaseInput(MessageParcel& data) override;
virtual void startInput(MessageParcel& data) override;
virtual void stopInput(MessageParcel& data) override;
void setInputMethodCoreFromHap(MessageParcel& data);
protected:
int32_t getUserId(int32_t uid);
};
}
}
#endif // FM_IMMS_PROJECT_INPUTMETHODSYSTEMABILITY_SK_H

View File

@ -0,0 +1,63 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_KEYBOARDTYPE_H
#define FM_IMMS_PROJECT_KEYBOARDTYPE_H
#include <vector>
#include "parcel.h"
#include <string>
namespace OHOS {
namespace MiscServices {
class KeyboardType : public Parcelable {
public:
KeyboardType();
KeyboardType(const KeyboardType& type);
~KeyboardType();
KeyboardType& operator=(const KeyboardType& type);
virtual bool Marshalling(Parcel &parcel) const override;
static KeyboardType *Unmarshalling(Parcel &parcel);
void setId(int32_t typeId);
void setLabelId(int32_t labelId);
void setIconId(int32_t iconId);
void setAsciiCapability(bool isAsciiCapable);
void setLanguage(std::u16string language);
void setInputSource(std::u16string inputSource);
void setCustomizedValue(std::u16string keyBoardTypeCustomizedValue);
int32_t getId() const;
int32_t getLabelId() const;
int32_t getIconId() const;
int32_t getHashCode() const;
std::u16string getLanguage() const;
std::u16string getInputSource() const;
std::u16string getCustomizedValue() const;
bool supportsAscii();
private:
int32_t mId;
int32_t mHashCode;
int32_t mLabelId;
int32_t mIconId;
bool mIsAsciiCapable;
std::u16string mLanguage;
std::u16string mInputSource;
std::u16string mCustomizedValue;
const int32_t ID_NONE = 0;
};
}
}
#endif // FM_IMMS_PROJECT_KEYBOARDTYPE_H

View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*! \file MessageHandler.h */
#ifndef FM_IMMS_PROJECT_MESSAGE_H
#define FM_IMMS_PROJECT_MESSAGE_H
#include "global.h"
#include "message_parcel.h"
namespace OHOS {
namespace MiscServices {
class Message {
public:
int32_t msgId_; //!< message id
MessageParcel *msgContent_ = nullptr; //!< message content
Message(int32_t msgId, MessageParcel* msgContent);
explicit Message(const Message& msg);
Message& operator= (const Message& msg);
~Message();
private:
Message(const Message&&);
Message& operator= (const Message&&);
};
}
}
#endif // FM_IMMS_PROJECT_MESSAGE_H

View File

@ -0,0 +1,100 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*! \file MessageHandler.h */
#ifndef FM_IMMS_PROJECT_MESSAGEHANDLER_H
#define FM_IMMS_PROJECT_MESSAGEHANDLER_H
#include <queue>
#include <mutex>
#include <condition_variable>
#include "global.h"
#include "message_parcel.h"
#include "message.h"
namespace OHOS {
namespace MiscServices {
namespace MessageID {
enum {
// for system broadcast
MSG_ID_SYSTEM_START = 0, //!< system started
MSG_ID_SYSTEM_STOP, //!< system stopped
MSG_ID_USER_START, //!< a user started
MSG_ID_USER_STOP, //!< a user stopped
MSG_ID_USER_UNLOCK, //!< a user unlocked
MSG_ID_USER_LOCK, //!< a user locked
MSG_ID_PACKAGE_ADDED, //!< a package is installed
MSG_ID_PACKAGE_REMOVED, //!< a package is removed
MSG_ID_SETTING_CHANGED, //!< input method setting is changed
// the request from client
MSG_ID_PREPARE_INPUT, //!< prepare input
MSG_ID_START_INPUT, //!< start input
MSG_ID_STOP_INPUT, //!< stop input
MSG_ID_RELEASE_INPUT, //!< release input
MSG_ID_SET_INPUT_METHOD_CORE,
// the request to handle the condition that the remote object died
MSG_ID_CLIENT_DIED, //!< input client died
MSG_ID_IMS_DIED, //!< input method service died
MSG_ID_DISABLE_IMS, //!< disable input method service
MSG_ID_RESTART_IMS, //!< restart input method service
MSG_ID_HIDE_KEYBOARD_SELF, //!< hide the current keyboard
MSG_ID_ADVANCE_TO_NEXT, //!< switch to next
MSG_ID_SET_DISPLAY_MODE, //!< set display mode
MSG_ID_SHELL_COMMAND, //!< shell command
MSG_ID_EXIT_SERVICE, //!< exit service
//the request from IMSA to IMC
MSG_ID_INSERT_CHAR,
MSG_ID_DELETE_BACKWARD,
MSG_ID_CLOSE,
MSG_ID_ON_INPUT_READY,
// the request from IMSA to IMA
MSG_ID_SHOW_KEYBOARD, //
MSG_ID_INITIALIZE_INPUT, //
MSG_ID_HIDE_KEYBOARD, //
MSG_ID_SET_KEYBOARD_TYPE,
MSG_ID_GET_KEYBOARD_WINDOW_HEIGHT,
// the request from IMC to IMA
MSG_ID_DISPATCH_KEY,//!< dispatch key from PhysicalKbd
};
}
class MessageHandler {
public:
MessageHandler();
~MessageHandler();
void SendMessage(Message* msg);
Message* GetMessage();
static MessageHandler* Instance();
private:
std::mutex mMutex; //!< a mutex to guard message queue
std::condition_variable mCV; //!< condition variable to work with mMutex
std::queue<Message*> mQueue ;//!< Message queue, guarded by mMutex;
MessageHandler(const MessageHandler&);
MessageHandler& operator= (const MessageHandler&);
MessageHandler(const MessageHandler&&);
MessageHandler& operator= (const MessageHandler&&);
};
}
}
#endif // FM_IMMS_PROJECT_MESSAGEHANDLER_H

View File

@ -0,0 +1,196 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_PERUSERSESSION_H
#define FM_IMMS_PROJECT_PERUSERSESSION_H
#include <thread>
#include <mutex>
#include <map>
#include <memory>
#include "iremote_object.h"
#include "i_input_control_channel.h"
#include "i_input_client.h"
#include "i_input_method_core.h"
#include "i_input_data_channel.h"
#include "i_input_method_agent.h"
#include "input_attribute.h"
#include "input_method_property.h"
#include "input_method_setting.h"
#include "input_control_channel_stub.h"
#include "message.h"
#include "message_handler.h"
#include "global.h"
#include "platform.h"
#include "keyboard_type.h"
#include "ability_manager_interface.h"
#include "ability_connect_callback_proxy.h"
#include "input_method_ability.h"
namespace OHOS {
namespace MiscServices {
class RemoteObjectDeathRecipient : public IRemoteObject::DeathRecipient {
public:
RemoteObjectDeathRecipient(int userId, int msgId);
~RemoteObjectDeathRecipient();
void OnRemoteDied(const wptr<IRemoteObject>& who) override;
private :
int userId_; //!< the id of the user to whom the object is linking
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
sptr<IInputDataChannel> channel; //!< the remote object handler for input method service callback to input client
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;
};
};
/*! \class PerUserSession
\brief The class provides session management in input method management service
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
};
public:
explicit PerUserSession(int userId);
~PerUserSession();
void SetCurrentIme(InputMethodProperty* ime);
void SetSecurityIme(InputMethodProperty* ime);
void SetInputMethodSetting(InputMethodSetting* setting);
void ResetIme(InputMethodProperty* defaultIme, InputMethodProperty* securityIme);
void OnPackageRemoved(const std::u16string& packageName);
int GetDisplayMode();
int GetKeyboardWindowHeight(int *retHeight);
KeyboardType* GetCurrentKeyboardType();
int OnSettingChanged(const std::u16string& key, const std::u16string& value);
void Dump(int fd);
void CreateWorkThread(MessageHandler& handler);
void JoinWorkThread();
void SetInputMethodAbility(sptr<InputMethodAbility> &inputMethodAbility);
static void BindInputAbility();
private:
int userId_; //!< the id of the user to whom the object is linking
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; //!< a map to manage the input clients connected to the service
/*!< \n key is the remote IInputClient handler
\n value is an object of an ClientInfo */
InputMethodProperty* currentIme[MAX_IME]; //!< 0 - the default ime. 1 - security ime
/*!< \n The pointers are referred to the objects in the PerUserSetting */
InputControlChannelStub* localControlChannel[MAX_IME]; //!< inputControlChannel object used by the local process
sptr<IInputControlChannel> inputControlChannel[MAX_IME]; //!< channels between the service and input method service
sptr<IInputMethodCore> imsCore[MAX_IME]; //!< the remote handlers of input method service
sptr<IRemoteObject> inputMethodToken[MAX_IME]; //!< the window token of keyboard
int currentKbdIndex[MAX_IME]; //!< current keyboard index
int lastImeIndex; //!< The last ime which showed keyboard
InputMethodSetting* inputMethodSetting; //!< The pointer referred to the object in PerUserSetting
int currentDisplayMode; //!< the display mode of the current keyboard
sptr<IInputMethodAgent> imsAgent;
InputChannel* imsChannel; //!< the write channel created by input method service
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; //!< remote object death monitor for input method service
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;
sptr<InputMethodAbility> inputMethodAbility_;
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);
void DumpClientInfo(int fd, const ClientInfo& clientInfo);
void DumpCurrentSession(int fd);
void CopyInputMethodService(int imeIndex);
ClientInfo* GetClientInfo(const sptr<IInputClient>& inputClient);
void WorkThread();
void OnPrepareInput(Message* msg);
void OnReleaseInput(Message* msg);
void OnStartInput(Message* msg);
void OnStopInput(Message* msg);
void OnClientDied(const wptr<IRemoteObject>& who);
void OnImsDied(const wptr<IRemoteObject>& who);
void OnHideKeyboardSelf(int flags);
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 StartInputMethod(int index);
int StopInputMethod(int index);
int ShowKeyboard(const sptr<IInputClient>& inputClient);
int HideKeyboard(const sptr<IInputClient>& inputClient);
void SetDisplayId(int displayId);
int GetImeIndex(const sptr<IInputClient>& inputClient);
static sptr<AAFwk::IAbilityManager> GetAbilityManagerService();
void onSetInputMethodCore(Message* msg);
};
}
}
#endif // FM_IMMS_PROJECT_PERUSERSESSION_H

View File

@ -0,0 +1,73 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_PERUSERSETTING_H
#define FM_IMMS_PROJECT_PERUSERSETTING_H
#include <map>
#include <string>
#include <vector>
#include "input_method_property.h"
#include "input_method_setting.h"
#include "global.h"
namespace OHOS {
namespace MiscServices {
class PerUserSetting {
public:
explicit PerUserSetting(int32_t userId);
~PerUserSetting();
void Initialize();
int32_t GetUserState();
InputMethodProperty* GetCurrentInputMethod();
InputMethodProperty* GetSecurityInputMethod();
InputMethodProperty* GetNextInputMethod();
InputMethodSetting* GetInputMethodSetting();
InputMethodProperty* GetInputMethodProperty(const std::u16string& imeId);
int32_t OnPackageAdded(std::u16string& packageName, bool* isSecurityIme = nullptr);
int32_t OnPackageRemoved(std::u16string& packageName, bool* isSecurityIme = nullptr);
int32_t OnSettingChanged(const std::u16string& key, const std::u16string& value);
void OnAdvanceToNext();
void OnUserLocked();
void Dump(int32_t fd);
int32_t ListInputMethodEnabled(std::vector<InputMethodProperty*> *properties);
int32_t ListInputMethod(std::vector<InputMethodProperty*> *properties);
int32_t ListKeyboardType(const std::u16string& imeId, std::vector<KeyboardType*> *types);
static bool CheckIfSecurityIme(const InputMethodProperty& property);
private:
int32_t userId_; //!< the id of the user to whom the object is linking
int32_t userState; //!< the state of the user to whom the object is linking
std::vector<InputMethodProperty*> inputMethodProperties; //!< a vector to save all IME installed for this user
std::u16string currentImeId; //!< the id of the default input method engine.
InputMethodSetting inputMethodSetting; //!< the object to manage the setting data for this user
PerUserSetting(const PerUserSetting&);
PerUserSetting& operator= (const PerUserSetting&);
PerUserSetting(const PerUserSetting&&);
PerUserSetting& operator= (const PerUserSetting&&);
void InitInputMethodSetting();
void ResetCurrentInputMethod();
std::u16string GetKeyboardTypeLanguage(const InputMethodProperty* property, int32_t hashCode);
std::u16string GetImeId(const std::u16string& packageName);
};
}
}
#endif // FM_IMMS_PROJECT_PERUSERSETTING_H

View File

@ -0,0 +1,66 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_PLATFORMAPI_H
#define FM_IMMS_PROJECT_PLATFORMAPI_H
#include <vector>
#include <string>
#include <memory>
#include "iremote_broker.h"
#include "iremote_object.h"
#include "i_platform_api.h"
#include "i_input_method_core.h"
#include "input_method_property.h"
#include "input_method_setting.h"
namespace OHOS {
namespace MiscServices {
class Platform {
public:
static Platform* Instance();
void SetPlatform(const sptr<IPlatformApi>& platformApi);
sptr<IInputMethodCore> BindInputMethodService(int userId, const std::u16string& packageName, const std::u16string& intention);
int UnbindInputMethodService(int userId, const std::u16string& packageName);
sptr<IRemoteObject> CreateWindowToken(int userId, int displayId, const std::u16string& packageName);
int DestroyWindowToken(int userId, const std::u16string& packageName);
int ListInputMethod(int userId, std::vector<InputMethodProperty*>* inputMethodProperties);
int GetInputMethodProperty(int userId, const std::u16string& packageName, InputMethodProperty* inputMethodProperty);
int GetInputMethodSetting(int userId, InputMethodSetting* inputMethodSetting);
int SetInputMethodSetting(int userId, const InputMethodSetting& inputMethodSetting);
bool CheckPhysicalKeyboard();
bool IsValidWindow(int uid, int pid, int displayId);
bool IsWindowFocused(int uid, int pid, int displayId);
static inline sptr<IRemoteObject> RemoteBrokerToObject(const sptr<IRemoteBroker>& broker)
{
return broker->AsObject();
}
private:
sptr<IPlatformApi> platformApi;
Platform();
~Platform();
Platform(const Platform&);
Platform& operator = (const Platform&);
Platform(const Platform&&);
Platform& operator = (const Platform&&);
};
}
}
#endif // FM_IMMS_PROJECT_PLATFORMAPI_H

View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef FM_IMMS_PROJECT_PLATFORMCALLBACK_SK_H
#define FM_IMMS_PROJECT_PLATFORMCALLBACK_SK_H
#include <string>
#include "iremote_stub.h"
#include "message_option.h"
#include "message_parcel.h"
#include "i_platform_callback.h"
namespace OHOS {
namespace MiscServices {
class PlatformCallbackStub : public IRemoteStub<IPlatformCallback> {
public:
PlatformCallbackStub();
~PlatformCallbackStub();
virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override;
virtual void notifyEvent(int eventId, int userId, const std::vector<std::u16string>& eventContent) override;
};
}
}
#endif // FM_IMMS_PROJECT_PLATFORMCALLBACK_SK_H

40
services/include/utils.h Normal file
View File

@ -0,0 +1,40 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*! \file utils.h */
#ifndef FM_IMMS_PROJECT_UTILS_H
#define FM_IMMS_PROJECT_UTILS_H
#include <string>
#include <codecvt>
#include <locale>
#include <iostream>
namespace OHOS {
namespace MiscServices {
class Utils {
public:
static std::string to_utf8( std::u16string str16 ) {
return std::wstring_convert< std::codecvt_utf8_utf16<char16_t>, char16_t >{}.to_bytes(str16);
}
static std::u16string to_utf16( std::string str ) {
return std::wstring_convert< std::codecvt_utf8_utf16<char16_t>, char16_t >{}.from_bytes(str);
}
};
}
}
#endif

223
services/src/global.cpp Normal file
View File

@ -0,0 +1,223 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdio.h>
#include "global.h"
namespace OHOS {
namespace MiscServices {
void LogTimeStamp()
{
struct timeval tv;
gettimeofday(&tv, nullptr);
struct tm nowTime;
localtime_r(&tv.tv_sec, &nowTime);
printf("%02d-%02d %02d:%02d:%02d.%03d\t", nowTime.tm_mon, nowTime.tm_mday,
nowTime.tm_hour, nowTime.tm_min, nowTime.tm_sec, (int)tv.tv_usec/1000);
}
namespace ErrorCode {
const char* ToString(int errorCode)
{
switch (errorCode) {
case NO_ERROR: {
return "no error";
}
case ERROR_NULL_POINTER: {
return "null pointer";
}
case ERROR_BAD_PARAMETERS: {
return "bad parameters";
}
case ERROR_SERVICE_START_FAILED: {
return "failed to start service";
}
case ERROR_USER_NOT_STARTED: {
return "user has not started";
}
case ERROR_USER_ALREADY_STARTED: {
return "user has already started";
}
case ERROR_USER_NOT_UNLOCKED: {
return "user has not unlocked";
}
case ERROR_USER_ALREADY_UNLOCKED: {
return "user has already unlocked";
}
case ERROR_USER_NOT_LOCKED: {
return "user has not locked";
}
case ERROR_IME_NOT_AVAILABLE: {
return "input method engine is not available";
}
case ERROR_SECURITY_IME_NOT_AVAILABLE: {
return "security input method engine is not available";
}
case ERROR_TOKEN_CREATE_FAILED: {
return "failed to create token";
}
case ERROR_TOKEN_DESTROY_FAILED: {
return "failed to destroy token";
}
case ERROR_IME_BIND_FAILED: {
return "failed to bind service";
}
case ERROR_IME_UNBIND_FAILED: {
return "failed to unbind service";
}
case ERROR_IME_START_FAILED: {
return "failed to start input";
}
case ERROR_IME_STOP_FAILED: {
return "failed to stop input";
}
case ERROR_KBD_SHOW_FAILED: {
return "failed to show keyboard";
}
case ERROR_KBD_HIDE_FAILED: {
return "failed to hide keyboard";
}
case ERROR_IME_NOT_STARTED: {
return "input method service has not started";
}
case ERROR_KBD_IS_OCCUPIED: {
return "keyboard is showing by another client";
}
case ERROR_KBD_IS_NOT_SHOWING: {
return "keyboard is not showing";
}
case ERROR_IME_ALREADY_STARTED: {
return "input method service has already started";
}
case ERROR_NOT_IME_PACKAGE: {
return "not an input method engine package";
}
case ERROR_IME_PACKAGE_DUPLICATED: {
return "duplicated input method engine package";
}
case ERROR_SETTING_SAME_VALUE: {
return "same setting value";
}
case ERROR_NO_NEXT_IME: {
return "next input method engine is not available";
}
case ERROR_CLIENTWINDOW_NOT_FOCUSED: {
return "input client window is not focused";
}
case ERROR_CLIENT_NOT_WINDOW: {
return "input client is not from a valid window";
}
case ERROR_REMOTE_IME_DIED: {
return "input method service died";
}
case ERROR_RESTART_IME_FAILED: {
return "failed to restart input method service";
}
case ERROR_REMOTE_CLIENT_DIED: {
return "input client died";
}
case ERROR_CLIENT_DUPLICATED: {
return "duplicated client";
}
case ERROR_CLIENT_NOT_FOUND: {
return "client is not found";
}
case ERROR_STATUS_UNKNOWN_ERROR: {
return "unknown error";
}
case ERROR_STATUS_NO_MEMORY: {
return "no memory";
}
case ERROR_STATUS_INVALID_OPERATION: {
return "invalid operation";
}
case ERROR_STATUS_BAD_VALUE: {
return "bad value";
}
case ERROR_STATUS_BAD_TYPE: {
return "bad type";
}
case ERROR_STATUS_NAME_NOT_FOUND: {
return "name not found";
}
case ERROR_STATUS_PERMISSION_DENIED: {
return "permission denied";
}
case ERROR_STATUS_NO_INIT: {
return "no init";
}
case ERROR_STATUS_ALREADY_EXISTS: {
return "already exists";
}
case ERROR_STATUS_DEAD_OBJECT: {
return "dead object";
}
case ERROR_STATUS_FAILED_TRANSACTION: {
return "failed transaction";
}
case ERROR_STATUS_BAD_INDEX: {
return "bad index";
}
case ERROR_STATUS_NOT_ENOUGH_DATA: {
return "not enough data";
}
case ERROR_STATUS_WOULD_BLOCK: {
return "would block";
}
case ERROR_STATUS_TIMED_OUT: {
return "time out";
}
case ERROR_STATUS_UNKNOWN_TRANSACTION: {
return "unknown transaction";
}
case ERROR_STATUS_FDS_NOT_ALLOWED: {
return "fds not allowed";
}
case ERROR_STATUS_UNEXPECTED_NULL: {
return "unexpected null";
}
case ERROR_EX_ILLEGAL_ARGUMENT: {
return "illegal argument exception";
}
case ERROR_EX_NULL_POINTER: {
return "null pointer exception";
}
case ERROR_EX_ILLEGAL_STATE: {
return "illegal state exception";
}
case ERROR_EX_NETWORK_MAIN_THREAD: {
return "network main thread exception";
}
case ERROR_EX_UNSUPPORTED_OPERATION: {
return "unsupported operation exception";
}
case ERROR_EX_SERVICE_SPECIFIC: {
return "service specific exception";
}
case ERROR_EX_PARCELABLE: {
return "parcelable exception";
}
default: {
return "error is out of definition";
}
}
return "error is out of definition";
};
}
}
}

View File

@ -0,0 +1,105 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "input_attribute.h"
namespace OHOS {
namespace MiscServices {
/*! Constructor
*/
InputAttribute::InputAttribute() : enterKeyType(0), inputOption(0)
{
}
/*! Constructor
\param attribute the source attribute copied to this instance
*/
InputAttribute::InputAttribute(const InputAttribute& attribute)
{
inputPattern = attribute.inputPattern;
enterKeyType = attribute.enterKeyType;
inputOption = attribute.inputOption;
}
/*! Destructor
*/
InputAttribute::~InputAttribute()
{
}
/*! operator=
\param attribute the source attribute copied to this instance
\return return this
*/
InputAttribute& InputAttribute::operator=(const InputAttribute& attribute)
{
if (this == &attribute) {
return *this;
}
inputPattern = attribute.inputPattern;
enterKeyType = attribute.enterKeyType;
inputOption = attribute.inputOption;
return *this;
}
/*! Write InputAttribute to parcel
\param[out] parcel write the data of InputAttribute to this parcel returned to caller
\return ErrorCode::NO_ERROR
\return ErrorCode::ERROR_NULL_POINTER parcel is null
*/
bool InputAttribute::Marshalling(OHOS::Parcel &parcel) const {
if (!(parcel.WriteInt32(inputPattern)
&& parcel.WriteInt32(enterKeyType)
&& parcel.WriteInt32(inputOption)))
return false;
return true;
}
/*! Read InputAttribute from parcel
\param parcel read the data of InputAttribute from this parcel
\return ErrorCode::NO_ERROR
\return ErrorCode::ERROR_NULL_POINTER parcel is null
*/
InputAttribute* InputAttribute::Unmarshalling(OHOS::Parcel &parcel) {
auto info = new InputAttribute();
info->inputPattern = parcel.ReadInt32();
info->enterKeyType = parcel.ReadInt32();
info->inputOption = parcel.ReadInt32();
return info;
}
/*! Get the security flag
\return true - It's password EditView. The input method management service should start system
security input method engine for this view.
\return false - It's an normal view.
*/
bool InputAttribute::GetSecurityFlag()
{
if (inputPattern == PATTERN_PASSWORD) {
return true;
}
return false;
}
/*! Set input pattern.
\n It's added for Unit test of PerUserSession
\param pattern PATTERN_PASSWORD or 0.
*/
void InputAttribute::SetInputPattern(int32_t pattern)
{
inputPattern = pattern;
}
}
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "input_channel.h"
#include "input_attribute.h"
#include "global.h"
namespace OHOS {
namespace MiscServices {
/*! Constructor
*/
InputChannel::InputChannel()
{
}
/*! Destructor
*/
InputChannel::~InputChannel()
{
}
/*! Write InputChannel to parcel
\param[out] parcel the data of InputChannel is written to this parcel returned to caller
\return ErrorCode::NO_ERROR
\return ErrorCode::ERROR_NULL_POINTER parcel is null
*/
bool InputChannel::Marshalling(Parcel &parcel) const {
parcel.ParseFrom(inputChannelParcel.GetData(), inputChannelParcel.GetDataSize());
return NO_ERROR;
}
/*! Get InputChannel from parcel
\param parcel get the data of InputChannel from this parcel
\return ErrorCode::NO_ERROR
\return ErrorCode::ERROR_NULL_POINTER parcel is null
*/
InputChannel* InputChannel::Unmarshalling(Parcel &parcel) {
auto inputChannel = new InputChannel();
inputChannel->inputChannelParcel.RewindRead(0);
inputChannel->inputChannelParcel.ParseFrom(parcel.GetData(), parcel.GetDataSize());
inputChannel->inputChannelParcel.RewindRead(0);
inputChannel->name = inputChannel->inputChannelParcel.ReadString16();
inputChannel->inputChannelParcel.RewindRead(0);
return inputChannel;
}
}
}

View File

@ -0,0 +1,105 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "parcel.h"
#include "iremote_broker.h"
#include "message_parcel.h"
#include "message_handler.h"
#include "global.h"
#include "iremote_proxy.h"
#include "i_input_control_channel.h"
#include "i_input_method_agent.h"
#include "input_control_channel_proxy.h"
/*! \class InputControlChannelProxy
\brief The proxy implementation of IInputControlChannel
This class should be implemented by input method service
*/
namespace OHOS {
namespace MiscServices {
InputControlChannelProxy::InputControlChannelProxy(const sptr<IRemoteObject> &impl) : IRemoteProxy<IInputControlChannel>(impl) {
}
InputControlChannelProxy::~InputControlChannelProxy()
{
}
void InputControlChannelProxy::onAgentCreated(sptr<IInputMethodAgent> &agent, InputChannel* channel)
{
IMSA_HILOGI("InputControlChannelProxy::onAgentCreated start.");
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteRemoteObject(agent->AsObject());
if (channel == nullptr) {
data.WriteInt32(0);
} else {
data.WriteInt32(1);
data.WriteParcelable(channel);
}
Remote()->SendRequest(ON_AGENT_CREATED, data, reply, option);
IMSA_HILOGI("InputMethodCoreStub::onAgentCreated end.");
}
void InputControlChannelProxy::hideKeyboardSelf(int flags)
{
IMSA_HILOGI("InputControlChannelProxy::hideKeyboardSelf");
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteInt32(flags);
Remote()->SendRequest(HIDE_KEYBOARD_SELF, data, reply, option);
}
bool InputControlChannelProxy::advanceToNext(bool isCurrentIme)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteBool(isCurrentIme);
Remote()->SendRequest(MessageID::MSG_ID_ADVANCE_TO_NEXT, data, reply, option);
IMSA_HILOGI("InputControlChannelProxy::advanceToNext.");
return true;
}
void InputControlChannelProxy::setDisplayMode(int mode)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteInt32(mode);
Remote()->SendRequest(MessageID::MSG_ID_SET_DISPLAY_MODE, data, reply, option);
IMSA_HILOGI("InputControlChannelProxy::setDisplayMode.");
}
void InputControlChannelProxy::onKeyboardShowed()
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
Remote()->SendRequest(ON_KEYBOARD_SHOWED, data, reply, option);
IMSA_HILOGI("InputControlChannelProxy::onKeyboardShowed.");
}
}
}

View File

@ -0,0 +1,255 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <chrono>
#include <stdint.h>
#include "message_handler.h"
#include "input_control_channel_stub.h"
#include "i_input_control_channel.h"
#include "input_channel.h"
#include "input_method_agent_proxy.h"
#include "message_parcel.h"
namespace OHOS {
namespace MiscServices {
/*! Constructor
\param userId the id of the user to whom the object is linking
*/
InputControlChannelStub::InputControlChannelStub(int userId)
{
userId_ = userId;
}
/*! Destructor
*/
InputControlChannelStub::~InputControlChannelStub() {
}
/*! Handle the transaction from the remote binder
\n Run in binder thread
\param code transaction code number
\param data the params from remote binder
\param[out] reply the result of the transaction replied to the remote binder
\param flags the flags of handling transaction
\return int32_t
*/
int32_t InputControlChannelStub::OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option)
{
IMSA_HILOGI("InputControlChannelStub::OnRemoteRequest code = %{public}u", code);
auto descriptorToken = data.ReadInterfaceToken();
if (descriptorToken != GetDescriptor()) {
return ErrorCode::ERROR_STATUS_UNKNOWN_TRANSACTION;
}
switch (code) {
case ON_AGENT_CREATED: {
sptr<InputMethodAgentProxy> proxy = new InputMethodAgentProxy(data.ReadRemoteObject());
sptr<IInputMethodAgent> agent = proxy;
InputChannel* channel = nullptr;
if (data.ReadInt32() > 0) {
channel = data.ReadParcelable<InputChannel>();
}
onAgentCreated(agent, channel);
reply.WriteNoException();
break;
}
case HIDE_KEYBOARD_SELF: {
int flag = data.ReadInt32();
hideKeyboardSelf(flag);
reply.WriteNoException();
break;
}
case ADVANCE_TO_NEXT: {
bool isCurrentIme = data.ReadInt32();
bool ret = advanceToNext(isCurrentIme);
reply.WriteNoException();
reply.WriteBool(ret);
break;
}
case SET_DISPLAY_MODE: {
int mode = data.ReadInt32();
setDisplayMode(mode);
reply.WriteNoException();
break;
}
case ON_KEYBOARD_SHOWED: {
onKeyboardShowed();
reply.WriteNoException();
break;
}
default: {
return IRemoteStub::OnRemoteRequest(code, data, reply, option);
}
}
return NO_ERROR;
}
/*! Called when input method service creates InputMethodAgentProxy
\n This call is running in binder thread
\param agent the remote handler from input method service, with which input client can remotely callback to
input method service
\param channel channel for sending physical keyboard event from input client to input method service
*/
void InputControlChannelStub::onAgentCreated(sptr < IInputMethodAgent >& agent, InputChannel* channel)
{
IMSA_HILOGI("InputControlChannelStub::onAgentCreated");
{
std::unique_lock < std::mutex > lck(mtx);
agentReadyFlag = true;
}
this->agent = agent;
this->channel = channel;
cv.notify_one();
}
/*! Called when input method service showed keyboard
\n This call is running in binder thread
*/
void InputControlChannelStub::onKeyboardShowed()
{
IMSA_HILOGI("InputControlChannelStub::onKeyboardShowed");
{
std::unique_lock < std::mutex > lck(mtx);
keyboardReadyFlag = true;
}
cv.notify_one();
}
/*! Send hideKeyboardSelf command to work thread.
\n This call is running in binder thread,
but the handling of hideKeyboardSelf is in the work thread of PerUserSession.
\see PerUserSession::OnHideKeyboardSelf
\param flags the flag value of hiding keyboard
*/
void InputControlChannelStub::hideKeyboardSelf(int flags)
{
IMSA_HILOGI("InputControlChannelStub::hideKeyboardSelf flags = %{public}d", flags);
MessageParcel* parcel = new MessageParcel();
parcel->WriteInt32(userId_);
parcel->WriteInt32(flags);
Message* msg = new Message(MessageID::MSG_ID_HIDE_KEYBOARD_SELF, parcel);
MessageHandler::Instance()->SendMessage(msg);
}
/*! Send advanceToNext command to work thread.
\n This call is running in binder thread,
but the handling of advanceToNext is in the work thread of InputMethodSystemAbility service
\n or in the work thread of PerUserSession
\see InputMethodSystemAbility::OnAdvanceToNext PerUserSession::OnAdvanceToNext
\see PerUserSetting::OnAdvanceToNext
\param isCurrentIme true - switch to next keyboard type within current input method engine
\n false - switch to next input method engine
\return true
*/
bool InputControlChannelStub::advanceToNext(bool isCurrentIme)
{
IMSA_HILOGI("InputControlChannelStub::advanceToNext");
MessageParcel* parcel = new MessageParcel();
parcel->WriteInt32(userId_);
parcel->WriteBool(isCurrentIme);
Message* msg = new Message(MessageID::MSG_ID_ADVANCE_TO_NEXT, parcel);
MessageHandler::Instance()->SendMessage(msg);
return true;
}
/*! Send setDisplayMode command to work thread.
\n This call is running in binder thread,
but the handling of setDisplayMode is in the work thread of PerUserSession.
\see PerUserSession::OnSetDisplayMode
\param mode 0 - part screen mode, 1 - full screen mode
*/
void InputControlChannelStub::setDisplayMode(int mode)
{
IMSA_HILOGI("InputControlChannelStub::setDisplayMode start");
MessageParcel* parcel = new MessageParcel();
parcel->WriteInt32(userId_);
parcel->WriteInt32(mode);
Message* msg = new Message(MessageID::MSG_ID_SET_DISPLAY_MODE, parcel);
MessageHandler::Instance()->SendMessage(msg);
}
/*! Reset ready flag to be false
\n This should be called before imsCore->startInput() in work thread of PerUserSession
*/
void InputControlChannelStub::ResetFlag()
{
IMSA_HILOGI("InputControlChannelStub::ResetFlag");
std::unique_lock < std::mutex > lck(mtx);
keyboardReadyFlag = false;
agentReadyFlag = false;
if (agent) {
agent = nullptr;
}
if (channel) {
delete channel;
channel = nullptr;
}
}
/*! Get input method agent and input write channel
\n This should be called in work thread of PerUserSession
\param[out] retAgent remote handler of InputMethodAgentProxy returned to the caller
\param[out] retChannel input write channel returned to caller
\return true - onAgentCreated is called by input method service in time
\n false - onAgentCreated is not called by input method service in time
*/
bool InputControlChannelStub::GetAgentAndChannel(sptr<IInputMethodAgent>* retAgent, InputChannel** retChannel)
{
IMSA_HILOGI("InputControlChannelStub::GetAgentAndChannel");
std::chrono::milliseconds millsec(300);
bool ret = false;
{
std::unique_lock < std::mutex > lck(mtx);
ret = cv.wait_for(lck, millsec, [this] {
return agentReadyFlag;
});
}
if (ret) {
if (retAgent) {
*retAgent = agent;
agent = nullptr;
}
if (retChannel) {
*retChannel = channel;
channel = nullptr;
}
return true;
}
return false;
}
/*! Wait for keyboard to be ready
\n This should be called in work thread of PerUserSession
\return true - onKeyboardShowed is called by input method service in time
\n false - onKeyboardShowed is not called by input method service in time
*/
bool InputControlChannelStub::WaitKeyboardReady()
{
IMSA_HILOGI("InputControlChannelStub::WaitKeyboardReady");
std::chrono::milliseconds millsec(300);
bool ret = false;
{
std::unique_lock < std::mutex > lck(mtx);
ret = cv.wait_for(lck, millsec, [this] {
return keyboardReadyFlag;
});
}
return ret;
}
}
}

View File

@ -0,0 +1,59 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "input_method_ability_connection_stub.h"
#include "message_parcel.h"
#include "message.h"
namespace OHOS {
namespace MiscServices {
InputMethodAbilityConnectionStub::InputMethodAbilityConnectionStub(const int index){
mIndex = index;
}
InputMethodAbilityConnectionStub::~InputMethodAbilityConnectionStub(){
}
void InputMethodAbilityConnectionStub::OnAbilityConnectDone(const AppExecFwk::ElementName &element, const sptr<IRemoteObject> &remoteObject, int resultCode){
IMSA_HILOGE("ConnectAbility: OnAbilityConnectDone.");
if(messageHandler != nullptr){
MessageParcel* data = new MessageParcel();
data->WriteParcelable(&element);
data->WriteRemoteObject(remoteObject);
data->WriteInt32(mIndex);
Message* msg = new Message(MessageID::MSG_ID_ABILITY_CONNECT_DONE, data);
messageHandler->SendMessage(msg);
}
}
void InputMethodAbilityConnectionStub::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode) {
IMSA_HILOGE("ConnectAbility: OnAbilityDisconnectDone.");
if(messageHandler != nullptr){
MessageParcel* data = new MessageParcel();
data->WriteParcelable(&element);
data->WriteInt32(mIndex);
Message* msg = new Message(MessageID::MSG_ID_ABILITY_DISCONNECT_DONE, data);
messageHandler->SendMessage(msg);
}
}
void InputMethodAbilityConnectionStub::SetHandler(MessageHandler* handler){
messageHandler = handler;
}
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "i_input_method_agent.h"
#include "iremote_proxy.h"
#include "iremote_broker.h"
#include "global.h"
/*! \class BpInputMethodAgentProxy
\brief The proxy implementation of IInputMethodAgent
This class should be implemented by input client
*/
namespace OHOS {
namespace MiscServices {
class InputMethodAgentProxy : public IRemoteProxy<IInputMethodAgent> {
public:
InputMethodAgentProxy(const sptr<IRemoteObject>& impl)
: IRemoteProxy<IInputMethodAgent>(impl)
{
}
~InputMethodAgentProxy()
{
}
int32_t dispatchKey(int key, int status)
{
(void)key;
(void)status;
return NO_ERROR;
}
};
}
}

View File

@ -0,0 +1,130 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "input_method_property.h"
namespace OHOS {
namespace MiscServices {
using namespace std;
/*! Constructor
*/
InputMethodProperty::InputMethodProperty()
{
}
/*! Destructor
*/
InputMethodProperty::~InputMethodProperty()
{
for(int32_t i=0; i<(int32_t)mTypes.size(); i++) {
delete mTypes[i];
}
mTypes.clear();
}
/*! Constructor
\param property the source property will be copied to this instance.
*/
InputMethodProperty::InputMethodProperty(const InputMethodProperty& property)
{
mImeId = property.mImeId;
mPackageName = property.mPackageName;
mAbilityName = property.mAbilityName;
mConfigurationPage = property.mConfigurationPage;
isSystemIme = property.isSystemIme;
mDefaultImeId = property.mDefaultImeId;
for(int i = 0; i < (int)mTypes.size(); i++) {
KeyboardType* type = new KeyboardType(*property.mTypes[i]);
mTypes.push_back(type);
}
}
/*! operator=
\param property the source property will be copied to this instance.
\return return this
*/
InputMethodProperty& InputMethodProperty::operator=(const InputMethodProperty& property)
{
if (this == &property) {
return *this;
}
mImeId = property.mImeId;
mPackageName = property.mPackageName;
mAbilityName = property.mAbilityName;
mConfigurationPage = property.mConfigurationPage;
isSystemIme = property.isSystemIme;
mDefaultImeId = property.mDefaultImeId;
for(int i = 0; i < (int)mTypes.size(); i++) {
KeyboardType* type = new KeyboardType(*property.mTypes[i]);
mTypes.push_back(type);
}
return *this;
}
/*! Write InputMethodProperty to parcel
\param[out] parcel the information is written to this parcel returned to caller
\return ErrorCode::NO_ERROR
\return ErrorCode::ERROR_NULL_POINTER parcel is null
*/
bool InputMethodProperty::Marshalling(Parcel &parcel) const
{
if (!(parcel.WriteString16(mImeId)
&&parcel.WriteString16(mPackageName)
&&parcel.WriteString16(mAbilityName)
&&parcel.WriteString16(mConfigurationPage)
&&parcel.WriteBool(isSystemIme)
&&parcel.WriteInt32(mDefaultImeId)))
return false;
int32_t size = (int32_t)mTypes.size();
parcel.WriteInt32(size);
if (size == 0)
return true;
for(int i=0; i<size; i++){
parcel.WriteParcelable(mTypes[i]);
}
return true;
}
/*! Get InputMethodProperty from parcel
\param parcel read InputMethodProperty from this parcel
\return ErrorCode::NO_ERROR
\return ErrorCode::ERROR_NULL_POINTER parcel is null
*/
InputMethodProperty* InputMethodProperty::Unmarshalling(Parcel &parcel)
{
auto info = new InputMethodProperty();
info->mImeId = parcel.ReadString16();
info->mPackageName = parcel.ReadString16();
info->mAbilityName = parcel.ReadString16();
info->mConfigurationPage = parcel.ReadString16();
info->isSystemIme = parcel.ReadBool();
info->mDefaultImeId = parcel.ReadInt32();
int32_t size = parcel.ReadInt32();
if (size == 0)
return info;
for (int i =0; i < size; i++) {
info->mTypes.push_back(parcel.ReadParcelable<KeyboardType>());
}
return info;
}
}
}

View File

@ -0,0 +1,342 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "input_method_setting.h"
#include "utils.h"
namespace OHOS {
namespace MiscServices {
const std::u16string InputMethodSetting::CURRENT_INPUT_METHOD_TAG = u"imms_current_input_method";
const std::u16string InputMethodSetting::ENABLED_INPUT_METHODS_TAG = u"imms_enabled_input_methods";
const std::u16string InputMethodSetting::CURRENT_KEYBOARD_TYPE_TAG = u"imms_current_keyboard_type";
const std::u16string InputMethodSetting::CURRENT_SYS_KEYBOARD_TYPE_TAG = u"imms_current_sys_keyboard_type";
const std::u16string InputMethodSetting::SYSTEM_LOCALE_TAG = u"system_locales";
/*! Constructor
*/
InputMethodSetting::InputMethodSetting()
{
}
/*! Destructor
*/
InputMethodSetting::~InputMethodSetting()
{
setting.clear();
}
/*! Constructor
\param inputMethodSetting the source InputMethodSetting copied to this instance
*/
InputMethodSetting::InputMethodSetting(const InputMethodSetting& inputMethodSetting)
{
setting = inputMethodSetting.setting;
}
/*! operator=
\param inputMethodSetting the source InputMethodSetting copied to this instance
\return return this instance
*/
InputMethodSetting& InputMethodSetting::operator=(const InputMethodSetting& inputMethodSetting)
{
if (this == &inputMethodSetting) {
return *this;
}
setting = inputMethodSetting.setting;
return *this;
}
/*! Write setting data to parcel
\param[out] parcel the setting data is written to parcel returned to caller.
\return ErrorCode::NO_ERROR
*/
bool InputMethodSetting::Marshalling(OHOS::Parcel &parcel) const {
int32_t size = setting.size();
parcel.WriteInt32(size);
std::map<std::u16string, std::u16string>::const_iterator it;
for(it = setting.cbegin(); it != setting.cend(); ++it) {
parcel.WriteString16(it->first);
parcel.WriteString16(it->second);
}
return ErrorCode::NO_ERROR;
}
/*! Read setting data from parcel
\param parcel read the setting data from the given parcel
\return ErrorCode::NO_ERROR
*/
InputMethodSetting* InputMethodSetting::Unmarshalling(OHOS::Parcel &parcel) {
auto ims = new InputMethodSetting();
int32_t size = parcel.ReadInt32();
for(int i = 0; i < size; i++) {
std::u16string key = parcel.ReadString16();
std::u16string value = parcel.ReadString16();
ims->setting.insert(std::pair<std::u16string, std::u16string>(key, value));
}
return ims;
}
/*! Set setting data for an item
\param key the name of setting item
\param value the value of setting item
*/
void InputMethodSetting::SetValue(const std::u16string& key, const std::u16string& value)
{
setting.insert_or_assign(key, value);
}
/*! Get setting data for an item
\param key the name of setting item
\return the value of setting item if key is found
\return an empty string if key is not found
*/
std::u16string InputMethodSetting::GetValue(const std::u16string& key) const
{
std::map<std::u16string, std::u16string>::const_iterator it = setting.find(key);
if (it == setting.end()) {
return u"";
}
return it->second;
}
/*! Get the default input method engine
\return the imeId of the default input method engine
*/
std::u16string InputMethodSetting::GetCurrentInputMethod() const
{
return GetValue(CURRENT_INPUT_METHOD_TAG);
}
/*! Set the default input method engine
\param imeId the ime Id of the given input method engine
*/
void InputMethodSetting::SetCurrentInputMethod(const std::u16string& imeId)
{
SetValue(CURRENT_INPUT_METHOD_TAG, imeId);
}
/*! Get enabled input method engine list
\return a vector of ImeId
*/
std::vector<std::u16string> InputMethodSetting::GetEnabledInputMethodList()
{
std::u16string value = GetValue(ENABLED_INPUT_METHODS_TAG);
std::vector<std::u16string> tmp1 = Split(value, DELIM_IME);
std::vector<std::u16string> imeList;
for(int i = 0; i < (int)tmp1.size(); i++) {
std::vector<std::u16string> tmp2 = Split(tmp1[i], DELIM_KBD_TYPE);
imeList.push_back(tmp2[0]);
tmp2.clear();
}
return imeList;
}
/*! Add an input method engine to enabled ime list
\param imeId the ime id of the added input method engine
\param types a vector of hashCode of keyboard types which are supported by the added input method engine
\return true - added successfully.
\return false - the given input method engine is already enabled.
*/
bool InputMethodSetting::AddEnabledInputMethod(const std::u16string& imeId, const std::vector<int32_t>& types)
{
std::u16string str = GetValue(ENABLED_INPUT_METHODS_TAG);
std::vector<std::u16string> imeList = Split(str, DELIM_IME);
std::u16string typeStr;
for(int i = 0; i < (int)types.size(); i++) {
typeStr = typeStr + u";" + Utils::to_utf16(std::to_string(types[i]));
}
std::u16string imeStr = imeId + typeStr;
bool flag = false;
for(int i = 0; i < (int)imeList.size(); i++) {
if (imeList[i] == imeStr) {
return false;
}
if (imeList[i].find_first_of(imeId)) {
imeList[i] = imeStr;
flag = true;
break;
}
}
if (flag == false) {
imeList.push_back(imeStr);
}
std::u16string value = BuildString(imeList, DELIM_IME);
SetValue(ENABLED_INPUT_METHODS_TAG, value);
imeList.clear();
return true;
}
/*! Remove an input method engine from enabled ime list.
\param imeId the ime id of the given input method engine
\return true - removed successfully.
\return false - ime id is not found in enabled ime list.
*/
bool InputMethodSetting::RemoveEnabledInputMethod(const std::u16string& imeId)
{
std::u16string str = GetValue(ENABLED_INPUT_METHODS_TAG);
std::vector<std::u16string> imeList = Split(str, DELIM_IME);
bool flag = false;
std::vector<std::u16string>::iterator it;
for(it = imeList.begin(); it < imeList.end(); ++it) {
if (it->find_first_of(imeId)) {
imeList.erase(it);
flag = true;
break;
}
}
if (flag == true) {
std::u16string value = BuildString(imeList, DELIM_IME);
SetValue(ENABLED_INPUT_METHODS_TAG, value);
}
imeList.clear();
return flag;
}
/*! Get the keyboard type list of the given input method engine
\param imeId the ime id of the given input method engine
\return a vector of hashCodes
*/
std::vector<int32_t> InputMethodSetting::GetEnabledKeyboardTypes(const std::u16string& imeId)
{
std::vector<int32_t> retValue;
std::u16string value = GetValue(ENABLED_INPUT_METHODS_TAG);
std::vector<std::u16string> tmpVector = Split(value, DELIM_IME);
bool flag = false;
std::u16string imeStr;
for(int i = 0; i < (int)tmpVector.size(); i++) {
if (tmpVector[i].find_first_of(imeId) != std::u16string::npos) {
flag = true;
imeStr = tmpVector[i];
break;
}
}
tmpVector.clear();
if (flag == false) {
return retValue;
}
std::vector<std::u16string> tmp2 = Split(imeStr, DELIM_KBD_TYPE);
for(int i = 1; i < (int)tmp2.size(); i++) {
std::u16string str = tmp2[i];
retValue.push_back(std::atoi(Utils::to_utf8(str).c_str()));
}
tmp2.clear();
return retValue;
}
/*! Get the default keyboard type
\return return the hashCode value of the default keyboard type.
*/
int32_t InputMethodSetting::GetCurrentKeyboardType()
{
std::u16string value = GetValue(CURRENT_KEYBOARD_TYPE_TAG);
return std::atoi(Utils::to_utf8(value).c_str());
}
/*! Set the default keyboard type
\param type hashCode of the given keyboard type
*/
void InputMethodSetting::SetCurrentKeyboardType(int32_t type)
{
std::u16string str = Utils::to_utf16(std::to_string(type));
SetValue(CURRENT_KEYBOARD_TYPE_TAG, str);
}
/*! Get the default keyboard type for security input method engine
\return return hashCode of the default keyboard type of security IME
*/
int32_t InputMethodSetting::GetCurrentSysKeyboardType()
{
std::u16string value = GetValue(CURRENT_SYS_KEYBOARD_TYPE_TAG);
return std::atoi(Utils::to_utf8(value).c_str());
}
/*! Set the default keyboard type for security IME
\param type the hashCode of the given keyboard type of security IME
*/
void InputMethodSetting::SetCurrentSysKeyboardType(int32_t type)
{
std::u16string str = Utils::to_utf16(std::to_string(type));
SetValue(CURRENT_SYS_KEYBOARD_TYPE_TAG, std::u16string(str));
}
/*! Clear setting data
*/
void InputMethodSetting::ClearData()
{
setting.clear();
}
/*! Find if the key is in the setting
\param key the name of setting item
\return true - key is found
\return false - key is not found
*/
bool InputMethodSetting::FindKey(const std::u16string& key) const
{
std::map<std::u16string, std::u16string>::const_iterator it = setting.find(key);
if (it == setting.end()) {
return false;
}
return true;
}
/*! Split a string into a vector
\param str the string to be split
\param delim the alphabet to split the string.
\return a vector of string
*/
std::vector<std::u16string> InputMethodSetting::Split(const std::u16string& str, char16_t delim)
{
std::vector<std::u16string> retValue;
std::u16string::size_type left,right;
left = 0;
right = str.find(delim, 0);
while(right != std::u16string::npos){
if(right-left){
retValue.emplace_back(str.substr(left,right-left));
}
left = right + 1;
right = str.find(delim,left);
}
if(left != str.size()){
retValue.emplace_back(str.substr(left));
}
return retValue;
}
/*! Build a string from a vector
\param vector a vector of string
\delim a separator
\return return a string
*/
std::u16string InputMethodSetting::BuildString(const std::vector<std::u16string>& vector, char16_t delim)
{
std::u16string retValue = u"";
char16_t delimStr[] = {delim, 0};
for(int i = 0; i < (int)vector.size(); i++) {
retValue += vector[i];
if (i<(int)vector.size()-1) {
retValue += std::u16string(delimStr);
}
}
return retValue;
}
}
}

View File

@ -0,0 +1,863 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "input_method_system_ability.h"
#include "message_handler.h"
#include "system_ability.h"
#include "system_ability_definition.h"
#include "iservice_registry.h"
#include "ipc_skeleton.h"
#include "global.h"
namespace OHOS {
namespace MiscServices {
using namespace MessageID;
REGISTER_SYSTEM_ABILITY_BY_ID(InputMethodSystemAbility, INPUT_METHOD_SYSTEM_ABILITY_ID, true);
const std::int32_t INIT_INTERVAL = 10000L;
std::mutex InputMethodSystemAbility::instanceLock_;
sptr<InputMethodSystemAbility> InputMethodSystemAbility::instance_;
std::shared_ptr<AppExecFwk::EventHandler> InputMethodSystemAbility::serviceHandler_;
/*! Constructor
*/
InputMethodSystemAbility::InputMethodSystemAbility(int32_t systemAbilityId, bool runOnCreate)
: SystemAbility(systemAbilityId, runOnCreate), state_(ServiceRunningState::STATE_NOT_START)
{
}
/*! Constructor
*/
InputMethodSystemAbility::InputMethodSystemAbility() : state_(ServiceRunningState::STATE_NOT_START)
{
}
/*! Destructor
*/
InputMethodSystemAbility::~InputMethodSystemAbility()
{
if (workThreadHandler.joinable()) {
workThreadHandler.join();
}
std::map<int32_t, PerUserSession*>::const_iterator it;
for(it=userSessions.cbegin(); it!=userSessions.cend();) {
PerUserSession *session = it->second;
it = userSessions.erase(it);
delete session;
}
userSessions.clear();
std::map<int32_t, PerUserSetting*>::const_iterator it1;
for(it1=userSettings.cbegin(); it1!=userSettings.cend();) {
PerUserSetting *setting = it1->second;
it1 = userSettings.erase(it1);
delete setting;
}
userSettings.clear();
std::map<int32_t, MessageHandler*>::const_iterator it2;
for(it2=msgHandlers.cbegin(); it2!=msgHandlers.cend();) {
MessageHandler *handler = it2->second;
it2 = msgHandlers.erase(it2);
delete handler;
}
msgHandlers.clear();
}
sptr<InputMethodSystemAbility> InputMethodSystemAbility::GetInstance()
{
if (instance_ == nullptr) {
std::lock_guard<std::mutex> autoLock(instanceLock_);
if (instance_ == nullptr) {
instance_ = new InputMethodSystemAbility;
}
}
return instance_;
}
void InputMethodSystemAbility::OnStart()
{
IMSA_HILOGI("Enter OnStart.");
if (state_ == ServiceRunningState::STATE_RUNNING) {
IMSA_HILOGI("ImsaService is already running.");
return;
}
Initialize();
InitServiceHandler();
if (Init() != ErrorCode::NO_ERROR) {
auto callback = [=]() { Init(); };
serviceHandler_->PostTask(callback, INIT_INTERVAL);
IMSA_HILOGE("Init failed. Try again 10s later");
return;
}
IMSA_HILOGI("Start ImsaService ErrorCode::NO_ERROR.");
return;
}
int32_t InputMethodSystemAbility::Init()
{
bool ret = Publish(InputMethodSystemAbility::GetInstance());
if (!ret) {
IMSA_HILOGE("Publish failed.");
return -1;
}
IMSA_HILOGI("Publish ErrorCode::NO_ERROR.");
state_ = ServiceRunningState::STATE_RUNNING;
return ErrorCode::NO_ERROR;
}
void InputMethodSystemAbility::OnStop()
{
IMSA_HILOGI("OnStop started.");
if (state_ != ServiceRunningState::STATE_RUNNING) {
return;
}
serviceHandler_ = nullptr;
state_ = ServiceRunningState::STATE_NOT_START;
IMSA_HILOGI("OnStop end.");
}
void InputMethodSystemAbility::InitServiceHandler()
{
IMSA_HILOGI("InitServiceHandler started.");
if (serviceHandler_ != nullptr) {
IMSA_HILOGI("InitServiceHandler already init.");
return;
}
std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create("InputMethodSystemAbility");
serviceHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
IMSA_HILOGI("InitServiceHandler succeeded.");
}
/*! Initialization of Input method management service
\n It's called after the service starts, before any transaction.
*/
void InputMethodSystemAbility::Initialize()
{
IMSA_HILOGI("InputMethodSystemAbility::Initialize");
// init work thread to handle the messages
workThreadHandler = std::thread([this] {
WorkThread();
});
PerUserSetting* setting=new PerUserSetting(0);
PerUserSession* session=new PerUserSession(0);
userSettings.insert(std::pair<int32_t,PerUserSetting*>(0,setting));
userSessions.insert(std::pair<int32_t,PerUserSession*>(0,session));
setting->Initialize();
}
/*! Get the state of user
\n This API is added for unit test.
\param userID the id of given user
\return user state can be one of the values of UserState
*/
int32_t InputMethodSystemAbility::GetUserState(int32_t userId)
{
PerUserSetting *setting = GetUserSetting(userId);
if (setting == nullptr) {
return UserState::USER_STATE_NOT_AVAILABLE;
}
return setting->GetUserState();
}
/*! Handle the transaction from the remote binder
\n Run in binder thread
\param code transaction code number
\param data the params from remote binder
\param[out] reply the result of the transaction replied to the remote binder
\param flags the flags of handling transaction
\return int32_t
*/
int32_t InputMethodSystemAbility::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
MessageOption &option)
{
return InputMethodSystemAbilityStub::OnRemoteRequest(code, data, reply, option);
}
/*! Get the display mode of keyboard
\n Run in binder thread
\param[out] retMode the display mode returned to the caller
\return ErrorCode::NO_ERROR no error
\return ErrorCode::ERROR_USER_NOT_UNLOCKED user not unlocked
*/
int32_t InputMethodSystemAbility::getDisplayMode(int32_t *retMode)
{
int32_t uid = IPCSkeleton::GetCallingUid();
int32_t userId = getUserId(uid);
PerUserSetting* setting = GetUserSetting(userId);
if (setting == nullptr || setting->GetUserState() != UserState::USER_STATE_UNLOCKED) {
IMSA_HILOGE("%s %d\n", ErrorCode::ToString(ErrorCode::ERROR_USER_NOT_UNLOCKED), userId);
return ErrorCode::ERROR_USER_NOT_UNLOCKED;
}
*retMode = GetUserSession(userId)->GetDisplayMode();
return ErrorCode::NO_ERROR;
}
/*! Get the window height of the current keyboard
\n Run in binder thread
\param[out] retHeight the window height returned to the caller
\return ErrorCode::NO_ERROR no error
\return ErrorCode::ERROR_USER_NOT_UNLOCKED user not unlocked
*/
int32_t InputMethodSystemAbility::getKeyboardWindowHeight(int32_t *retHeight)
{
int32_t uid = IPCSkeleton::GetCallingUid();
int32_t userId = getUserId(uid);
PerUserSetting* setting = GetUserSetting(userId);
if (setting == nullptr || setting->GetUserState() != UserState::USER_STATE_UNLOCKED) {
IMSA_HILOGE("%s %d\n", ErrorCode::ToString(ErrorCode::ERROR_USER_NOT_UNLOCKED), userId);
return ErrorCode::ERROR_USER_NOT_UNLOCKED;
}
int32_t ret = GetUserSession(userId)->GetKeyboardWindowHeight(retHeight);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("Failed to get keyboard window height. ErrorCode=%d\n", ret);
}
return ret;
}
/*! Get the current keyboard type
\n Run in binder thread
\param[out] retType the current keyboard type returned to the caller
\return ErrorCode::NO_ERROR no error
\return ErrorCode::ERROR_USER_NOT_UNLOCKED user not unlocked
\return ErrorCode::ERROR_NULL_POINTER current keyboard type is null
*/
int32_t InputMethodSystemAbility::getCurrentKeyboardType(KeyboardType* retType)
{
int32_t uid = IPCSkeleton::GetCallingUid();
int32_t userId = getUserId(uid);
PerUserSetting* setting = GetUserSetting(userId);
if (setting == nullptr || setting->GetUserState() != UserState::USER_STATE_UNLOCKED) {
IMSA_HILOGE("%s %d\n", ErrorCode::ToString(ErrorCode::ERROR_USER_NOT_UNLOCKED), userId);
return ErrorCode::ERROR_USER_NOT_UNLOCKED;
}
KeyboardType* type = GetUserSession(userId)->GetCurrentKeyboardType();
if (type == nullptr) {
return ErrorCode::ERROR_NULL_POINTER;
}
*retType = *type;
return ErrorCode::NO_ERROR;
}
/*! Get the enabled input method engine list
\n Run in binder thread
\param[out] properties input method engine list returned to the caller
\return ErrorCode::NO_ERROR no error
\return ErrorCode::ERROR_USER_NOT_UNLOCKED user not unlocked
*/
int32_t InputMethodSystemAbility::listInputMethodEnabled(std::vector<InputMethodProperty*> *properties)
{
int32_t uid = IPCSkeleton::GetCallingUid();
int32_t userId = getUserId(uid);
PerUserSetting* setting = GetUserSetting(userId);
if (setting == nullptr || setting->GetUserState() != UserState::USER_STATE_UNLOCKED) {
IMSA_HILOGE("%s %d\n", ErrorCode::ToString(ErrorCode::ERROR_USER_NOT_UNLOCKED), userId);
return ErrorCode::ERROR_USER_NOT_UNLOCKED;
}
setting->ListInputMethodEnabled(properties);
std::vector<InputMethodProperty*>::iterator it;
for(it=properties->begin(); it!=properties->end();) {
if (*it && (*it)->isSystemIme) {
it = properties->erase(it);
} else {
++it;
}
}
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
\return ErrorCode::NO_ERROR no error
\return ErrorCode::ERROR_USER_NOT_UNLOCKED user not unlocked
*/
int32_t InputMethodSystemAbility::listInputMethod(std::vector<InputMethodProperty*> *properties)
{
int32_t uid = IPCSkeleton::GetCallingUid();
int32_t userId = getUserId(uid);
PerUserSetting* setting = GetUserSetting(userId);
if (setting == nullptr || setting->GetUserState() != UserState::USER_STATE_UNLOCKED) {
IMSA_HILOGE("%s %d\n", ErrorCode::ToString(ErrorCode::ERROR_USER_NOT_UNLOCKED), userId);
return ErrorCode::ERROR_USER_NOT_UNLOCKED;
}
setting->ListInputMethod(properties);
std::vector<InputMethodProperty*>::iterator it;
for(it=properties->begin(); it!=properties->end();) {
if (*it && (*it)->isSystemIme) {
it = properties->erase(it);
} else {
++it;
}
}
return ErrorCode::NO_ERROR;
}
/*! Get the keyboard type list for the given input method engine
\n Run in binder thread
\param imeId the id of the given input method engine
\param[out] types keyboard type list returned to the caller
\return ErrorCode::NO_ERROR no error
\return ErrorCode::ERROR_USER_NOT_UNLOCKED user not unlocked
*/
int32_t InputMethodSystemAbility::listKeyboardType(const std::u16string& imeId, std::vector<KeyboardType*> *types)
{
int32_t uid = IPCSkeleton::GetCallingUid();
int32_t userId = getUserId(uid);
PerUserSetting* setting = GetUserSetting(userId);
if (setting == nullptr || setting->GetUserState() != UserState::USER_STATE_UNLOCKED) {
IMSA_HILOGE("%s %d\n", ErrorCode::ToString(ErrorCode::ERROR_USER_NOT_UNLOCKED), userId);
return ErrorCode::ERROR_USER_NOT_UNLOCKED;
}
return setting->ListKeyboardType(imeId, types);
}
/*! Print service information for the input method management service.
\n Run in binder thread
\n The information includes :
\li The user information in the service
\li The input method engine information
\li The input method setting data
\li The session information in the service.
\param fd the raw file descriptor that the dump is being sent to
\param args the parameters for dump command. This parameter is ignored here.
\return ErrorCode::NO_ERROR
*/
int32_t InputMethodSystemAbility::dump(int32_t fd, const std::vector<std::u16string>& args)
{
(void) args;
dprintf(fd, "\nInputMethodSystemAbility State:\n");
std::map<int32_t, PerUserSetting*>::const_iterator it;
int32_t index = 0;
dprintf(fd, "* User count = %d\n", userSettings.size());
for(it=userSettings.cbegin(); it!=userSettings.cend(); ++it) {
PerUserSetting* setting = it->second;
int32_t userId = it->first;
int32_t userState = setting->GetUserState();
if (userState == UserState::USER_STATE_STARTED) {
dprintf(fd, "[%d] User information: UserId = %d, UserState = USER_STATE_STARTED\n", index++, userId);
} else if (userState == UserState::USER_STATE_UNLOCKED) {
dprintf(fd, "[%d] User information: UserId = %d, UserState = USER_STATE_UNLOCKED\n", index++, userId);
setting->Dump(fd);
PerUserSession* session = GetUserSession(userId);
session->Dump(fd);
}
dprintf(fd, "\n");
}
dprintf(fd, "\n");
return ErrorCode::NO_ERROR;
}
/*! Get the instance of PerUserSetting for the given user
\param userId the user id of the given user
\return a pointer of the instance if the user is found
\return null if the user is not found
*/
PerUserSetting* InputMethodSystemAbility::GetUserSetting(int32_t userId)
{
std::map<int32_t, PerUserSetting*>::iterator it = userSettings.find(userId);
if (it == userSettings.end()) {
return nullptr;
}
return it->second;
}
/*! Get the instance of PerUserSession for the given user
\param userId the user id of the given user
\return a pointer of the instance if the user is found
\return null if the user is not found
*/
PerUserSession* InputMethodSystemAbility::GetUserSession(int32_t userId)
{
std::map<int32_t, PerUserSession*>::iterator it = userSessions.find(userId);
if (it == userSessions.end()) {
return nullptr;
}
return it->second;
}
/*! Work Thread of input method management service
\n Remote commands which may change the state or data in the service will be handled sequentially in this thread.
*/
void InputMethodSystemAbility::WorkThread()
{
while(1){
Message* msg = MessageHandler::Instance()->GetMessage();
switch(msg->msgId_) {
case MSG_ID_USER_START : {
OnUserStarted(msg);
break;
}
case MSG_ID_USER_STOP: {
OnUserStopped(msg);
break;
}
case MSG_ID_USER_UNLOCK: {
OnUserUnlocked(msg);
break;
}
case MSG_ID_USER_LOCK : {
OnUserLocked(msg);
break;
}
case MSG_ID_PACKAGE_ADDED: {
OnPackageAdded(msg);
break;
}
case MSG_ID_PACKAGE_REMOVED: {
OnPackageRemoved(msg);
break;
}
case MSG_ID_SETTING_CHANGED: {
OnSettingChanged(msg);
break;
}
case MSG_ID_PREPARE_INPUT: {
OnPrepareInput(msg);
break;
}
case MSG_ID_RELEASE_INPUT:
case MSG_ID_START_INPUT:
case MSG_ID_STOP_INPUT:
case MSG_ID_SET_INPUT_METHOD_CORE:
case MSG_ID_HIDE_KEYBOARD_SELF:
case MSG_ID_SET_DISPLAY_MODE:
case MSG_ID_CLIENT_DIED:
case MSG_ID_IMS_DIED:
case MSG_ID_RESTART_IMS: {
OnHandleMessage(msg);
break;
}
case MSG_ID_DISABLE_IMS: {
OnDisableIms(msg);
break;
}
case MSG_ID_ADVANCE_TO_NEXT: {
OnAdvanceToNext(msg);
break;
}
case MSG_ID_EXIT_SERVICE: {
std::map<int32_t, MessageHandler*>::const_iterator it;
for(it=msgHandlers.cbegin(); it!=msgHandlers.cend();) {
MessageHandler *handler = it->second;
Message* destMsg = new Message(MSG_ID_EXIT_SERVICE, nullptr);
handler->SendMessage(destMsg);
GetUserSession(it->first)->JoinWorkThread();
it = msgHandlers.erase(it);
delete handler;
}
delete msg;
return;
}
default: {
break;
}
}
// delete msg;
}
}
/*! Called when a user is started. (EVENT_USER_STARTED is received)
\n Run in work thread of input method management service
\param msg the parameters are saved in msg->msgContent_
\return ErrorCode
*/
int32_t InputMethodSystemAbility::OnUserStarted(const Message* msg)
{
IMSA_HILOGI("Start...\n");
if (msg->msgContent_ == nullptr) {
IMSA_HILOGE("Aborted! %s\n", ErrorCode::ToString(ErrorCode::ERROR_BAD_PARAMETERS));
return ErrorCode::ERROR_BAD_PARAMETERS;
}
int32_t userId = msg->msgContent_->ReadInt32();
PerUserSetting* setting = GetUserSetting(userId);
if (setting != nullptr) {
IMSA_HILOGE("Aborted! %s %d\n", ErrorCode::ToString(ErrorCode::ERROR_USER_ALREADY_STARTED), userId);
return ErrorCode::ERROR_USER_ALREADY_STARTED;
}
setting = new PerUserSetting(userId);
PerUserSession* session = new PerUserSession(userId);
userSettings.insert(std::pair<int32_t, PerUserSetting*>(userId, setting));
userSessions.insert(std::pair<int32_t, PerUserSession*>(userId, session));
IMSA_HILOGI("End...[%d]\n", userId);
return ErrorCode::NO_ERROR;
}
/*! Called when a user is stopped. (EVENT_USER_STOPPED is received)
\n Run in work thread of input method management service
\param msg the parameters are saved in msg->msgContent_
\return ErrorCode
*/
int32_t InputMethodSystemAbility::OnUserStopped(const Message* msg)
{
IMSA_HILOGI("Start...\n");
if (msg->msgContent_ == nullptr) {
IMSA_HILOGE("Aborted! %s\n", ErrorCode::ToString(ErrorCode::ERROR_BAD_PARAMETERS));
return ErrorCode::ERROR_BAD_PARAMETERS;
}
int32_t userId = msg->msgContent_->ReadInt32();
PerUserSetting* setting = GetUserSetting(userId);
PerUserSession* session = GetUserSession(userId);
if (setting == nullptr || session == nullptr) {
IMSA_HILOGE("Aborted! %s %d\n", ErrorCode::ToString(ErrorCode::ERROR_USER_NOT_STARTED), userId);
return ErrorCode::ERROR_USER_NOT_STARTED;
}
if (setting->GetUserState() == UserState::USER_STATE_UNLOCKED) {
IMSA_HILOGE("Aborted! %s %d\n", ErrorCode::ToString(ErrorCode::ERROR_USER_NOT_LOCKED), userId);
return ErrorCode::ERROR_USER_NOT_LOCKED;
}
std::map<int32_t, PerUserSession*>::iterator itSession = userSessions.find(userId);
userSessions.erase(itSession);
delete session;
std::map<int32_t, PerUserSetting*>::iterator itSetting = userSettings.find(userId);
userSettings.erase(itSetting);
delete setting;
IMSA_HILOGI("End...[%d]\n", userId);
return ErrorCode::NO_ERROR;
}
int32_t InputMethodSystemAbility::setInputMethodCore(sptr<IInputMethodCore> &core){
return ErrorCode::NO_ERROR;
}
/*! Called when a user is unlocked. (EVENT_USER_UNLOCKED is received)
\n Run in work thread of input method management service
\param msg the parameters are saved in msg->msgContent_
\return ErrorCode
*/
int32_t InputMethodSystemAbility::OnUserUnlocked(const Message* msg)
{
IMSA_HILOGI("Start...\n");
if (msg->msgContent_ == nullptr) {
IMSA_HILOGE("Aborted! %s\n", ErrorCode::ToString(ErrorCode::ERROR_BAD_PARAMETERS));
return ErrorCode::ERROR_BAD_PARAMETERS;
}
int32_t userId = msg->msgContent_->ReadInt32();
PerUserSetting* setting = GetUserSetting(userId);
PerUserSession* session = GetUserSession(userId);
if (setting == nullptr || session == nullptr) {
IMSA_HILOGE("Aborted! %s %d\n", ErrorCode::ToString(ErrorCode::ERROR_USER_NOT_STARTED), userId);
return ErrorCode::ERROR_USER_NOT_STARTED;
}
if (setting->GetUserState() == UserState::USER_STATE_UNLOCKED) {
IMSA_HILOGE("Aborted! %s %d\n", ErrorCode::ToString(ErrorCode::ERROR_USER_ALREADY_UNLOCKED), userId);
return ErrorCode::ERROR_USER_ALREADY_UNLOCKED;
}
setting->Initialize();
InputMethodProperty* ime = setting->GetSecurityInputMethod();
session->SetSecurityIme(ime);
ime = setting->GetCurrentInputMethod();
session->SetCurrentIme(ime);
session->SetInputMethodSetting(setting->GetInputMethodSetting());
IMSA_HILOGI("End...[%d]\n", userId);
return ErrorCode::NO_ERROR;
}
/*! Called when a user is locked. (EVENT_USER_LOCKED is received)
\n Run in work thread of input method management service
\param msg the parameters are saved in msg->msgContent_
\return ErrorCode
*/
int32_t InputMethodSystemAbility::OnUserLocked(const Message* msg)
{
IMSA_HILOGI("Start...\n");
if (msg->msgContent_ == nullptr) {
IMSA_HILOGE("Aborted! %s\n", ErrorCode::ToString(ErrorCode::ERROR_BAD_PARAMETERS));
return ErrorCode::ERROR_BAD_PARAMETERS;
}
int32_t userId = msg->msgContent_->ReadInt32();
PerUserSetting* setting = GetUserSetting(userId);
if (setting == nullptr || setting->GetUserState() != UserState::USER_STATE_UNLOCKED) {
IMSA_HILOGE("Aborted! %s %d\n", ErrorCode::ToString(ErrorCode::ERROR_USER_NOT_UNLOCKED), userId);
return ErrorCode::ERROR_USER_NOT_UNLOCKED;
}
std::map<int32_t, MessageHandler*>::iterator it = msgHandlers.find(userId);
if (it!=msgHandlers.end()) {
MessageHandler* handler = it->second;
Message* destMsg = new Message(MSG_ID_USER_LOCK , nullptr);
handler->SendMessage(destMsg);
GetUserSession(userId)->JoinWorkThread();
msgHandlers.erase(it);
delete handler;
}
setting->OnUserLocked();
IMSA_HILOGI("End...[%d]\n", userId);
return ErrorCode::NO_ERROR;
}
/*! Prepare input. Called by an input client.
\n Run in work thread of input method management service
\param msg the parameters from remote client are saved in msg->msgContent_
\return ErrorCode::NO_ERROR
\return ErrorCode::ERROR_USER_NOT_UNLOCKED user not unlocked
*/
int32_t InputMethodSystemAbility::OnPrepareInput(Message* msg)
{
IMSA_HILOGI("InputMethodSystemAbility::OnPrepareInput");
MessageParcel* data = msg->msgContent_;
int32_t userId = data->ReadInt32();
PerUserSetting* setting = GetUserSetting(userId);
if (setting == nullptr || setting->GetUserState() != UserState::USER_STATE_UNLOCKED) {
IMSA_HILOGE("InputMethodSystemAbility::OnPrepareInput GetUserSetting Aborted! %{public}s %{public}d\n", ErrorCode::ToString(ErrorCode::ERROR_USER_NOT_UNLOCKED), userId);
return ErrorCode::ERROR_USER_NOT_UNLOCKED;
}
std::map<int32_t, MessageHandler*>::const_iterator it = msgHandlers.find(userId);
if(it==msgHandlers.end()) {
PerUserSession* session = GetUserSession(userId);
MessageHandler* handler = new MessageHandler();
session->CreateWorkThread(*handler);
msgHandlers.insert(std::pair<int32_t, MessageHandler*>(userId, handler));
it = msgHandlers.find(userId);
}
if (it!=msgHandlers.end()) {
MessageHandler* handler = it->second;
handler->SendMessage(msg);
}
return 0;
}
/*! Handle message
\param msgId the id of message to run
\msg the parameters are saved in msg->msgContent_
\return ErrorCode::NO_ERROR
\return ErrorCode::ERROR_USER_NOT_UNLOCKED user not unlocked
*/
int32_t InputMethodSystemAbility::OnHandleMessage(Message* msg)
{
MessageParcel* data = msg->msgContent_;
int32_t userId = data->ReadInt32();
PerUserSetting* setting = GetUserSetting(userId);
if (setting == nullptr || setting->GetUserState() != UserState::USER_STATE_UNLOCKED) {
IMSA_HILOGE("Aborted! %s %d\n", ErrorCode::ToString(ErrorCode::ERROR_USER_NOT_UNLOCKED), userId);
return ErrorCode::ERROR_USER_NOT_UNLOCKED;
}
std::map<int32_t, MessageHandler*>::const_iterator it = msgHandlers.find(userId);
if (it!=msgHandlers.end()) {
MessageHandler* handler = it->second;
// Message* destMsg = new Message(*msg);
handler->SendMessage(msg);
}
return ErrorCode::NO_ERROR;
}
/*! Called when a package is installed.
\n Run in work thread of input method management service
\param msg the parameters are saved in msg->msgContent_
\return ErrorCode::NO_ERROR
\return ErrorCode::ERROR_USER_NOT_UNLOCKED user not unlocked
\return ErrorCode::ERROR_BAD_PARAMETERS bad parameter
*/
int32_t InputMethodSystemAbility::OnPackageAdded(const Message* msg)
{
IMSA_HILOGI("Start...\n");
MessageParcel* data = msg->msgContent_;
int32_t userId = data->ReadInt32();
int32_t size = data->ReadInt32();
if (size <= 0) {
IMSA_HILOGE("Aborted! %s\n", ErrorCode::ToString(ErrorCode::ERROR_BAD_PARAMETERS));
return ErrorCode::ERROR_BAD_PARAMETERS;
}
std::u16string packageName = data->ReadString16();
PerUserSetting* setting = GetUserSetting(userId);
if (setting == nullptr || setting->GetUserState() != UserState::USER_STATE_UNLOCKED) {
IMSA_HILOGE("Aborted! %s %d\n", ErrorCode::ToString(ErrorCode::ERROR_USER_NOT_UNLOCKED), userId);
return ErrorCode::ERROR_USER_NOT_UNLOCKED;
}
bool securityImeFlag = false;
int32_t ret = setting->OnPackageAdded(packageName, &securityImeFlag);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGI("End...\n");
return ret;
}
if (securityImeFlag == true) {
InputMethodProperty* securityIme = setting->GetSecurityInputMethod();
InputMethodProperty* defaultIme = setting->GetCurrentInputMethod();
GetUserSession(userId)->ResetIme(defaultIme, securityIme);
}
IMSA_HILOGI("End...\n");
return 0;
}
/*! Called when a package is removed.
\n Run in work thread of input method management service
\param msg the parameters are saved in msg->msgContent_
\return ErrorCode::NO_ERROR
\return ErrorCode::ERROR_USER_NOT_UNLOCKED user not unlocked
\return ErrorCode::ERROR_BAD_PARAMETERS bad parameter
*/
int32_t InputMethodSystemAbility::OnPackageRemoved(const Message* msg)
{
IMSA_HILOGI("Start...\n");
MessageParcel* data = msg->msgContent_;
int32_t userId = data->ReadInt32();
int32_t size = data->ReadInt32();
if (size <= 0) {
IMSA_HILOGE("Aborted! %s\n", ErrorCode::ToString(ErrorCode::ERROR_BAD_PARAMETERS));
return ErrorCode::ERROR_BAD_PARAMETERS;
}
std::u16string packageName = data->ReadString16();
PerUserSetting* setting = GetUserSetting(userId);
if (setting == nullptr || setting->GetUserState() != UserState::USER_STATE_UNLOCKED) {
IMSA_HILOGE("Aborted! %s %d\n", ErrorCode::ToString(ErrorCode::ERROR_USER_NOT_UNLOCKED), userId);
return ErrorCode::ERROR_USER_NOT_UNLOCKED;
}
PerUserSession* session = GetUserSession(userId);
session->OnPackageRemoved(packageName);
bool securityImeFlag = false;
int32_t ret = setting->OnPackageRemoved(packageName, &securityImeFlag);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGI("End...\n");
return ret;
}
if (securityImeFlag == true) {
InputMethodProperty* securityIme = setting->GetSecurityInputMethod();
InputMethodProperty* defaultIme = setting->GetCurrentInputMethod();
GetUserSession(userId)->ResetIme(defaultIme, securityIme);
}
return 0;
}
/*! Called when input method setting data is changed.
\n Run in work thread of input method management service
\param msg the parameters from remote binder are saved in msg->msgContent_
\return ErrorCode::NO_ERROR
\return ErrorCode::ERROR_USER_NOT_UNLOCKED user not unlocked
\return ErrorCode::ERROR_BAD_PARAMETERS bad parameter
*/
int32_t InputMethodSystemAbility::OnSettingChanged(const Message* msg)
{
IMSA_HILOGI("Start...\n");
MessageParcel* data = msg->msgContent_;
int32_t userId = data->ReadInt32();
int32_t size = data->ReadInt32();
if (size < 2) {
IMSA_HILOGE("Aborted! %s\n", ErrorCode::ToString(ErrorCode::ERROR_BAD_PARAMETERS));
return ErrorCode::ERROR_BAD_PARAMETERS;
}
std::u16string updatedKey = data->ReadString16();
std::u16string updatedValue = data->ReadString16();
PerUserSetting* setting = GetUserSetting(userId);
if (setting == nullptr || setting->GetUserState() != UserState::USER_STATE_UNLOCKED) {
IMSA_HILOGE("Aborted! %s %d\n", ErrorCode::ToString(ErrorCode::ERROR_USER_NOT_UNLOCKED), userId);
return ErrorCode::ERROR_USER_NOT_UNLOCKED;
}
PerUserSession* session = GetUserSession(userId);
int32_t ret = session->OnSettingChanged(updatedKey, updatedValue);
if (ret == ErrorCode::ERROR_SETTING_SAME_VALUE) {
IMSA_HILOGI("End...No need to update\n");
return ret;
}
// PerUserSetting does not need handle keyboard type change notification
if (updatedKey == InputMethodSetting::CURRENT_KEYBOARD_TYPE_TAG ||
updatedKey == InputMethodSetting::CURRENT_SYS_KEYBOARD_TYPE_TAG) {
IMSA_HILOGI("End...\n");
return ErrorCode::NO_ERROR;
}
ret = setting->OnSettingChanged(updatedKey, updatedValue);
if (ret != 0) {
IMSA_HILOGI("End...No need to update\n");
return ret;
}
InputMethodProperty* securityIme = setting->GetSecurityInputMethod();
InputMethodProperty* defaultIme = setting->GetCurrentInputMethod();
session->ResetIme(defaultIme, securityIme);
IMSA_HILOGI("End...\n");
return ErrorCode::NO_ERROR;
}
/*! Disable input method service. Called from PerUserSession module
\n Run in work thread of input method management service
\param msg the parameters are saved in msg->msgContent_
\return ErrorCode::NO_ERROR
\return ErrorCode::ERROR_USER_NOT_UNLOCKED user not unlocked
*/
int32_t InputMethodSystemAbility::OnDisableIms(const Message* msg)
{
IMSA_HILOGI("Start...\n");
MessageParcel* data = msg->msgContent_;
int32_t userId = data->ReadInt32();
std::u16string imeId = data->ReadString16();
PerUserSetting* setting = GetUserSetting(userId);
if (setting == nullptr || setting->GetUserState() != UserState::USER_STATE_UNLOCKED) {
IMSA_HILOGE("Aborted! %s %d\n", ErrorCode::ToString(ErrorCode::ERROR_USER_NOT_UNLOCKED), userId);
return ErrorCode::ERROR_USER_NOT_UNLOCKED;
}
InputMethodSetting tmpSetting;
std::u16string key = InputMethodSetting::ENABLED_INPUT_METHODS_TAG;
tmpSetting.SetValue(key, setting->GetInputMethodSetting()->GetValue(key));
tmpSetting.RemoveEnabledInputMethod(imeId);
//Platform::Instance()->SetInputMethodSetting(userId, tmpSetting);
IMSA_HILOGI("End...\n");
return ErrorCode::NO_ERROR;
}
/*! Switch to next ime or next keyboard type. It's called by input method service
\n Run in work thread of input method management service or the work thread of PerUserSession
\param msg the parameters from remote binder are saved in msg->msgContent_
\return ErrorCode::NO_ERROR
\return ErrorCode::ERROR_USER_NOT_UNLOCKED user not unlocked
*/
int32_t InputMethodSystemAbility::OnAdvanceToNext(const Message* msg)
{
IMSA_HILOGI("Start...\n");
MessageParcel* data = msg->msgContent_;
int32_t userId = data->ReadInt32();
bool isCurrentIme = data->ReadBool();
PerUserSetting* setting = GetUserSetting(userId);
if (setting == nullptr || setting->GetUserState() != UserState::USER_STATE_UNLOCKED) {
IMSA_HILOGE("Aborted! %s %d\n", ErrorCode::ToString(ErrorCode::ERROR_USER_NOT_UNLOCKED), userId);
return ErrorCode::ERROR_USER_NOT_UNLOCKED;
}
if (isCurrentIme) {
std::map<int32_t, MessageHandler*>::const_iterator it = msgHandlers.find(userId);
if (it!=msgHandlers.end()) {
Message* destMsg = new Message(msg->msgId_, nullptr);
it->second->SendMessage(destMsg);
}
} else {
setting->OnAdvanceToNext();
}
IMSA_HILOGI("End...\n");
return ErrorCode::NO_ERROR;
}
}
}

View File

@ -0,0 +1,279 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "input_method_system_ability_stub.h"
#include "message_handler.h"
#include "ipc_skeleton.h"
namespace OHOS {
namespace MiscServices {
using namespace MessageID;
/*! Handle the transaction from the remote binder
\n Run in binder thread
\param code transaction code number
\param data the parameters from remote binder
\param[out] reply the result of the transaction replied to the remote binder
\param flags the flags of handling transaction
\return int32_t
*/
int32_t InputMethodSystemAbilityStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
MessageOption &option)
{
IMSA_HILOGI("InputMethodSystemAbilityStub::OnRemoteRequest code = %{public}u", code);
auto descriptorToken = data.ReadInterfaceToken();
if (descriptorToken != GetDescriptor()) {
return ErrorCode::ERROR_STATUS_UNKNOWN_TRANSACTION;
}
switch(code) {
case PREPARE_INPUT: {
prepareInput(data);
reply.WriteInt32(NO_ERROR);
break;
}
case RELEASE_INPUT: {
MessageParcel* msgParcel = (MessageParcel*) &data;
releaseInput(*msgParcel);
reply.WriteInt32(NO_ERROR);
break;
}
case START_INPUT: {
MessageParcel* msgParcel = (MessageParcel*) &data;
startInput(*msgParcel);
reply.WriteInt32(NO_ERROR);
break;
}
case STOP_INPUT: {
MessageParcel* msgParcel = (MessageParcel*) &data;
stopInput(*msgParcel);
reply.WriteInt32(NO_ERROR);
break;
}
case SET_INPUT_METHOD_CORE:{
MessageParcel* msgParcel = (MessageParcel*) &data;
setInputMethodCoreFromHap(*msgParcel);
reply.WriteInt32(NO_ERROR);
break;
}
case GET_DISPLAY_MODE: {
int32_t mode = 0;
int32_t status = getDisplayMode(&mode);
if (status == ErrorCode::NO_ERROR) {
reply.WriteInt32(NO_ERROR);
reply.WriteInt32(mode);
} else {
reply.WriteInt32(ErrorCode::ERROR_EX_ILLEGAL_STATE);
reply.WriteInt32(-1);
}
break;
}
case GET_KEYBOARD_WINDOW_HEIGHT: {
int32_t height = 0;
int32_t status = getKeyboardWindowHeight(&height);
if (status == ErrorCode::NO_ERROR) {
reply.WriteInt32(NO_ERROR);
reply.WriteInt32(height);
} else {
reply.WriteInt32(ErrorCode::ERROR_EX_ILLEGAL_STATE);
reply.WriteInt32(-1);
}
break;
}
case GET_CURRENT_KEYBOARD_TYPE: {
KeyboardType type;
int32_t status = getCurrentKeyboardType(&type);
if (status == ErrorCode::NO_ERROR) {
reply.WriteInt32(NO_ERROR);
reply.WriteParcelable(&type);
} else if (status == ErrorCode::ERROR_NULL_POINTER) {
reply.WriteInt32(NO_ERROR);
reply.WriteInt32(0);
} else {
reply.WriteInt32(ErrorCode::ERROR_EX_ILLEGAL_STATE);
reply.WriteInt32(-1);
}
break;
}
case LIST_INPUT_METHOD_ENABLED: {
std::vector<InputMethodProperty*> properties;
int32_t ret = listInputMethodEnabled(&properties);
if (ret != ErrorCode::NO_ERROR) {
reply.WriteInt32(ErrorCode::ERROR_EX_ILLEGAL_STATE); // write exception code
reply.WriteInt32(-1);
} else {
reply.WriteInt32(NO_ERROR);
int32_t size = properties.size();
reply.WriteInt32(size);
for(int32_t i=0; i<size; i++) {
reply.WriteParcelable(properties[i]);
}
properties.clear();
}
break;
}
case LIST_INPUT_METHOD: {
std::vector<InputMethodProperty*> properties;
int32_t ret = listInputMethod(&properties);
if (ret != ErrorCode::NO_ERROR) {
reply.WriteInt32(ErrorCode::ERROR_EX_ILLEGAL_STATE); // write exception code
reply.WriteInt32(-1);
return ret;
}
reply.WriteInt32(NO_ERROR);
int32_t size = properties.size();
reply.WriteInt32(size);
for(int32_t i=0; i<size; i++) {
reply.WriteParcelable(properties[i]);
}
properties.clear();
break;
}
case LIST_KEYBOARD_TYPE: {
std::u16string imeId = data.ReadString16();
std::vector<KeyboardType*> kbdTypes;
int32_t ret = listKeyboardType(imeId, &kbdTypes);
if (ret != ErrorCode::NO_ERROR) {
reply.WriteInt32(ErrorCode::ERROR_EX_ILLEGAL_STATE);
reply.WriteInt32(-1);
return ret;
}
reply.WriteInt32(NO_ERROR);
int32_t size = kbdTypes.size();
reply.WriteInt32(size);
for(int32_t i=0; i<size; i++) {
reply.WriteParcelable(kbdTypes[i]);
}
kbdTypes.clear();
break;
}
default: {
return BRemoteObject::OnRemoteRequest(code, data, reply, option);
}
}
return NO_ERROR;
}
/*! Prepare input
\n Send prepareInput command to work thread.
The handling of prepareInput is in the work thread of PerUserSession.
\see PerUserSession::OnPrepareInput
\param data the parcel in which the parameters are saved
*/
void InputMethodSystemAbilityStub::prepareInput(MessageParcel& data)
{
IMSA_HILOGI("InputMethodSystemAbilityStub::prepareInput");
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);
parcel->WriteInt32(data.ReadInt32());
parcel->WriteRemoteObject(data.ReadRemoteObject());
parcel->WriteRemoteObject(data.ReadRemoteObject());
parcel->WriteParcelable(data.ReadParcelable<InputAttribute>());
Message* msg = new Message(MSG_ID_PREPARE_INPUT, parcel);
MessageHandler::Instance()->SendMessage(msg);
}
/*! Release input
\n Send releaseInput command to work thread.
The handling of releaseInput is in the work thread of PerUserSession.
\see PerUserSession::OnReleaseInput
\param data the parcel in which the parameters are saved
*/
void InputMethodSystemAbilityStub::releaseInput(MessageParcel& data)
{
IMSA_HILOGE("InputMethodSystemAbilityStub::releaseInput");
int32_t uid = IPCSkeleton::GetCallingUid();
int32_t userId = getUserId(uid);
MessageParcel* parcel = new MessageParcel();
parcel->WriteInt32(userId);
parcel->WriteRemoteObject(data.ReadRemoteObject());
Message* msg = new Message(MSG_ID_RELEASE_INPUT, parcel);
MessageHandler::Instance()->SendMessage(msg);
}
/*! Start input
\n Send startInput command to work thread.
The handling of startInput is in the work thread of PerUserSession.
\see PerUserSession::OnStartInput
\param data the parcel in which the parameters are saved
*/
void InputMethodSystemAbilityStub::startInput(MessageParcel& data)
{
int32_t uid = IPCSkeleton::GetCallingUid();
int32_t userId = getUserId(uid);
MessageParcel* parcel = new MessageParcel();
parcel->WriteInt32(userId);
parcel->WriteRemoteObject(data.ReadRemoteObject());
Message* msg = new Message(MSG_ID_START_INPUT, parcel);
MessageHandler::Instance()->SendMessage(msg);
}
/*! Stop input
\n Send stopInput command to work thread.
The handling of stopInput is in the work thread of PerUserSession.
\see PerUserSession::OnStopInput
\param data the parcel in which the parameters are saved
*/
void InputMethodSystemAbilityStub::stopInput(MessageParcel& data)
{
int32_t uid = IPCSkeleton::GetCallingUid();
int32_t userId = getUserId(uid);
MessageParcel* parcel = new MessageParcel();
parcel->WriteInt32(userId);
parcel->WriteRemoteObject(data.ReadRemoteObject());
Message* msg = new Message(MSG_ID_STOP_INPUT, parcel);
MessageHandler::Instance()->SendMessage(msg);
}
/*! Prepare input
\n Send prepareInput command to work thread.
The handling of prepareInput is in the work thread of PerUserSession.
\see PerUserSession::OnPrepareInput
\param data the parcel in which the parameters are saved
*/
void InputMethodSystemAbilityStub::setInputMethodCoreFromHap(MessageParcel& data)
{
IMSA_HILOGI("InputMethodSystemAbilityStub::setInputMethodCoreFromHap");
int32_t uid = IPCSkeleton::GetCallingUid();
int32_t userId = getUserId(uid);
MessageParcel* parcel = new MessageParcel();
parcel->WriteInt32(userId);
parcel->WriteRemoteObject(data.ReadRemoteObject());
Message* msg = new Message(MSG_ID_SET_INPUT_METHOD_CORE, parcel);
MessageHandler::Instance()->SendMessage(msg);
}
/*! Get user id from uid
\param uid the uid from which the remote call is
\return return user id of the remote caller
*/
int32_t InputMethodSystemAbilityStub::getUserId(int32_t uid)
{
return uid/1000000;
}
}
}

View File

@ -0,0 +1,187 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "keyboard_type.h"
namespace OHOS {
namespace MiscServices {
using namespace std;
/*! Constructor
*/
KeyboardType::KeyboardType()
{
}
/*! Constructor from another instance
\param type the source instance
*/
KeyboardType::KeyboardType(const KeyboardType& type)
{
mId = type.mId;
mHashCode = type.mHashCode;
mLabelId = type.mLabelId;
mIconId = type.mIconId;
mIsAsciiCapable = type.mIsAsciiCapable;
mLanguage = type.mLanguage;
mInputSource = type.mInputSource;
mCustomizedValue = type.mCustomizedValue;
}
/*! Destructor
*/
KeyboardType::~KeyboardType()
{
}
/*! Get value from another instance
\param type source instance
\return return this
*/
KeyboardType& KeyboardType::operator=(const KeyboardType& type)
{
if (this == &type) {
return *this;
}
mId = type.mId;
mHashCode = type.mHashCode;
mLabelId = type.mLabelId;
mIconId = type.mIconId;
mIsAsciiCapable = type.mIsAsciiCapable;
mLanguage = type.mLanguage;
mInputSource = type.mInputSource;
mCustomizedValue = type.mCustomizedValue;
return *this;
}
/*! Write the details of object to parcel
*/
bool KeyboardType::Marshalling(Parcel &parcel) const
{
if (!(parcel.WriteInt32(mId)
&& parcel.WriteInt32(mHashCode)
&& parcel.WriteInt32(mLabelId)
&& parcel.WriteInt32(mIconId)
&& parcel.WriteBool(mIsAsciiCapable)
&& parcel.WriteString16(mLanguage)
&& parcel.WriteString16(mInputSource)
&& parcel.WriteString16(mCustomizedValue)))
return false;
return true;
}
/*! Read the details of object from parcel
\param parcel read the details of object from this parcel
\return ErrorCode::NO_ERROR
\return ErrorCode::ERROR_NULL_POINTER parcel is null
*/
KeyboardType* KeyboardType::Unmarshalling(Parcel &parcel)
{
auto info = new KeyboardType();
info->mId = parcel.ReadInt32();
info->mHashCode = parcel.ReadInt32();
info->mLabelId = parcel.ReadInt32();
info->mIconId = parcel.ReadInt32();
info->mIsAsciiCapable = parcel.ReadBool();
info->mLanguage = parcel.ReadString16();
info->mInputSource = parcel.ReadString16();
info->mCustomizedValue = parcel.ReadString16();
return info;
}
void KeyboardType::setId(int32_t typeId)
{
mId = typeId;
if (typeId != ID_NONE) {
mHashCode = typeId;
} else {
mHashCode = ID_NONE;
}
}
void KeyboardType::setLabelId(int32_t labelId)
{
mLabelId = labelId;
}
void KeyboardType::setIconId(int32_t iconId)
{
mIconId = iconId;
}
void KeyboardType::setAsciiCapability(bool isAsciiCapable)
{
mIsAsciiCapable = isAsciiCapable;
}
void KeyboardType::setLanguage(u16string language)
{
mLanguage = language;
}
void KeyboardType::setInputSource(u16string inputSource)
{
mInputSource = inputSource;
}
void KeyboardType::setCustomizedValue(u16string keyBoardTypeCustomizedValue)
{
mCustomizedValue = keyBoardTypeCustomizedValue;
}
int32_t KeyboardType::getId() const
{
return mId;
}
int32_t KeyboardType::getLabelId() const
{
return mLabelId;
}
int32_t KeyboardType::getIconId() const
{
return mIconId;
}
/*! Get hash code of the object
\return return hashCode value
*/
int KeyboardType::getHashCode() const
{
return mHashCode;
}
/*! Get language of the object
\return return the language of this object
*/
u16string KeyboardType::getLanguage() const
{
return mLanguage;
}
u16string KeyboardType::getInputSource() const
{
return mInputSource;
}
u16string KeyboardType::getCustomizedValue() const
{
return mCustomizedValue;
}
}
}

73
services/src/message.cpp Normal file
View File

@ -0,0 +1,73 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "message.h"
namespace OHOS {
namespace MiscServices {
/*! Constructor
\param msgId a message Id
\param msgContent the content of a message
*/
Message::Message(int32_t msgId, MessageParcel* msgContent)
{
msgId_ = msgId;
msgContent_ = msgContent;
if (msgContent_) {
msgContent_->RewindRead(0);
}
}
/*! Constructor
\param msg a source message
*/
Message::Message(const Message& msg)
{
msgId_ = msg.msgId_;
if (msgContent_ != nullptr) {
delete msgContent_;
}
MessageParcel* src = msg.msgContent_;
if (src) {
msgContent_ = new MessageParcel();
msgContent_->ParseFrom(src->GetData(), src->GetDataSize());
// msgContent_->RewindRead(0);
}
}
Message& Message::operator=(const Message& msg)
{
if (this == &msg) {
return *this;
}
msgId_ = msg.msgId_;
if (msgContent_ != nullptr) {
delete msgContent_;
}
if (msg.msgContent_) {
msgContent_ = new MessageParcel();
msgContent_->ParseFrom(msg.msgContent_->GetData(), msg.msgContent_->GetDataSize());
msgContent_->RewindRead(0);
}
return *this;
}
Message::~Message( ) {
if (msgContent_) {
delete msgContent_;
}
}
}
}

View File

@ -0,0 +1,80 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "message_handler.h"
namespace OHOS {
namespace MiscServices {
/*! Constructor
*/
MessageHandler::MessageHandler()
{
}
/*! Destructor
*/
MessageHandler::~MessageHandler()
{
std::unique_lock<std::mutex> lock(mMutex);
while (! mQueue.empty()) {
Message* msg = mQueue.front();
mQueue.pop();
delete msg;
}
}
/*! Send a message
\param msg a message to be sent
\note the msg pointer should not be freed by the caller
*/
void MessageHandler::SendMessage(Message* msg)
{
{
std::unique_lock<std::mutex> lock(mMutex);
mQueue.push(msg);
}
mCV.notify_one();
}
/*! Get a message
\return a pointer referred to an object of message
\note the returned pointer should be freed by the caller.
*/
Message* MessageHandler::GetMessage()
{
std::unique_lock<std::mutex> lock(mMutex);
mCV.wait(lock, [this]{
return !this->mQueue.empty();
});
Message* msg = (Message*) mQueue.front();
mQueue.pop();
return msg;
}
/*! The single instance of MessageHandler in the service
\return the pointer referred to an object.
*/
MessageHandler* MessageHandler::Instance()
{
static MessageHandler *handler = nullptr;
if (handler == nullptr) {
handler = new MessageHandler();
}
return handler;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,577 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "unistd.h" //usleep
#include "peruser_setting.h"
#include "platform.h"
#include "utils.h"
namespace OHOS {
namespace MiscServices {
/*! Constructor
\param userId the id number of this user
*/
PerUserSetting::PerUserSetting(int userId)
{
userId_ = userId;
currentImeId = Utils::to_utf16("");
userState = UserState::USER_STATE_STARTED;
}
/*! Destructor
*/
PerUserSetting::~PerUserSetting()
{
if (userState == UserState::USER_STATE_UNLOCKED) {
OnUserLocked();
}
}
/*! Initialize data for this user.
\n It's called when this user is unlocked. The work includes:
\li read all installed input method engine information from the system
\li read input method setting data from the system
*/
void PerUserSetting::Initialize()
{
userState = UserState::USER_STATE_UNLOCKED;
inputMethodProperties.clear();
int ret = Platform::Instance()->ListInputMethod(userId_, &inputMethodProperties);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("Failed to listInputMethod [%d]\n", userId_);
}
int size = inputMethodProperties.size();
if (size == 0) {
currentImeId = Utils::to_utf16("");
}
ret = Platform::Instance()->GetInputMethodSetting(userId_, &inputMethodSetting);
if (ret != ErrorCode::NO_ERROR) {
IMSA_HILOGE("Failed to getInputMethodSetting [%d]\n", userId_);
} else {
if (size > 0) {
InitInputMethodSetting();
}
}
}
/*! Add an input method engine.
\n It's called when a package is installed in the system.
\param packageName the package name of installed package.
\param[out] isSecurityIme check if the added ime is a security ime.
\return ErrorCode::NO_ERROR The installed package is an IME package, and is added in the input method management system
\return ErrorCode::ERROR_NOT_IME_PACKAGE The installed package is not an IME package.
\return ErrorCode::ERROR_IME_PACKAGE_DUPLICATED The installed package is duplicated.
*/
int PerUserSetting::OnPackageAdded(std::u16string& packageName, bool* isSecurityIme)
{
if (isSecurityIme) {
*isSecurityIme = false;
}
std::u16string imeId = GetImeId(packageName);
if (imeId.size() != 0) {
IMSA_HILOGI("%s [%d]\n", ErrorCode::ToString(ErrorCode::ERROR_IME_PACKAGE_DUPLICATED), userId_);
return ErrorCode::ERROR_IME_PACKAGE_DUPLICATED;
}
// retake the input method list installed in the system.
InputMethodProperty *property = new InputMethodProperty();
int ret = Platform::Instance()->GetInputMethodProperty(userId_, packageName, property);
if (ret != ErrorCode::NO_ERROR) {
delete property;
IMSA_HILOGI("%s [%d]\n", ErrorCode::ToString(ErrorCode::ERROR_NOT_IME_PACKAGE), userId_);
return ErrorCode::ERROR_NOT_IME_PACKAGE;
}
inputMethodProperties.push_back(property);
if (CheckIfSecurityIme(*property)) {
if (isSecurityIme) {
*isSecurityIme = true;
}
return ErrorCode::NO_ERROR;
}
std::vector<int> types;
for(int i=0; i<(int)property->mTypes.size(); i++) {
types.push_back(property->mTypes[i]->getHashCode());
}
InputMethodSetting imSetting;
std::u16string key = InputMethodSetting::ENABLED_INPUT_METHODS_TAG;
imSetting.SetValue(key, inputMethodSetting.GetValue(key));
imSetting.AddEnabledInputMethod(property->mImeId, types);
types.clear();
Platform::Instance()->SetInputMethodSetting(userId_, imSetting);
return ErrorCode::NO_ERROR;
}
/*! Remove an input method engine.
\n It's called when a package is removed from the system.
\param packageName the package name of installed package.
\param[out] isSecurityIme check if the removed ime is a security ime.
\return ErrorCode::NO_ERROR The removed package is an IME package, and is removed from the input method management system
\return ErrorCode::ERROR_NOT_IME_PACKAGE The removed package is not an IME package.
*/
int PerUserSetting::OnPackageRemoved(std::u16string& packageName, bool* isSecurityIme)
{
if (isSecurityIme) {
*isSecurityIme = false;
}
std::u16string imeId = GetImeId(packageName);
if (imeId.size() == 0) {
IMSA_HILOGI("%s [%d]\n", ErrorCode::ToString(ErrorCode::ERROR_NOT_IME_PACKAGE), userId_);
return ErrorCode::ERROR_NOT_IME_PACKAGE;
}
bool securityFlag = false;
std::vector<InputMethodProperty*>::iterator it;
for(it=inputMethodProperties.begin(); it<inputMethodProperties.end(); ++it) {
InputMethodProperty* node = (InputMethodProperty*) *it;
if (node->mImeId == imeId) {
if (CheckIfSecurityIme(*node)==true) {
securityFlag = true;
}
inputMethodProperties.erase(it);
delete node;
break;
}
}
if (securityFlag) {
if (isSecurityIme) {
*isSecurityIme = true;
}
return ErrorCode::NO_ERROR;
}
InputMethodSetting imSetting;
std::u16string key = InputMethodSetting::ENABLED_INPUT_METHODS_TAG;
imSetting.SetValue(key, inputMethodSetting.GetValue(key));
int flag = imSetting.RemoveEnabledInputMethod(imeId);
if (flag == false) {
IMSA_HILOGI("The package removed is not an enabled IME. [%d]\n", userId_);
return ErrorCode::NO_ERROR;
}
Platform::Instance()->SetInputMethodSetting(userId_, imSetting);
// wait for some time so that the setting change will not be overrided by the followed transact
usleep(100*1000);
return ErrorCode::NO_ERROR;
}
/*! Update input method setting data.
\n It's called when the input method setting data in the system is changed.
\param key the name of setting item
\param value the value of the setting item
\return ErrorCode::NO_ERROR update the setting data to input method management system.
\return ErrorCode::ERROR_SETTING_SAME_VALUE the current value is same as the one in the system.
*/
int PerUserSetting::OnSettingChanged(const std::u16string& key, const std::u16string& value)
{
std::u16string currentValue = inputMethodSetting.GetValue(key);
if (currentValue == value) {
return ErrorCode::ERROR_SETTING_SAME_VALUE;
}
inputMethodSetting.SetValue(key, value);
if (key == InputMethodSetting::CURRENT_INPUT_METHOD_TAG) {
currentImeId = inputMethodSetting.GetCurrentInputMethod();
} else if (key == InputMethodSetting::ENABLED_INPUT_METHODS_TAG) {
if ((currentImeId.size()>0 && value.find(currentImeId) == std::string::npos) ||
currentImeId.size()==0 ){
ResetCurrentInputMethod();
InputMethodSetting tmpSetting;
tmpSetting.ClearData();
tmpSetting.SetCurrentInputMethod(currentImeId);
tmpSetting.SetCurrentKeyboardType(-1);
Platform::Instance()->SetInputMethodSetting(userId_, tmpSetting);
}
}
return ErrorCode::NO_ERROR;
}
/*! Switch to the next input method service.
*/
void PerUserSetting::OnAdvanceToNext()
{
bool flag = false;
std::u16string enabledInputMethods = inputMethodSetting.GetValue(InputMethodSetting::ENABLED_INPUT_METHODS_TAG);
std::u16string imeId;
std::u16string nextImeId = Utils::to_utf16("");
InputMethodProperty* firstEnabledProperty = nullptr;
for(int i=0; i<(int)inputMethodProperties.size(); i++) {
imeId = inputMethodProperties[i]->mImeId;
if (imeId == currentImeId) {
flag = true;
} else if (enabledInputMethods.find(imeId) != std::string::npos) {
if (flag == true) {
nextImeId = imeId;
break;
} else if (firstEnabledProperty == nullptr) {
firstEnabledProperty = inputMethodProperties[i];
}
}
}
if (nextImeId.size() == 0 && firstEnabledProperty) {
nextImeId = firstEnabledProperty->mImeId;
}
// next enabled ime is not available.
if (nextImeId.size() == 0) {
IMSA_HILOGW("No next IME is available. [%d]\n", userId_);
return ;
}
InputMethodSetting tmpSetting;
tmpSetting.SetCurrentInputMethod(nextImeId);
tmpSetting.SetCurrentKeyboardType(-1);
Platform::Instance()->SetInputMethodSetting(userId_, tmpSetting);
}
/*! It's Called when this user is locked.
\n Release data for this user including:
\li release input method engine information
\li release input method setting data
*/
void PerUserSetting::OnUserLocked()
{
if (userState == UserState::USER_STATE_STARTED) {
return;
}
userState = UserState::USER_STATE_STARTED;
currentImeId = Utils::to_utf16("");
// release input method properties
std::vector<InputMethodProperty*>::iterator it;
for(it=inputMethodProperties.begin(); it<inputMethodProperties.end();) {
InputMethodProperty* node = (InputMethodProperty*) *it;
if (node != nullptr) {
it = inputMethodProperties.erase(it);
delete node;
}
}
inputMethodProperties.clear();
// release input method setting.
inputMethodSetting.ClearData();
}
/*! Print the related information for this user into the given stream
\n The information includes:
\li The user id and user state
\li The information of all input method engine installed in the system
\li The input method setting data of this user.
\param fd the raw file descriptor that the dump is being sent to
*/
void PerUserSetting::Dump(int fd)
{
int size = inputMethodProperties.size();
dprintf(fd, "\n - User Setting State :\n");
dprintf(fd, " * Installed IME count = %d\n", size);
std::vector<std::u16string> imeList = inputMethodSetting.GetEnabledInputMethodList();
size = imeList.size();
dprintf(fd, "\n * Enabled IME count : %d\n",size);
for(int i=0; i<size; i++) {
dprintf(fd, " [%d] ImeId = %s\n", i, Utils::to_utf8(imeList[i]).c_str());
std::vector<int> hashCodeList = inputMethodSetting.GetEnabledKeyboardTypes(imeList[i]);
dprintf(fd, " Enabled keyboard count = %d, hashcode list : ", hashCodeList.size());
for(int j=0; j<(int)hashCodeList.size(); j++) {
dprintf(fd, "%d", hashCodeList[j]);
if (j<(int)hashCodeList.size()-1) {
dprintf(fd, ", ");
}
}
dprintf(fd, "\n");
hashCodeList.clear();
}
imeList.clear();
}
/*! Get the state of this user
\return UserState::USER_STATE_STARTED user is started
\return UserState::USER_STATE_UNLOCKED user is unlocked
*/
int PerUserSetting::GetUserState()
{
return userState;
}
/*! Get the current IME
\return a pointer of InputMethodProperty when an IME is available.
\return null when there is no enabled IME in the system.
\note The returned pointer should NOT be freed by caller
*/
InputMethodProperty* PerUserSetting::GetCurrentInputMethod()
{
for(int i=0; i<(int)inputMethodProperties.size(); i++) {
if (currentImeId == inputMethodProperties[i]->mImeId) {
return inputMethodProperties[i];
}
}
// if default ime is null, we use security ime as default ime.
return GetSecurityInputMethod();
}
/*! Get the system security IME
\return a pointer of InputMethodProperty when an system security IME is available.
\return null when there is no security IME in the system.
\note The returned pointer should NOT be freed by caller
*/
InputMethodProperty* PerUserSetting::GetSecurityInputMethod()
{
InputMethodProperty* ime = nullptr;
std::u16string systemLocales = inputMethodSetting.GetValue(InputMethodSetting::SYSTEM_LOCALE_TAG);
for(int i=0; i<(int)inputMethodProperties.size(); i++) {
if (CheckIfSecurityIme(*inputMethodProperties[i])==false) {
continue;
}
// if systemLocales is not setting, return the first security ime
if (systemLocales.size()==0) {
return inputMethodProperties[i];
}
if (ime==nullptr) {
ime = inputMethodProperties[i];
}
for(int j=0; j<(int)inputMethodProperties[i]->mTypes.size(); j++) {
std::u16string language = inputMethodProperties[i]->mTypes[j]->getLanguage();
// if the keyboard language is in the list of system locales, return the ime
if (systemLocales.find(language) != std::string::npos) {
return inputMethodProperties[i];
}
}
}
return ime;
}
/*! Get the next enabled IME
\return a pointer of InputMethodProperty when the next enabled IME is available.
\return null when the next enabled IME is not available.
\note The returned pointer should NOT be freed by caller
*/
InputMethodProperty* PerUserSetting::GetNextInputMethod()
{
bool flag = false;
std::u16string enabledInputMethods = inputMethodSetting.GetValue(InputMethodSetting::ENABLED_INPUT_METHODS_TAG);
std::u16string imeId;
InputMethodProperty* firstEnabledProperty = nullptr;
for(int i=0; i<(int)inputMethodProperties.size(); i++) {
imeId = inputMethodProperties[i]->mImeId;
if (imeId == currentImeId) {
flag = true;
} else if (enabledInputMethods.find(imeId) != std::string::npos) {
if (flag == true) {
return inputMethodProperties[i];
} else if (firstEnabledProperty == nullptr) {
firstEnabledProperty = inputMethodProperties[i];
}
}
}
return firstEnabledProperty;
}
/*! Get the input method setting data
\return a pointer of InputMethodSetting.
\note The returned pointer should NOT be freed by caller
*/
InputMethodSetting* PerUserSetting::GetInputMethodSetting()
{
return &inputMethodSetting;
}
/*! list the details of all the enabled input method engine
\param[out] properties the details will be written to the param properties
\return ErrorCode::NO_ERROR
*/
int32_t PerUserSetting::ListInputMethodEnabled(std::vector<InputMethodProperty*> *properties)
{
std::u16string enabledInputMethods = inputMethodSetting.GetValue(InputMethodSetting::ENABLED_INPUT_METHODS_TAG);
for(int i=0; i<(int)inputMethodProperties.size(); i++) {
if (enabledInputMethods.find(inputMethodProperties[i]->mImeId) != std::string::npos) {
properties->push_back(inputMethodProperties[i]);
}
}
return ErrorCode::NO_ERROR;
}
/*! List the details of all input method engine installed in the system
\param[out] properties the details will be written to the param properties
\return ErrorCode::NO_ERROR
*/
int32_t PerUserSetting::ListInputMethod(std::vector<InputMethodProperty*> *properties)
{
for(int i=0; i<(int)inputMethodProperties.size(); i++) {
properties->push_back(inputMethodProperties[i]);
}
return ErrorCode::NO_ERROR;
}
/*! List the keyboard types of given input method engine
\param imeId the id of the given IME
\param[out] types the data of type list of the given IME will be written to types
\return ErrorCode::NO_ERROR
*/
int32_t PerUserSetting::ListKeyboardType(const std::u16string& imeId, std::vector<KeyboardType*> *types)
{
for(int i=0; i<(int)inputMethodProperties.size(); i++) {
if (imeId == inputMethodProperties[i]->mImeId) {
for(int j=0; j<(int)inputMethodProperties[i]->mTypes.size(); j++) {
types->push_back(inputMethodProperties[i]->mTypes[j]);
}
break;
}
}
return ErrorCode::NO_ERROR;
}
/*! Get the input method engine details of the given imeId
\param imeId the id of the given IME
\return a pointer of InputMethodProperty when the given IME exists.
\return null when the given IME is not available
\note the returned pointer should not be freed by the caller.
*/
InputMethodProperty* PerUserSetting::GetInputMethodProperty(const std::u16string& imeId)
{
for(int i=0; i<(int)inputMethodProperties.size(); i++) {
if (inputMethodProperties[i]->mImeId == imeId) {
return inputMethodProperties[i];
}
}
return nullptr;
}
/*! Get the language of keyboard type according to the given hashCode
\param property a pointer to an IME
\param hashCode the given hashCode
\return language value when the given hashCode is found
\return an empty string when the given hashCode is not found
*/
std::u16string PerUserSetting::GetKeyboardTypeLanguage(const InputMethodProperty* property, int hashCode)
{
for(int i=0; i<(int)property->mTypes.size(); i++) {
if (property->mTypes[i]->getHashCode() == hashCode) {
return property->mTypes[i]->getLanguage();
}
}
return Utils::to_utf16("");
}
/*! Init input method setting data
*/
void PerUserSetting::InitInputMethodSetting()
{
bool flag = inputMethodSetting.FindKey(InputMethodSetting::ENABLED_INPUT_METHODS_TAG);
if (flag == false) {
for(int i=0; i<(int)inputMethodProperties.size(); i++) {
if (CheckIfSecurityIme(*inputMethodProperties[i])==true) {
continue;
}
std::vector<int> types;
for(int j=0; j<(int)inputMethodProperties[i]->mTypes.size(); j++) {
types.push_back(inputMethodProperties[i]->mTypes[j]->getHashCode());
}
inputMethodSetting.AddEnabledInputMethod(inputMethodProperties[i]->mImeId, types);
types.clear();
}
}
flag = inputMethodSetting.FindKey(InputMethodSetting::CURRENT_INPUT_METHOD_TAG);
std::u16string imeId = inputMethodSetting.GetCurrentInputMethod();
if (flag == false) {
ResetCurrentInputMethod();
} else {
currentImeId = imeId;
}
flag = inputMethodSetting.FindKey(InputMethodSetting::CURRENT_SYS_KEYBOARD_TYPE_TAG);
if (flag==false) {
inputMethodSetting.SetCurrentSysKeyboardType(-1);
}
Platform::Instance()->SetInputMethodSetting(userId_, inputMethodSetting);
}
/*! Reset the current (default) input method engine
\li Look for the first keyboard language which is in the system locale list.
\li If no keyboard language is in system locale list, we use the first system ime as current ime.
\li If no system ime is there, we use the first enabled ime as current ime.
\li If no enabled ime, set current ime as null.
*/
void PerUserSetting::ResetCurrentInputMethod()
{
std::u16string systemLocales = inputMethodSetting.GetValue(InputMethodSetting::SYSTEM_LOCALE_TAG);
std::u16string enabledInputMethods = inputMethodSetting.GetValue(InputMethodSetting::ENABLED_INPUT_METHODS_TAG);
std::u16string imeId;
InputMethodProperty* firstEnabledIme = nullptr;
bool flag = false;
for(int i=0; i<(int)inputMethodProperties.size(); i++) {
imeId = inputMethodProperties[i]->mImeId;
if (enabledInputMethods.find(imeId) == std::string::npos) {
continue;
}
if (firstEnabledIme == nullptr) {
firstEnabledIme = inputMethodProperties[i];
}
std::vector<int> hashCodeList = inputMethodSetting.GetEnabledKeyboardTypes(imeId);
for(int j=0; j<(int)hashCodeList.size(); j++) {
std::u16string language = GetKeyboardTypeLanguage(inputMethodProperties[i], hashCodeList[j]);
if (systemLocales.find(language) != std::string::npos) {
currentImeId = imeId;
flag = true;
break;
}
}
if (flag) {
break;
}
}
// if we cannot find any keyboard type which belongs to system locales,
// we will use the first enabled ime as current ime.
if (flag == false) {
if (firstEnabledIme) {
currentImeId = firstEnabledIme->mImeId;
} else {
currentImeId = Utils::to_utf16("");
}
}
inputMethodSetting.SetCurrentInputMethod(currentImeId);
inputMethodSetting.SetCurrentKeyboardType(-1);
}
/*! Get the id of the given input method engine
\param packageName the packageName of the given IME
\return the id of the given IME
*/
std::u16string PerUserSetting::GetImeId(const std::u16string& packageName)
{
for(int i=0; i<(int)inputMethodProperties.size(); i++) {
if (inputMethodProperties[i]->mPackageName == packageName) {
return inputMethodProperties[i]->mImeId;
}
}
return Utils::to_utf16("");
}
/*! Check if the InputMethodProperty object is a security ime
\param property the InputMethodProperty object needed to be checked
\return true - It's a security Ime
\n false - It's not a security Ime
*/
bool PerUserSetting::CheckIfSecurityIme(const InputMethodProperty& property)
{
return property.isSystemIme;
}
}
}

188
services/src/platform.cpp Normal file
View File

@ -0,0 +1,188 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "global.h"
#include "platform.h"
#include "platform_callback_stub.h"
namespace OHOS {
namespace MiscServices {
void Platform::SetPlatform(const sptr < IPlatformApi >& platformApi)
{
this->platformApi = platformApi;
sptr < IPlatformCallback > cb = new PlatformCallbackStub();
this->platformApi->registerCallback(cb);
}
/*! Constructor
*/
Platform::Platform()
{
}
/*! Destructor
*/
Platform::~Platform()
{
}
/*! Single instance exists in the service
*/
Platform* Platform::Instance()
{
static Platform* platform = nullptr;
if (platform == nullptr) {
platform = new Platform();
}
return platform;
}
/*! Start an input method service
\param userId the id of the given user.
\param packageName the packageName of the given input method engine which is going to start
\param intention the intention to start the service
\return the remote object handler of started input method service.
*/
sptr < IInputMethodCore > Platform::BindInputMethodService(int userId, const std::u16string& packageName,
const std::u16string& intention)
{
if (platformApi == nullptr) {
return nullptr;
}
return platformApi->bindInputMethodService(packageName, intention, userId);
}
/*! Stop an input method service
\param userId the id of the given user.
\param packageName the packageName of the given input method engine which is going to stop
\return ErrorCode
*/
int Platform::UnbindInputMethodService(int userId, const std::u16string& packageName)
{
if (platformApi == nullptr) {
return ErrorCode::ERROR_NULL_POINTER;
}
return platformApi->unbindInputMethodService(userId, packageName);
}
/*! Create window token
\param userId the id of the given user.
\param displayId the id of display screen
\param packageName the packageName of the given input method engine
\return ErrorCode
*/
sptr < IRemoteObject > Platform::CreateWindowToken(int userId, int displayId, const std::u16string& packageName)
{
if (platformApi == nullptr) {
return nullptr;
}
return platformApi->createWindowToken(userId, displayId, packageName);
}
/*! Destroy window token
\param userId the id of the given user.
\param packageName the packageName of the given input method engine
\return ErrorCode
*/
int Platform::DestroyWindowToken(int userId, const std::u16string& packageName)
{
if (platformApi == nullptr) {
return ErrorCode::ERROR_NULL_POINTER;
}
return platformApi->destroyWindowToken(userId, packageName);
}
/*! Get all the installed input method engines for the given user
\param userId the id of the given user.
\param[out] inputMethodProperties the input method engine list installed in the system for the given user
\return ErrorCode
*/
int Platform::ListInputMethod(int userId, std::vector < InputMethodProperty* > * inputMethodProperties)
{
return 0;
}
/*! Get input method engine information of the given package for the given user
\param userId the id of the given user.
\param packageName the given package name for which to get input method engine information
\param[out] inputMethodProperty the input method engine information for the given package
\return ErrorCode
*/
int Platform::GetInputMethodProperty(int userId, const std::u16string& packageName, InputMethodProperty * inputMethodProperty)
{
if (platformApi == nullptr) {
return ErrorCode::ERROR_NULL_POINTER;
}
return platformApi->getInputMethodProperty(userId, packageName, inputMethodProperty);
}
/*! Get the input method setting data for the given user
\param userId the id of the given user
\param[out] inputMethodSetting the input method setting data for the given user
\return ErrorCode
*/
int Platform::GetInputMethodSetting(int userId, InputMethodSetting * inputMethodSetting)
{
return 0;
}
/*! Set the input method setting data for the given user
\param userId the id of the given user
\param inputMethodSetting the input method setting data for the given user
\return ErrorCode
*/
int Platform::SetInputMethodSetting(int userId, const InputMethodSetting& inputMethodSetting)
{
if (platformApi == nullptr) {
return ErrorCode::ERROR_NULL_POINTER;
}
return platformApi->setInputMethodSetting(userId, inputMethodSetting);
}
/*! Check if a physical keyboard is connected to the system
\return true - a physical keyboard is connected
\n false - no physical keyboard
*/
bool Platform::CheckPhysicalKeyboard()
{
return true;
}
/*! Check if the remote caller is from a valid window
\return true - the remote caller is from a valid window
\n false - the remote caller is not from a valid window
*/
bool Platform::IsValidWindow(int uid, int pid, int displayId)
{
(void)uid;
(void)pid;
(void)displayId;
return true;
}
/*! Check if the remote caller is from a focused window
\return true - the remote caller is from a focused window
\n false - the remote caller is not from a focused window
*/
bool Platform::IsWindowFocused(int uid, int pid, int displayId)
{
(void)uid;
(void)pid;
(void)displayId;
return true;
}
}
}

View File

@ -0,0 +1,223 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "i_platform_api.h"
#include "i_input_method_core.h"
#include "iremote_proxy.h"
#include "message_parcel.h"
#include "peer_holder.h"
#include "input_method_setting.h"
#include "peer_holder.h"
#include "utils.h"
#include <string>
#include <stdint.h>
/*! \class PlatformApiProxy
\brief The proxy implementation of IPlatformApi
\todo This class will be deleted on target platform
*/
namespace OHOS {
namespace MiscServices {
class PlatformApi : public IRemoteProxy < IPlatformApi > {
public:
PlatformApi(const sptr < IRemoteObject >& impl)
: IRemoteProxy < IPlatformApi >(impl)
{
}
~PlatformApi()
{
}
int32_t registerCallback(const sptr < IPlatformCallback >& cb)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteRemoteObject(cb->AsObject());
int32_t status = Remote()->SendRequest(REGISTER_CALLBACK, data, reply,option);
if (status != ErrorCode::NO_ERROR) {
return status;
}
int code = reply.ReadException();
if (code != 0) {
return code;
}
return ErrorCode::NO_ERROR;
}
std::u16string getInterfaceDescriptor() {
return Utils::to_utf16("20210814");
}
sptr < IInputMethodCore > bindInputMethodService(const std::u16string& packageName, const std::u16string& intention, int userId)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteString16(packageName);
data.WriteString16(intention);
data.WriteInt32(userId);
int32_t status = Remote()->SendRequest(BIND_IMS, data, reply,option);
if (status != ErrorCode::NO_ERROR) {
LOG_DEBUG("status = %s\n", ErrorCode::ToString(status));
return nullptr;
}
int code = reply.ReadException();
if (code != 0) {// code=0, means no exception.
LOG_DEBUG("exception code : %d\n", code);
return nullptr;
}
sptr < IInputMethodCore > ims = nullptr;
reply.ReadRemoteObject();
return ims;
}
int32_t unbindInputMethodService(int userId, const std::u16string& packageName)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteInt32(userId);
data.WriteString16(packageName);
int32_t status = Remote()->SendRequest(UNBIND_IMS, data, reply,option);
if (status != ErrorCode::NO_ERROR) {
return status;
}
int code = reply.ReadException();
if (code != 0) {
return code;
}
return ErrorCode::NO_ERROR;
}
sptr < IRemoteObject > createWindowToken(int userId, int displayId, const std::u16string& packageName)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteInt32(userId);
data.WriteInt32(displayId);
data.WriteString16(packageName);
int32_t status = Remote()->SendRequest(CREATE_WINDOW_TOKEN, data, reply,option);
if (status != ErrorCode::NO_ERROR) {
return nullptr;
}
int code = reply.ReadException();
if (code != 0) { // code=0, means no exception.
IMSA_HILOGE("Exception code = %d\n", code);
return nullptr;
}
sptr < IRemoteObject > token = reply.ReadRemoteObject();
return token;
}
int32_t destroyWindowToken(int userId, const std::u16string& packageName)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteInt32(userId);
data.WriteString16(packageName);
int32_t status = Remote()->SendRequest(DESTROY_WINDOW_TOKEN, data, reply,option);
if (status != ErrorCode::NO_ERROR) {
return status;
}
int code = reply.ReadException();
if (code != 0) // code=0, means no exception.
return code;
return ErrorCode::NO_ERROR;
}
int32_t listInputMethod(int userId, std::vector < InputMethodProperty* > * inputMethodProperties)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteInt32(userId);
int32_t status = Remote()->SendRequest(LIST_INPUT_METHOD, data, reply,option);
if (status != ErrorCode::NO_ERROR) {
return status;
}
int code = reply.ReadException();
if (code != 0) // code=0, means no exception.
return code;
int size = reply.ReadInt32();
for (int i = 0; i < size; i++) {
InputMethodProperty * property = new InputMethodProperty();
property = reply.ReadParcelable<InputMethodProperty>();
inputMethodProperties->push_back(property);
}
return ErrorCode::NO_ERROR;
}
virtual int32_t getInputMethodProperty(int userId, const std::u16string& packageName, InputMethodProperty * inputMethodProperty)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteInt32(userId);
data.WriteString16(packageName);
int32_t status = Remote()->SendRequest(GET_INPUT_METHOD_PROPERTY, data, reply,option);
if (status != ErrorCode::NO_ERROR) {
return status;
}
int code = reply.ReadException();
if (code != 0) // code=0, means no exception.
return code;
inputMethodProperty = reply.ReadParcelable<InputMethodProperty>();
return status;
}
int32_t getInputMethodSetting(int userId, InputMethodSetting * inputMethodSetting)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteInt32(userId);
int32_t status = Remote()->SendRequest(GET_INPUT_METHOD_SETTING, data, reply,option);
if (status != ErrorCode::NO_ERROR) {
return status;
}
int code = reply.ReadException();
if (code != 0) // code=0, means no exception.
return code;
inputMethodSetting = reply.ReadParcelable<InputMethodSetting>();
return status;
}
int32_t setInputMethodSetting(int userId, const InputMethodSetting& inputMethodSetting)
{
MessageParcel data, reply;
MessageOption option;
data.WriteInterfaceToken(GetDescriptor());
data.WriteInt32(userId);
data.WriteParcelable(&inputMethodSetting);
int32_t status = Remote()->SendRequest(SET_INPUT_METHOD_SETTING, data, reply,option);
if (status != ErrorCode::NO_ERROR) {
return status;
}
int code = reply.ReadException();
if (code != 0) // code=0, means no exception.
return code;
return ErrorCode::NO_ERROR;
}
};
}
}

View File

@ -0,0 +1,49 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string>
#include "iremote_proxy.h"
#include "iremote_object.h"
#include "global.h"
#include "i_platform_callback.h"
/*! \class PlatformCallbackProxy
\brief The proxy of IPlatformCallback
\todo This class will be deleted on target platform
*/
namespace OHOS {
namespace MiscServices {
class PlatformCallbackProxy : public IRemoteProxy < IPlatformCallback > {
public:
PlatformCallbackProxy(const sptr < IRemoteObject >& impl)
: IRemoteProxy < IPlatformCallback >(impl)
{
}
~PlatformCallbackProxy()
{
}
void notifyEvent(int eventId, int userId, const std::vector < std::u16string >& eventContent)
{
(void)eventId;
(void)userId;
(void)eventContent;
}
};
}
}

View File

@ -0,0 +1,100 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "message_handler.h"
#include "message.h"
#include "message_parcel.h"
#include "message_option.h"
#include "global.h"
#include "platform_callback_stub.h"
namespace OHOS {
namespace MiscServices {
using namespace MessageID;
PlatformCallbackStub::PlatformCallbackStub() {
}
PlatformCallbackStub::~PlatformCallbackStub() {
}
int PlatformCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel & data, MessageParcel & reply, MessageOption & option) {
switch (code) {
case NOTIFY_EVENT: {
int eventId = data.ReadInt32();
int userId = data.ReadInt32();
std::vector < std::u16string > eventContent;
int size = data.ReadInt32();
for (int i = 0; i < size; i++) {
eventContent.push_back(data.ReadString16());
}
notifyEvent(eventId, userId, eventContent);
break;
}
default: {
return IRemoteStub::OnRemoteRequest(code, data, reply, option);
}
}
return NO_ERROR;
}
void PlatformCallbackStub::notifyEvent(int eventId, int userId, const std::vector<std::u16string>& eventContent) {
int msgId = 0;
switch (eventId) {
case CommonEvent::COMMON_EVENT_USER_STARTED: {
msgId = MSG_ID_USER_START;
break;
}
case CommonEvent::COMMON_EVENT_USER_STOPPED: {
msgId = MSG_ID_USER_STOP;
break;
}
case CommonEvent::COMMON_EVENT_USER_UNLOCKED: {
msgId = MSG_ID_USER_UNLOCK;
break;
}
case CommonEvent::COMMON_EVENT_USER_LOCKED: {
msgId = MSG_ID_USER_LOCK;
break;
}
case CommonEvent::COMMON_EVENT_SETTING_CHANGED: {
msgId = MSG_ID_SETTING_CHANGED;
break;
}
case CommonEvent::COMMON_EVENT_PACKAGE_ADDED: {
msgId = MSG_ID_PACKAGE_ADDED;
break;
}
case CommonEvent::COMMON_EVENT_PACKAGE_REMOVED: {
msgId = MSG_ID_PACKAGE_REMOVED;
break;
}
default: {
return ;
}
}
MessageParcel* parcel = new MessageParcel();
parcel->WriteInt32(userId);
int size = eventContent.size();
parcel->WriteInt32(size);
for (int i = 0; i < size; i++) {
parcel->WriteString16(eventContent[i]);
}
Message* msg = new Message(msgId, parcel);
MessageHandler::Instance()->SendMessage(msg);
}
}
}

98
unitest/BUILD.gn Normal file
View File

@ -0,0 +1,98 @@
# Copyright (C) 2021 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("//build/test.gni")
config("module_private_config") {
visibility = [ ":*" ]
include_dirs = [
"include",
]
}
module_output_path = "inputmethod_native/inputmethod_service"
ohos_unittest("InputMethodControllerTest") {
module_out_path = module_output_path
sources = [
"src/test_imc.cpp"]
configs = [
":module_private_config",
]
deps = [
"//base/miscservices/inputmethod/frameworks/inputmethod_controller:inputmethod_client",
"//base/miscservices/inputmethod/frameworks/inputmethod_ability:inputmethod_ability",
"//base/miscservices/inputmethod/services:inputmethod_service",
"//utils/native/base:utils",
"//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core",
"//foundation/communication/ipc/interfaces/innerkits/ipc_single:ipc_single",
"//third_party/googletest:gtest_main",
"//utils/native/base:utils",
"//foundation/aafwk/standard/services/abilitymgr:abilityms",
"//foundation/aafwk/standard/interfaces/innerkits/ability_manager:ability_manager",
"//foundation/distributedschedule/dmsfwk/interfaces/innerkits/uri:zuri",
"//foundation/aafwk/standard/interfaces/innerkits/want:want",
"//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk",
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
"//foundation/ace/napi/:ace_napi",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
]
}
ohos_unittest("InputMethodAbilityTest") {
module_out_path = module_output_path
sources = [
"src/test_ima.cpp"]
configs = [
":module_private_config",
]
deps = [
"//base/miscservices/inputmethod/frameworks/inputmethod_controller:inputmethod_client",
"//base/miscservices/inputmethod/frameworks/inputmethod_ability:inputmethod_ability",
"//base/miscservices/inputmethod/services:inputmethod_service",
"//utils/native/base:utils",
"//foundation/communication/ipc/interfaces/innerkits/ipc_core:ipc_core",
"//foundation/communication/ipc/interfaces/innerkits/ipc_single:ipc_single",
"//third_party/googletest:gtest_main",
"//utils/native/base:utils",
"//foundation/aafwk/standard/services/abilitymgr:abilityms",
"//foundation/aafwk/standard/interfaces/innerkits/ability_manager:ability_manager",
"//foundation/distributedschedule/dmsfwk/interfaces/innerkits/uri:zuri",
"//foundation/aafwk/standard/interfaces/innerkits/want:want",
"//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk",
"//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy",
"//foundation/ace/napi/:ace_napi",
]
external_deps = [
"hiviewdfx_hilog_native:libhilog",
]
}
group("unittest") {
testonly = true
deps = []
deps += [ ":InputMethodControllerTest", ":InputMethodAbilityTest" ]
}

68
unitest/src/test_ima.cpp Normal file
View File

@ -0,0 +1,68 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <functional>
#include <gtest/gtest.h>
#include <cstdint>
#include <vector>
#include <sys/time.h>
#include <thread>
#include <string>
#include "global.h"
#include "ability_manager_interface.h"
#include "ability_connect_callback_proxy.h"
#include "system_ability_definition.h"
#include "want.h"
#include "input_method_ability_connection_stub.h"
#include "ability_connect_callback_proxy.h"
#include "sa_mgr_client.h"
#include "element_name.h"
#include "input_method_ability.h"
#include "message_handler.h"
using namespace testing::ext;
using namespace OHOS;
using namespace OHOS::MiscServices;
using namespace OHOS::AAFwk;
class InputMethodAbilityTest : public testing::Test
{
public:
static void SetUpTestCase(void);
static void TearDownTestCase(void);
void SetUp();
void TearDown();
};
void InputMethodAbilityTest::SetUpTestCase(void)
{
IMSA_HILOGI("InputMethodAbilityTest::SetUpTestCase");
}
void InputMethodAbilityTest::TearDownTestCase(void)
{
IMSA_HILOGI("InputMethodAbilityTest::TearDownTestCase");
}
void InputMethodAbilityTest::SetUp(void)
{
IMSA_HILOGI("InputMethodAbilityTest::SetUp");
}
void InputMethodAbilityTest::TearDown(void)
{
IMSA_HILOGI("InputMethodAbilityTest::TearDown");
}

112
unitest/src/test_imc.cpp Normal file
View File

@ -0,0 +1,112 @@
/*
* Copyright (C) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <functional>
#include <gtest/gtest.h>
#include <cstdint>
#include <vector>
#include <sys/time.h>
#include <thread>
#include <string>
#include "global.h"
#include "utils.h"
#include "input_method_controller.h"
#include "i_input_method_system_ability.h"
#include "i_input_method_agent.h"
#include "input_data_channel_stub.h"
#include "input_client_stub.h"
#include "iservice_registry.h"
#include "system_ability_definition.h"
using namespace testing::ext;
using namespace OHOS;
using namespace OHOS::MiscServices;
class TextListener : public OnTextChangedListener {
public:
TextListener() {}
~TextListener() {}
void InsertText(const std::u16string& text) {
IMSA_HILOGI("IMC TEST TextListener InsertText: %{public}s", Utils::to_utf8(text).c_str());
}
void DeleteBackward(int32_t length){
IMSA_HILOGI("IMC TEST TextListener DeleteBackward length: %{public}d", length);
}
void SetKeyboardStatus(bool status) {
IMSA_HILOGI("IMC TEST TextListener SetKeyboardStatus %{public}d", status);
}
};
class InputMethodControllerTest : public testing::Test
{
public:
static void SetUpTestCase(void);
static void TearDownTestCase(void);
void SetUp();
void TearDown();
};
void InputMethodControllerTest::SetUpTestCase(void)
{
IMSA_HILOGI("InputMethodControllerTest::SetUpTestCase");
}
void InputMethodControllerTest::TearDownTestCase(void)
{
IMSA_HILOGI("InputMethodControllerTest::TearDownTestCase");
}
void InputMethodControllerTest::SetUp(void)
{
IMSA_HILOGI("InputMethodControllerTest::SetUp");
}
void InputMethodControllerTest::TearDown(void)
{
IMSA_HILOGI("InputMethodControllerTest::TearDown");
}
/**
* @tc.name: Imc001
* @tc.desc: Bind IMSA.
* @tc.type: FUNC
*/
HWTEST_F(InputMethodControllerTest, Imc001, TestSize.Level0)
{
IMSA_HILOGI("IMC TEST START");
sptr<InputMethodController> imc = InputMethodController::GetInstance();
ASSERT_TRUE(imc!=nullptr);
sptr<OnTextChangedListener> textListener = new TextListener();
IMSA_HILOGI("IMC Attach START");
imc->Attach();
int waitForStatusOk =2;
sleep(waitForStatusOk);
IMSA_HILOGI("IMC ShowTextInput START");
imc->ShowTextInput(textListener);
sleep(10);
IMSA_HILOGI("IMC HideTextInput START");
imc->HideTextInput();
sleep(waitForStatusOk);
IMSA_HILOGI("IMC Close START");
imc->Close();
sleep(waitForStatusOk);
IMSA_HILOGI("IMC TEST OVER");
}