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 <cstdint>
18 #include <string_ex.h>
19
20 #include "i_input_data_channel.h"
21 #include "input_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(int userId)31 InputMethodCoreStub::InputMethodCoreStub(int userId)
32 {
33 userId_ = userId;
34 msgHandler_ = nullptr;
35 }
36
~InputMethodCoreStub()37 InputMethodCoreStub::~InputMethodCoreStub()
38 {
39 }
40
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)41 int32_t InputMethodCoreStub::OnRemoteRequest(
42 uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
43 {
44 IMSA_HILOGI("InputMethodCoreStub, code = %{public}u, callingPid:%{public}d, callingUid:%{public}d", code,
45 IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid());
46 auto descriptorToken = data.ReadInterfaceToken();
47 if (descriptorToken != GetDescriptor()) {
48 IMSA_HILOGI("InputMethodCoreStub::OnRemoteRequest descriptorToken is invalid");
49 return ErrorCode::ERROR_STATUS_UNKNOWN_TRANSACTION;
50 }
51 switch (code) {
52 case INIT_INPUT_CONTROL_CHANNEL: {
53 InitInputControlChannelOnRemote(data, reply);
54 break;
55 }
56 case SHOW_KEYBOARD: {
57 ShowKeyboardOnRemote(data, reply);
58 break;
59 }
60 case HIDE_KEYBOARD: {
61 reply.WriteInt32(HideKeyboard());
62 break;
63 }
64 case STOP_INPUT_SERVICE: {
65 StopInputService(Str16ToStr8(data.ReadString16()));
66 reply.WriteInt32(ErrorCode::NO_ERROR);
67 break;
68 }
69 case SET_SUBTYPE: {
70 SetSubtypeOnRemote(data, reply);
71 break;
72 }
73 case CLEAR_DATA_CHANNEL: {
74 reply.WriteInt32(ClearDataChannelOnRemote(data));
75 break;
76 }
77 default: {
78 return IRemoteStub::OnRemoteRequest(code, data, reply, option);
79 }
80 }
81 return NO_ERROR;
82 }
83
InitInputControlChannel(sptr<IInputControlChannel> & inputControlChannel,const std::string & imeId)84 int32_t InputMethodCoreStub::InitInputControlChannel(
85 sptr<IInputControlChannel> &inputControlChannel, const std::string &imeId)
86 {
87 IMSA_HILOGD("InputMethodCoreStub::InitInputControlChannel");
88 if (msgHandler_ == nullptr) {
89 return ErrorCode::ERROR_NULL_POINTER;
90 }
91
92 MessageParcel *data = new MessageParcel();
93 if (inputControlChannel != nullptr) {
94 IMSA_HILOGD("InputMethodCoreStub, inputControlChannel is not nullptr");
95 data->WriteRemoteObject(inputControlChannel->AsObject());
96 }
97 data->WriteString(imeId);
98 Message *msg = new Message(MessageID::MSG_ID_INIT_INPUT_CONTROL_CHANNEL, data);
99 msgHandler_->SendMessage(msg);
100 return ErrorCode::NO_ERROR;
101 }
102
HideKeyboard()103 int32_t InputMethodCoreStub::HideKeyboard()
104 {
105 IMSA_HILOGD("InputMethodCoreStub::hideKeyboard");
106 return InputMethodAbility::GetInstance()->HideKeyboard();
107 }
108
StopInputService(std::string imeId)109 void InputMethodCoreStub::StopInputService(std::string imeId)
110 {
111 IMSA_HILOGD("InputMethodCoreStub::StopInputService");
112 if (!msgHandler_) {
113 return;
114 }
115 MessageParcel *data = new MessageParcel();
116 data->WriteString16(Str8ToStr16(imeId));
117
118 Message *msg = new Message(MessageID::MSG_ID_STOP_INPUT_SERVICE, data);
119 msgHandler_->SendMessage(msg);
120 }
121
SetMessageHandler(MessageHandler * msgHandler)122 void InputMethodCoreStub::SetMessageHandler(MessageHandler *msgHandler)
123 {
124 msgHandler_ = msgHandler;
125 }
126
InitInputControlChannelOnRemote(MessageParcel & data,MessageParcel & reply)127 void InputMethodCoreStub::InitInputControlChannelOnRemote(MessageParcel &data, MessageParcel &reply)
128 {
129 sptr<IRemoteObject> channelObject = data.ReadRemoteObject();
130 if (channelObject == nullptr) {
131 IMSA_HILOGE("channelObject is nullptr");
132 reply.WriteInt32(ErrorCode::ERROR_EX_PARCELABLE);
133 return;
134 }
135 sptr<IInputControlChannel> inputControlChannel = new InputControlChannelProxy(channelObject);
136 if (inputControlChannel == nullptr) {
137 IMSA_HILOGE("failed to new inputControlChannel");
138 reply.WriteInt32(ErrorCode::ERROR_NULL_POINTER);
139 return;
140 }
141 auto ret = InitInputControlChannel(inputControlChannel, data.ReadString());
142 reply.WriteInt32(ret);
143 }
144
ShowKeyboardOnRemote(MessageParcel & data,MessageParcel & reply)145 void InputMethodCoreStub::ShowKeyboardOnRemote(MessageParcel &data, MessageParcel &reply)
146 {
147 IMSA_HILOGD("InputMethodCoreStub::ShowKeyboardOnRemote");
148 sptr<IRemoteObject> channel;
149 bool isShowKeyboard = false;
150 bool attachFlag = false;
151 if (!ITypesUtil::Unmarshal(data, channel, isShowKeyboard, attachFlag)) {
152 IMSA_HILOGE("Unmarshal failed.");
153 return;
154 }
155 auto ret = InputMethodAbility::GetInstance()->ShowKeyboard(channel, isShowKeyboard, attachFlag);
156 reply.WriteInt32(ret);
157 }
158
SetSubtypeOnRemote(MessageParcel & data,MessageParcel & reply)159 void InputMethodCoreStub::SetSubtypeOnRemote(MessageParcel &data, MessageParcel &reply)
160 {
161 IMSA_HILOGD("InputMethodCoreStub::SetSubtypeOnRemote");
162 SubProperty property;
163 int32_t ret = SendMessage(MessageID::MSG_ID_SET_SUBTYPE, [&data, &property](MessageParcel &parcel) {
164 return ITypesUtil::Unmarshal(data, property) && ITypesUtil::Marshal(parcel, property);
165 });
166 reply.WriteInt32(ret);
167 }
168
ClearDataChannelOnRemote(MessageParcel & data)169 int32_t InputMethodCoreStub::ClearDataChannelOnRemote(MessageParcel &data)
170 {
171 sptr<IRemoteObject> channel = nullptr;
172 if (!ITypesUtil::Unmarshal(data, channel)) {
173 IMSA_HILOGE("failed to read message parcel");
174 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
175 }
176 InputMethodAbility::GetInstance()->ClearDataChannel(channel);
177 return ErrorCode::NO_ERROR;
178 }
179
ShowKeyboard(const sptr<IInputDataChannel> & inputDataChannel,bool isShowKeyboard,bool attachFlag)180 int32_t InputMethodCoreStub::ShowKeyboard(
181 const sptr<IInputDataChannel> &inputDataChannel, bool isShowKeyboard, bool attachFlag)
182 {
183 return ErrorCode::NO_ERROR;
184 }
185
SetSubtype(const SubProperty & property)186 int32_t InputMethodCoreStub::SetSubtype(const SubProperty &property)
187 {
188 return ErrorCode::NO_ERROR;
189 }
190
ClearDataChannel(const sptr<IInputDataChannel> & channel)191 int32_t InputMethodCoreStub::ClearDataChannel(const sptr<IInputDataChannel> &channel)
192 {
193 return ErrorCode::NO_ERROR;
194 }
195
SendMessage(int code,ParcelHandler input)196 int32_t InputMethodCoreStub::SendMessage(int code, ParcelHandler input)
197 {
198 IMSA_HILOGD("InputMethodCoreStub::SendMessage");
199 if (msgHandler_ == nullptr) {
200 IMSA_HILOGE("InputMethodCoreStub::msgHandler_ is nullptr");
201 return ErrorCode::ERROR_EX_NULL_POINTER;
202 }
203 auto *parcel = new (std::nothrow) MessageParcel();
204 if (parcel == nullptr) {
205 IMSA_HILOGE("parcel is nullptr");
206 return ErrorCode::ERROR_EX_NULL_POINTER;
207 }
208 if (input != nullptr && (!input(*parcel))) {
209 IMSA_HILOGE("write data failed");
210 delete parcel;
211 return ErrorCode::ERROR_EX_PARCELABLE;
212 }
213 auto *msg = new (std::nothrow) Message(code, parcel);
214 if (msg == nullptr) {
215 IMSA_HILOGE("msg is nullptr");
216 delete parcel;
217 return ErrorCode::ERROR_EX_NULL_POINTER;
218 }
219 msgHandler_->SendMessage(msg);
220 return ErrorCode::NO_ERROR;
221 }
222 } // namespace MiscServices
223 } // namespace OHOS
224