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