1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "input_method_core_stub.h"
16
17 #include <string_ex.h>
18
19 #include <cstdint>
20
21 #include "i_input_data_channel.h"
22 #include "input_control_channel_proxy.h"
23 #include "system_cmd_channel_proxy.h"
24 #include "input_method_ability.h"
25 #include "ipc_skeleton.h"
26 #include "itypes_util.h"
27 #include "message_handler.h"
28 #include "message_parcel.h"
29
30 namespace OHOS {
31 namespace MiscServices {
32 using namespace MessageID;
InputMethodCoreStub()33 InputMethodCoreStub::InputMethodCoreStub()
34 {
35 msgHandler_ = nullptr;
36 }
37
~InputMethodCoreStub()38 InputMethodCoreStub::~InputMethodCoreStub()
39 {
40 }
41
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)42 int32_t InputMethodCoreStub::OnRemoteRequest(
43 uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
44 {
45 IMSA_HILOGD("InputMethodCoreStub, code: %{public}u, callingPid: %{public}d, callingUid: %{public}d.", code,
46 IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid());
47 auto descriptorToken = data.ReadInterfaceToken();
48 if (descriptorToken != IInputMethodCore::GetDescriptor()) {
49 IMSA_HILOGE("InputMethodCoreStub descriptor error!");
50 return ErrorCode::ERROR_STATUS_UNKNOWN_TRANSACTION;
51 }
52 if (code < CORE_CMD_BEGIN || code >= CORE_CMD_END) {
53 IMSA_HILOGE("code error, code = %{public}u, callingPid: %{public}d, callingUid: %{public}d.", code,
54 IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid());
55 return IRemoteStub::OnRemoteRequest(code, data, reply, option);
56 }
57 return (this->*HANDLERS[code])(data, reply);
58 }
59
InitInputControlChannel(const sptr<IInputControlChannel> & inputControlChannel)60 int32_t InputMethodCoreStub::InitInputControlChannel(const sptr<IInputControlChannel> &inputControlChannel)
61 {
62 return SendMessage(MessageID::MSG_ID_INIT_INPUT_CONTROL_CHANNEL, [inputControlChannel](MessageParcel &data) {
63 return ITypesUtil::Marshal(data, inputControlChannel->AsObject());
64 });
65 }
66
ShowKeyboard()67 int32_t InputMethodCoreStub::ShowKeyboard()
68 {
69 return InputMethodAbility::GetInstance()->ShowKeyboard();
70 }
71
HideKeyboard()72 int32_t InputMethodCoreStub::HideKeyboard()
73 {
74 return InputMethodAbility::GetInstance()->HideKeyboard();
75 }
76
StopInputService(bool isTerminateIme)77 int32_t InputMethodCoreStub::StopInputService(bool isTerminateIme)
78 {
79 return InputMethodAbility::GetInstance()->OnStopInputService(isTerminateIme);
80 }
81
SetMessageHandler(MessageHandler * msgHandler)82 void InputMethodCoreStub::SetMessageHandler(MessageHandler *msgHandler)
83 {
84 msgHandler_ = msgHandler;
85 }
86
InitInputControlChannelOnRemote(MessageParcel & data,MessageParcel & reply)87 int32_t InputMethodCoreStub::InitInputControlChannelOnRemote(MessageParcel &data, MessageParcel &reply)
88 {
89 sptr<IRemoteObject> channelObject = data.ReadRemoteObject();
90 if (channelObject == nullptr) {
91 IMSA_HILOGE("channelObject is nullptr!");
92 return reply.WriteInt32(ErrorCode::ERROR_EX_PARCELABLE) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
93 }
94 sptr<IInputControlChannel> inputControlChannel = new (std::nothrow) InputControlChannelProxy(channelObject);
95 if (inputControlChannel == nullptr) {
96 IMSA_HILOGE("failed to new inputControlChannel!");
97 return reply.WriteInt32(ErrorCode::ERROR_NULL_POINTER) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
98 }
99 auto ret = InitInputControlChannel(inputControlChannel);
100 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
101 }
102
StartInputOnRemote(MessageParcel & data,MessageParcel & reply)103 int32_t InputMethodCoreStub::StartInputOnRemote(MessageParcel &data, MessageParcel &reply)
104 {
105 IMSA_HILOGI("CoreStub, callingPid/Uid: %{public}d/%{public}d.", IPCSkeleton::GetCallingPid(),
106 IPCSkeleton::GetCallingUid());
107 bool isBindFromClient = false;
108 InputClientInfo clientInfo = {};
109 sptr<IRemoteObject> channel = nullptr;
110 if (!ITypesUtil::Unmarshal(data, isBindFromClient, clientInfo, clientInfo.channel)) {
111 IMSA_HILOGE("Unmarshal failed!");
112 return ErrorCode::ERROR_EX_PARCELABLE;
113 }
114 auto ret = StartInput(clientInfo, isBindFromClient);
115 return ITypesUtil::Marshal(reply, ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
116 }
117
SecurityChangeOnRemote(MessageParcel & data,MessageParcel & reply)118 int32_t InputMethodCoreStub::SecurityChangeOnRemote(MessageParcel &data, MessageParcel &reply)
119 {
120 int32_t security;
121 if (!ITypesUtil::Unmarshal(data, security)) {
122 IMSA_HILOGE("Unmarshal failed!");
123 return ErrorCode::ERROR_EX_PARCELABLE;
124 }
125 auto ret = InputMethodAbility::GetInstance()->OnSecurityChange(security);
126 return ITypesUtil::Marshal(reply, ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
127 }
128
OnConnectSystemCmd(const sptr<IRemoteObject> & channel,sptr<IRemoteObject> & agent)129 int32_t InputMethodCoreStub::OnConnectSystemCmd(const sptr<IRemoteObject> &channel, sptr<IRemoteObject> &agent)
130 {
131 return ErrorCode::NO_ERROR;
132 }
133
OnConnectSystemCmdOnRemote(MessageParcel & data,MessageParcel & reply)134 int32_t InputMethodCoreStub::OnConnectSystemCmdOnRemote(MessageParcel &data, MessageParcel &reply)
135 {
136 sptr<IRemoteObject> channelObject = nullptr;
137 if (!ITypesUtil::Unmarshal(data, channelObject)) {
138 IMSA_HILOGE("failed to read message parcel!");
139 return ErrorCode::ERROR_EX_PARCELABLE;
140 }
141 sptr<IRemoteObject> agent = nullptr;
142 auto ret = InputMethodAbility::GetInstance()->OnConnectSystemCmd(channelObject, agent);
143 return reply.WriteInt32(ret) && reply.WriteRemoteObject(agent) ? ErrorCode::NO_ERROR
144 : ErrorCode::ERROR_EX_PARCELABLE;
145 }
146
SetSubtypeOnRemote(MessageParcel & data,MessageParcel & reply)147 int32_t InputMethodCoreStub::SetSubtypeOnRemote(MessageParcel &data, MessageParcel &reply)
148 {
149 SubProperty property;
150 int32_t ret = SendMessage(MessageID::MSG_ID_SET_SUBTYPE, [&data, &property](MessageParcel &parcel) {
151 return ITypesUtil::Unmarshal(data, property) && ITypesUtil::Marshal(parcel, property);
152 });
153 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
154 }
155
StopInputOnRemote(MessageParcel & data,MessageParcel & reply)156 int32_t InputMethodCoreStub::StopInputOnRemote(MessageParcel &data, MessageParcel &reply)
157 {
158 sptr<IRemoteObject> channel = nullptr;
159 if (!ITypesUtil::Unmarshal(data, channel)) {
160 IMSA_HILOGE("failed to read message parcel!");
161 return ErrorCode::ERROR_EX_PARCELABLE;
162 }
163 auto ret = InputMethodAbility::GetInstance()->StopInput(channel);
164 return ITypesUtil::Marshal(reply, ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
165 }
166
IsEnableOnRemote(MessageParcel & data,MessageParcel & reply)167 int32_t InputMethodCoreStub::IsEnableOnRemote(MessageParcel &data, MessageParcel &reply)
168 {
169 bool isEnable = IsEnable();
170 return ITypesUtil::Marshal(reply, ErrorCode::NO_ERROR, isEnable) ? ErrorCode::NO_ERROR
171 : ErrorCode::ERROR_EX_PARCELABLE;
172 }
173
ShowKeyboardOnRemote(MessageParcel & data,MessageParcel & reply)174 int32_t InputMethodCoreStub::ShowKeyboardOnRemote(MessageParcel &data, MessageParcel &reply)
175 {
176 auto ret = ShowKeyboard();
177 return ITypesUtil::Marshal(reply, ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
178 }
179
HideKeyboardOnRemote(MessageParcel & data,MessageParcel & reply)180 int32_t InputMethodCoreStub::HideKeyboardOnRemote(MessageParcel &data, MessageParcel &reply)
181 {
182 auto ret = HideKeyboard();
183 return ITypesUtil::Marshal(reply, ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
184 }
185
StopInputServiceOnRemote(MessageParcel & data,MessageParcel & reply)186 int32_t InputMethodCoreStub::StopInputServiceOnRemote(MessageParcel &data, MessageParcel &reply)
187 {
188 bool isTerminateIme = false;
189 if (!ITypesUtil::Unmarshal(data, isTerminateIme)) {
190 IMSA_HILOGE("unmarshal failed!");
191 return ErrorCode::ERROR_EX_PARCELABLE;
192 }
193 auto ret = StopInputService(isTerminateIme);
194 return ITypesUtil::Marshal(reply, ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
195 }
196
IsPanelShownOnRemote(MessageParcel & data,MessageParcel & reply)197 int32_t InputMethodCoreStub::IsPanelShownOnRemote(MessageParcel &data, MessageParcel &reply)
198 {
199 PanelInfo info;
200 if (!ITypesUtil::Unmarshal(data, info)) {
201 IMSA_HILOGE("unmarshal failed!");
202 return ErrorCode::ERROR_EX_PARCELABLE;
203 }
204 bool isShown = false;
205 int32_t ret = IsPanelShown(info, isShown);
206 return ITypesUtil::Marshal(reply, ret, isShown) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
207 }
208
OnClientInactiveOnRemote(MessageParcel & data,MessageParcel & reply)209 int32_t InputMethodCoreStub::OnClientInactiveOnRemote(MessageParcel &data, MessageParcel &reply)
210 {
211 sptr<IRemoteObject> channel = nullptr;
212 if (!ITypesUtil::Unmarshal(data, channel)) {
213 IMSA_HILOGE("failed to read message parcel!");
214 return ErrorCode::ERROR_EX_PARCELABLE;
215 }
216 InputMethodAbility::GetInstance()->OnClientInactive(channel);
217 return ITypesUtil::Marshal(reply, ErrorCode::NO_ERROR) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
218 }
219
StartInput(const InputClientInfo & clientInfo,bool isBindFromClient)220 int32_t InputMethodCoreStub::StartInput(const InputClientInfo &clientInfo, bool isBindFromClient)
221 {
222 return InputMethodAbility::GetInstance()->StartInput(clientInfo, isBindFromClient);
223 }
224
SetSubtype(const SubProperty & property)225 int32_t InputMethodCoreStub::SetSubtype(const SubProperty &property)
226 {
227 return ErrorCode::NO_ERROR;
228 }
229
OnSecurityChange(int32_t security)230 int32_t InputMethodCoreStub::OnSecurityChange(int32_t security)
231 {
232 return ErrorCode::NO_ERROR;
233 }
234
StopInput(const sptr<IRemoteObject> & channel)235 int32_t InputMethodCoreStub::StopInput(const sptr<IRemoteObject> &channel)
236 {
237 return ErrorCode::NO_ERROR;
238 }
239
IsEnable()240 bool InputMethodCoreStub::IsEnable()
241 {
242 return InputMethodAbility::GetInstance()->IsEnable();
243 }
244
IsPanelShown(const PanelInfo & panelInfo,bool & isShown)245 int32_t InputMethodCoreStub::IsPanelShown(const PanelInfo &panelInfo, bool &isShown)
246 {
247 return InputMethodAbility::GetInstance()->IsPanelShown(panelInfo, isShown);
248 }
249
OnClientInactive(const sptr<IRemoteObject> & channel)250 void InputMethodCoreStub::OnClientInactive(const sptr<IRemoteObject> &channel)
251 {
252 }
253
SendMessage(int code,ParcelHandler input)254 int32_t InputMethodCoreStub::SendMessage(int code, ParcelHandler input)
255 {
256 IMSA_HILOGD("InputMethodCoreStub::SendMessage start.");
257 if (msgHandler_ == nullptr) {
258 IMSA_HILOGE("InputMethodCoreStub::msgHandler_ is nullptr!");
259 return ErrorCode::ERROR_EX_NULL_POINTER;
260 }
261 auto *parcel = new (std::nothrow) MessageParcel();
262 if (parcel == nullptr) {
263 IMSA_HILOGE("parcel is nullptr!");
264 return ErrorCode::ERROR_EX_NULL_POINTER;
265 }
266 if (input != nullptr && (!input(*parcel))) {
267 IMSA_HILOGE("write data failed!");
268 delete parcel;
269 return ErrorCode::ERROR_EX_PARCELABLE;
270 }
271 auto *msg = new (std::nothrow) Message(code, parcel);
272 if (msg == nullptr) {
273 IMSA_HILOGE("msg is nullptr!");
274 delete parcel;
275 return ErrorCode::ERROR_EX_NULL_POINTER;
276 }
277 msgHandler_->SendMessage(msg);
278 return ErrorCode::NO_ERROR;
279 }
280 } // namespace MiscServices
281 } // namespace OHOS