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 "input_method_ability.h"
24 #include "ipc_skeleton.h"
25 #include "message_handler.h"
26 #include "message_parcel.h"
27
28 namespace OHOS {
29 namespace MiscServices {
30 using namespace MessageID;
InputMethodCoreStub()31 InputMethodCoreStub::InputMethodCoreStub()
32 {
33 msgHandler_ = nullptr;
34 }
35
~InputMethodCoreStub()36 InputMethodCoreStub::~InputMethodCoreStub()
37 {
38 }
39
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)40 int32_t InputMethodCoreStub::OnRemoteRequest(
41 uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
42 {
43 IMSA_HILOGD("InputMethodCoreStub, code: %{public}u, callingPid: %{public}d, callingUid: %{public}d", code,
44 IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid());
45 auto descriptorToken = data.ReadInterfaceToken();
46 if (descriptorToken != IInputMethodCore::GetDescriptor()) {
47 IMSA_HILOGE("InputMethodCoreStub descriptor error");
48 return ErrorCode::ERROR_STATUS_UNKNOWN_TRANSACTION;
49 }
50 if (code >= FIRST_CALL_TRANSACTION && code < static_cast<uint32_t>(CORE_CMD_LAST)) {
51 return (this->*HANDLERS.at(code))(data, reply);
52 } else {
53 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
54 }
55 }
56
InitInputControlChannel(const sptr<IInputControlChannel> & inputControlChannel)57 int32_t InputMethodCoreStub::InitInputControlChannel(const sptr<IInputControlChannel> &inputControlChannel)
58 {
59 return SendMessage(MessageID::MSG_ID_INIT_INPUT_CONTROL_CHANNEL, [inputControlChannel](MessageParcel &data) {
60 return ITypesUtil::Marshal(data, inputControlChannel->AsObject());
61 });
62 }
63
ShowKeyboard()64 int32_t InputMethodCoreStub::ShowKeyboard()
65 {
66 return InputMethodAbility::GetInstance()->ShowKeyboard();
67 }
68
HideKeyboard()69 int32_t InputMethodCoreStub::HideKeyboard()
70 {
71 return InputMethodAbility::GetInstance()->HideKeyboard();
72 }
73
StopInputService(bool isTerminateIme)74 void InputMethodCoreStub::StopInputService(bool isTerminateIme)
75 {
76 SendMessage(MessageID::MSG_ID_STOP_INPUT_SERVICE,
77 [isTerminateIme](MessageParcel &data) { return ITypesUtil::Marshal(data, isTerminateIme); });
78 }
79
SetMessageHandler(MessageHandler * msgHandler)80 void InputMethodCoreStub::SetMessageHandler(MessageHandler *msgHandler)
81 {
82 msgHandler_ = msgHandler;
83 }
84
InitInputControlChannelOnRemote(MessageParcel & data,MessageParcel & reply)85 int32_t InputMethodCoreStub::InitInputControlChannelOnRemote(MessageParcel &data, MessageParcel &reply)
86 {
87 sptr<IRemoteObject> channelObject = data.ReadRemoteObject();
88 if (channelObject == nullptr) {
89 IMSA_HILOGE("channelObject is nullptr");
90 return reply.WriteInt32(ErrorCode::ERROR_EX_PARCELABLE) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
91 }
92 sptr<IInputControlChannel> inputControlChannel = new (std::nothrow) InputControlChannelProxy(channelObject);
93 if (inputControlChannel == nullptr) {
94 IMSA_HILOGE("failed to new inputControlChannel");
95 return reply.WriteInt32(ErrorCode::ERROR_NULL_POINTER) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
96 }
97 auto ret = InitInputControlChannel(inputControlChannel);
98 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
99 }
100
StartInputOnRemote(MessageParcel & data,MessageParcel & reply)101 int32_t InputMethodCoreStub::StartInputOnRemote(MessageParcel &data, MessageParcel &reply)
102 {
103 IMSA_HILOGI(
104 "CoreStub, callingPid/Uid: %{public}d/%{public}d", IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid());
105 bool isBindFromClient = false;
106 InputClientInfo clientInfo = {};
107 if (!ITypesUtil::Unmarshal(data, isBindFromClient, clientInfo)) {
108 IMSA_HILOGE("Unmarshal failed.");
109 return ErrorCode::ERROR_EX_PARCELABLE;
110 }
111 auto ret = StartInput(clientInfo, isBindFromClient);
112 return ITypesUtil::Marshal(reply, ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
113 }
114
SecurityChangeOnRemote(MessageParcel & data,MessageParcel & reply)115 int32_t InputMethodCoreStub::SecurityChangeOnRemote(MessageParcel &data, MessageParcel &reply)
116 {
117 int32_t security;
118 if (!ITypesUtil::Unmarshal(data, security)) {
119 IMSA_HILOGE("Unmarshal failed.");
120 return ErrorCode::ERROR_EX_PARCELABLE;
121 }
122 auto ret = InputMethodAbility::GetInstance()->OnSecurityChange(security);
123 return ITypesUtil::Marshal(reply, ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
124 }
125
SetSubtypeOnRemote(MessageParcel & data,MessageParcel & reply)126 int32_t InputMethodCoreStub::SetSubtypeOnRemote(MessageParcel &data, MessageParcel &reply)
127 {
128 SubProperty property;
129 int32_t ret = SendMessage(MessageID::MSG_ID_SET_SUBTYPE, [&data, &property](MessageParcel &parcel) {
130 return ITypesUtil::Unmarshal(data, property) && ITypesUtil::Marshal(parcel, property);
131 });
132 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
133 }
134
StopInputOnRemote(MessageParcel & data,MessageParcel & reply)135 int32_t InputMethodCoreStub::StopInputOnRemote(MessageParcel &data, MessageParcel &reply)
136 {
137 sptr<IRemoteObject> channel = nullptr;
138 if (!ITypesUtil::Unmarshal(data, channel)) {
139 IMSA_HILOGE("failed to read message parcel");
140 return ErrorCode::ERROR_EX_PARCELABLE;
141 }
142 auto ret = InputMethodAbility::GetInstance()->StopInput(channel);
143 return ITypesUtil::Marshal(reply, ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
144 }
145
IsEnableOnRemote(MessageParcel & data,MessageParcel & reply)146 int32_t InputMethodCoreStub::IsEnableOnRemote(MessageParcel &data, MessageParcel &reply)
147 {
148 bool isEnable = IsEnable();
149 return ITypesUtil::Marshal(reply, ErrorCode::NO_ERROR, isEnable) ? ErrorCode::NO_ERROR
150 : ErrorCode::ERROR_EX_PARCELABLE;
151 }
152
ShowKeyboardOnRemote(MessageParcel & data,MessageParcel & reply)153 int32_t InputMethodCoreStub::ShowKeyboardOnRemote(MessageParcel &data, MessageParcel &reply)
154 {
155 auto ret = ShowKeyboard();
156 return ITypesUtil::Marshal(reply, ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
157 }
158
HideKeyboardOnRemote(MessageParcel & data,MessageParcel & reply)159 int32_t InputMethodCoreStub::HideKeyboardOnRemote(MessageParcel &data, MessageParcel &reply)
160 {
161 auto ret = HideKeyboard();
162 return ITypesUtil::Marshal(reply, ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
163 }
164
StopInputServiceOnRemote(MessageParcel & data,MessageParcel & reply)165 int32_t InputMethodCoreStub::StopInputServiceOnRemote(MessageParcel &data, MessageParcel &reply)
166 {
167 bool isTerminateIme = false;
168 if (!ITypesUtil::Unmarshal(data, isTerminateIme)) {
169 IMSA_HILOGE("unmarshal failed");
170 return ErrorCode::ERROR_EX_PARCELABLE;
171 }
172 StopInputService(isTerminateIme);
173 return ITypesUtil::Marshal(reply, ErrorCode::NO_ERROR) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
174 }
175
IsPanelShownOnRemote(MessageParcel & data,MessageParcel & reply)176 int32_t InputMethodCoreStub::IsPanelShownOnRemote(MessageParcel &data, MessageParcel &reply)
177 {
178 PanelInfo info;
179 if (!ITypesUtil::Unmarshal(data, info)) {
180 IMSA_HILOGE("unmarshal failed");
181 return ErrorCode::ERROR_EX_PARCELABLE;
182 }
183 bool isShown = false;
184 int32_t ret = IsPanelShown(info, isShown);
185 return ITypesUtil::Marshal(reply, ret, isShown) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
186 }
187
OnClientInactiveOnRemote(MessageParcel & data,MessageParcel & reply)188 int32_t InputMethodCoreStub::OnClientInactiveOnRemote(MessageParcel &data, MessageParcel &reply)
189 {
190 sptr<IRemoteObject> channel = nullptr;
191 if (!ITypesUtil::Unmarshal(data, channel)) {
192 IMSA_HILOGE("failed to read message parcel");
193 return ErrorCode::ERROR_EX_PARCELABLE;
194 }
195 InputMethodAbility::GetInstance()->OnClientInactive(channel);
196 return ITypesUtil::Marshal(reply, ErrorCode::NO_ERROR) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
197 }
198
OnTextConfigChangeOnRemote(MessageParcel & data,MessageParcel & reply)199 int32_t InputMethodCoreStub::OnTextConfigChangeOnRemote(MessageParcel &data, MessageParcel &reply)
200 {
201 InputClientInfo clientInfo;
202 if (!ITypesUtil::Unmarshal(data, clientInfo)) {
203 IMSA_HILOGE("failed to read message parcel");
204 return ErrorCode::ERROR_EX_PARCELABLE;
205 }
206 int32_t ret = InputMethodAbility::GetInstance()->OnTextConfigChange(clientInfo);
207 return ITypesUtil::Marshal(reply, ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
208 }
209
StartInput(const InputClientInfo & clientInfo,bool isBindFromClient)210 int32_t InputMethodCoreStub::StartInput(const InputClientInfo &clientInfo, bool isBindFromClient)
211 {
212 return InputMethodAbility::GetInstance()->StartInput(clientInfo, isBindFromClient);
213 }
214
SetSubtype(const SubProperty & property)215 int32_t InputMethodCoreStub::SetSubtype(const SubProperty &property)
216 {
217 return ErrorCode::NO_ERROR;
218 }
219
OnSecurityChange(int32_t security)220 int32_t InputMethodCoreStub::OnSecurityChange(int32_t security)
221 {
222 return ErrorCode::NO_ERROR;
223 }
224
StopInput(const sptr<IInputDataChannel> & channel)225 int32_t InputMethodCoreStub::StopInput(const sptr<IInputDataChannel> &channel)
226 {
227 return ErrorCode::NO_ERROR;
228 }
229
IsEnable()230 bool InputMethodCoreStub::IsEnable()
231 {
232 return InputMethodAbility::GetInstance()->IsEnable();
233 }
234
IsPanelShown(const PanelInfo & panelInfo,bool & isShown)235 int32_t InputMethodCoreStub::IsPanelShown(const PanelInfo &panelInfo, bool &isShown)
236 {
237 return InputMethodAbility::GetInstance()->IsPanelShown(panelInfo, isShown);
238 }
239
OnClientInactive(const sptr<IInputDataChannel> & channel)240 void InputMethodCoreStub::OnClientInactive(const sptr<IInputDataChannel> &channel)
241 {
242 }
243
OnTextConfigChange(const InputClientInfo & clientInfo)244 int32_t InputMethodCoreStub::OnTextConfigChange(const InputClientInfo &clientInfo)
245 {
246 return ErrorCode::NO_ERROR;
247 }
248
SendMessage(int code,ParcelHandler input)249 int32_t InputMethodCoreStub::SendMessage(int code, ParcelHandler input)
250 {
251 IMSA_HILOGD("InputMethodCoreStub::SendMessage");
252 if (msgHandler_ == nullptr) {
253 IMSA_HILOGE("InputMethodCoreStub::msgHandler_ is nullptr");
254 return ErrorCode::ERROR_EX_NULL_POINTER;
255 }
256 auto *parcel = new (std::nothrow) MessageParcel();
257 if (parcel == nullptr) {
258 IMSA_HILOGE("parcel is nullptr");
259 return ErrorCode::ERROR_EX_NULL_POINTER;
260 }
261 if (input != nullptr && (!input(*parcel))) {
262 IMSA_HILOGE("write data failed");
263 delete parcel;
264 return ErrorCode::ERROR_EX_PARCELABLE;
265 }
266 auto *msg = new (std::nothrow) Message(code, parcel);
267 if (msg == nullptr) {
268 IMSA_HILOGE("msg is nullptr");
269 delete parcel;
270 return ErrorCode::ERROR_EX_NULL_POINTER;
271 }
272 msgHandler_->SendMessage(msg);
273 return ErrorCode::NO_ERROR;
274 }
275 } // namespace MiscServices
276 } // namespace OHOS
277