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
16 #include "input_data_channel_stub.h"
17
18 #include "global.h"
19 #include "input_method_controller.h"
20 #include "ipc_object_stub.h"
21 #include "ipc_skeleton.h"
22 #include "ipc_types.h"
23 #include "itypes_util.h"
24 #include "message.h"
25 namespace OHOS {
26 namespace MiscServices {
27 constexpr int32_t MAX_TIMEOUT = 2500;
InputDataChannelStub()28 InputDataChannelStub::InputDataChannelStub() : msgHandler(nullptr)
29 {
30 }
31
~InputDataChannelStub()32 InputDataChannelStub::~InputDataChannelStub()
33 {
34 }
35
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)36 int32_t InputDataChannelStub::OnRemoteRequest(
37 uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
38 {
39 IMSA_HILOGD("code = %{public}u, callingPid:%{public}d, callingUid:%{public}d", code, IPCSkeleton::GetCallingPid(),
40 IPCSkeleton::GetCallingUid());
41 auto descriptorToken = data.ReadInterfaceToken();
42 if (descriptorToken != GetDescriptor()) {
43 return ErrorCode::ERROR_STATUS_UNKNOWN_TRANSACTION;
44 }
45 switch (code) {
46 case INSERT_TEXT: {
47 reply.WriteInt32(InsertText(data.ReadString16()));
48 break;
49 }
50 case DELETE_FORWARD: {
51 reply.WriteInt32(DeleteForward(data.ReadInt32()));
52 break;
53 }
54 case DELETE_BACKWARD: {
55 reply.WriteInt32(DeleteBackward(data.ReadInt32()));
56 break;
57 }
58 case GET_TEXT_BEFORE_CURSOR: {
59 GetText(MessageID::MSG_ID_GET_TEXT_BEFORE_CURSOR, data, reply);
60 break;
61 }
62 case GET_TEXT_AFTER_CURSOR: {
63 GetText(MessageID::MSG_ID_GET_TEXT_AFTER_CURSOR, data, reply);
64 break;
65 }
66 case GET_TEXT_INDEX_AT_CURSOR: {
67 GetTextIndexAtCursor(MessageID::MSG_ID_GET_TEXT_INDEX_AT_CURSOR, data, reply);
68 break;
69 }
70 case SEND_KEYBOARD_STATUS: {
71 SendKeyboardStatus(data.ReadInt32());
72 break;
73 }
74 case SEND_FUNCTION_KEY: {
75 reply.WriteInt32(SendFunctionKey(data.ReadInt32()));
76 break;
77 }
78 case MOVE_CURSOR: {
79 reply.WriteInt32(MoveCursor(data.ReadInt32()));
80 break;
81 }
82 case GET_ENTER_KEY_TYPE: {
83 int32_t keyType = 0;
84 reply.WriteInt32(GetEnterKeyType(keyType));
85 reply.WriteInt32(keyType);
86 break;
87 }
88 case GET_INPUT_PATTERN: {
89 int32_t inputPattern = 0;
90 reply.WriteInt32(GetInputPattern(inputPattern));
91 reply.WriteInt32(inputPattern);
92 break;
93 }
94 case SELECT_BY_RANGE: {
95 SelectByRangeOnRemote(data, reply);
96 break;
97 }
98 case HANDLE_EXTEND_ACTION: {
99 HandleExtendActionOnRemote(data, reply);
100 break;
101 }
102 case SELECT_BY_MOVEMENT: {
103 SelectByMovementOnRemote(data, reply);
104 break;
105 }
106 case GET_TEXT_CONFIG: {
107 TextTotalConfig textConfig = {};
108 reply.WriteInt32(GetTextConfig(textConfig));
109 ITypesUtil::Marshal(reply, textConfig);
110 break;
111 }
112 default:
113 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
114 }
115 return NO_ERROR;
116 }
117
SelectByRangeOnRemote(MessageParcel & data,MessageParcel & reply)118 int32_t InputDataChannelStub::SelectByRangeOnRemote(MessageParcel &data, MessageParcel &reply)
119 {
120 IMSA_HILOGD("InputDataChannelStub run in");
121 int32_t start = 0;
122 int32_t end = 0;
123 int ret = SendMessage([&data, &start, &end](MessageParcel &parcel) {
124 return ITypesUtil::Unmarshal(data, start, end) && ITypesUtil::Marshal(parcel, start, end) ?
125 new (std::nothrow)Message(MessageID::MSG_ID_SELECT_BY_RANGE, &parcel) : nullptr;
126 });
127 if (!ITypesUtil::Marshal(reply, ret)) {
128 IMSA_HILOGE("failed to write reply");
129 return ErrorCode::ERROR_EX_PARCELABLE;
130 }
131 return ErrorCode::NO_ERROR;
132 }
133
SelectByMovementOnRemote(MessageParcel & data,MessageParcel & reply)134 int32_t InputDataChannelStub::SelectByMovementOnRemote(MessageParcel &data, MessageParcel &reply)
135 {
136 IMSA_HILOGD("InputDataChannelStub run in");
137 int32_t direction = 0;
138 int32_t cursorMoveSkip = 0;
139 auto ret = SendMessage([&data, &direction, &cursorMoveSkip](MessageParcel &parcel) {
140 return ITypesUtil::Unmarshal(data, direction, cursorMoveSkip)
141 && ITypesUtil::Marshal(parcel, direction, cursorMoveSkip)
142 ? new (std::nothrow) Message(MessageID::MSG_ID_SELECT_BY_MOVEMENT, &parcel)
143 : nullptr;
144 });
145 if (!ITypesUtil::Marshal(reply, ret)) {
146 IMSA_HILOGE("failed to write reply");
147 return ErrorCode::ERROR_EX_PARCELABLE;
148 }
149 return ErrorCode::NO_ERROR;
150 }
151
HandleExtendActionOnRemote(MessageParcel & data,MessageParcel & reply)152 int32_t InputDataChannelStub::HandleExtendActionOnRemote(MessageParcel &data, MessageParcel &reply)
153 {
154 IMSA_HILOGD("InputDataChannelStub run in");
155 int32_t action = 0;
156 auto ret = SendMessage([&data, &action](MessageParcel &parcel) {
157 return ITypesUtil::Unmarshal(data, action) && ITypesUtil::Marshal(parcel, action) ?
158 new (std::nothrow)Message(MessageID::MSG_ID_HANDLE_EXTEND_ACTION, &parcel) : nullptr;
159 });
160 if (!ITypesUtil::Marshal(reply, ret)) {
161 IMSA_HILOGE("failed to write reply");
162 return ErrorCode::ERROR_EX_PARCELABLE;
163 }
164 return ErrorCode::NO_ERROR;
165 }
166
InsertText(const std::u16string & text)167 int32_t InputDataChannelStub::InsertText(const std::u16string &text)
168 {
169 IMSA_HILOGI("InputDataChannelStub::InsertText");
170 if (msgHandler == nullptr) {
171 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
172 }
173 MessageParcel *parcel = new MessageParcel;
174 parcel->WriteString16(text);
175 Message *msg = new Message(MessageID::MSG_ID_INSERT_CHAR, parcel);
176 msgHandler->SendMessage(msg);
177 IMSA_HILOGI("InputDataChannelStub::InsertText return true");
178 return ErrorCode::NO_ERROR;
179 }
180
DeleteForward(int32_t length)181 int32_t InputDataChannelStub::DeleteForward(int32_t length)
182 {
183 IMSA_HILOGI("InputDataChannelStub::DeleteForward");
184 if (msgHandler == nullptr) {
185 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
186 }
187 MessageParcel *parcel = new MessageParcel;
188 parcel->WriteInt32(length);
189 Message *msg = new Message(MessageID::MSG_ID_DELETE_FORWARD, parcel);
190 msgHandler->SendMessage(msg);
191
192 return ErrorCode::NO_ERROR;
193 }
194
DeleteBackward(int32_t length)195 int32_t InputDataChannelStub::DeleteBackward(int32_t length)
196 {
197 IMSA_HILOGI("InputDataChannelStub::DeleteBackward");
198 if (msgHandler == nullptr) {
199 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
200 }
201 MessageParcel *parcel = new MessageParcel;
202 parcel->WriteInt32(length);
203 Message *msg = new Message(MessageID::MSG_ID_DELETE_BACKWARD, parcel);
204 msgHandler->SendMessage(msg);
205 return ErrorCode::NO_ERROR;
206 }
207
GetText(int32_t msgId,MessageParcel & data,MessageParcel & reply)208 int32_t InputDataChannelStub::GetText(int32_t msgId, MessageParcel &data, MessageParcel &reply)
209 {
210 IMSA_HILOGD("InputDataChannelStub::start");
211 int32_t number = -1;
212 auto resultHandler = std::make_shared<BlockData<std::u16string>>(MAX_TIMEOUT, u"");
213 auto ret = SendMessage([&msgId, &data, &number, &resultHandler](MessageParcel &parcel) {
214 return ITypesUtil::Unmarshal(data, number) && ITypesUtil::Marshal(parcel, number) ?
215 new (std::nothrow)Message(msgId, &parcel, resultHandler) : nullptr;
216 });
217 if (ret != ErrorCode::NO_ERROR) {
218 return ITypesUtil::Marshal(reply, ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
219 }
220 auto text = resultHandler->GetValue();
221 ret = resultHandler->IsTimeOut() ? ErrorCode::ERROR_CONTROLLER_INVOKING_FAILED : ErrorCode::NO_ERROR;
222 if (!ITypesUtil::Marshal(reply, ret, text)) {
223 IMSA_HILOGE("failed to write reply");
224 return ErrorCode::ERROR_EX_PARCELABLE;
225 }
226 return ErrorCode::NO_ERROR;
227 }
228
GetTextIndexAtCursor(int32_t msgId,MessageParcel & data,MessageParcel & reply)229 int32_t InputDataChannelStub::GetTextIndexAtCursor(int32_t msgId, MessageParcel &data, MessageParcel &reply)
230 {
231 IMSA_HILOGD("InputDataChannelStub::start");
232 auto resultHandler = std::make_shared<BlockData<int32_t>>(MAX_TIMEOUT, -1);
233 auto ret = SendMessage([&msgId, &resultHandler](MessageParcel &parcel) {
234 return new (std::nothrow) Message(msgId, &parcel, resultHandler);
235 });
236 if (ret != ErrorCode::NO_ERROR) {
237 return ITypesUtil::Marshal(reply, ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
238 }
239 auto index = resultHandler->GetValue();
240 ret = resultHandler->IsTimeOut() ? ErrorCode::ERROR_CONTROLLER_INVOKING_FAILED : ErrorCode::NO_ERROR;
241 if (!ITypesUtil::Marshal(reply, ret, index)) {
242 IMSA_HILOGE("failed to write reply");
243 return ErrorCode::ERROR_EX_PARCELABLE;
244 }
245 return ErrorCode::NO_ERROR;
246 }
247
GetTextBeforeCursor(int32_t number,std::u16string & text)248 int32_t InputDataChannelStub::GetTextBeforeCursor(int32_t number, std::u16string &text)
249 {
250 return ErrorCode::NO_ERROR;
251 }
252
GetTextAfterCursor(int32_t number,std::u16string & text)253 int32_t InputDataChannelStub::GetTextAfterCursor(int32_t number, std::u16string &text)
254 {
255 return ErrorCode::NO_ERROR;
256 }
257
GetTextIndexAtCursor(int32_t & index)258 int32_t InputDataChannelStub::GetTextIndexAtCursor(int32_t &index)
259 {
260 return ErrorCode::NO_ERROR;
261 }
262
GetEnterKeyType(int32_t & keyType)263 int32_t InputDataChannelStub::GetEnterKeyType(int32_t &keyType)
264 {
265 IMSA_HILOGI("InputDataChannelStub::GetEnterKeyType");
266 return InputMethodController::GetInstance()->GetEnterKeyType(keyType);
267 }
268
GetInputPattern(int32_t & inputPattern)269 int32_t InputDataChannelStub::GetInputPattern(int32_t &inputPattern)
270 {
271 IMSA_HILOGI("InputDataChannelStub::GetInputPattern");
272 return InputMethodController::GetInstance()->GetInputPattern(inputPattern);
273 }
274
GetTextConfig(TextTotalConfig & textConfig)275 int32_t InputDataChannelStub::GetTextConfig(TextTotalConfig &textConfig)
276 {
277 IMSA_HILOGI("InputDataChannelStub run in.");
278 return InputMethodController::GetInstance()->GetTextConfig(textConfig);
279 }
280
SendKeyboardStatus(int32_t status)281 void InputDataChannelStub::SendKeyboardStatus(int32_t status)
282 {
283 IMSA_HILOGI("InputDataChannelStub::SendKeyboardStatus");
284 if (msgHandler != nullptr) {
285 MessageParcel *parcel = new MessageParcel;
286 parcel->WriteInt32(status);
287 Message *msg = new Message(MessageID::MSG_ID_SEND_KEYBOARD_STATUS, parcel);
288 msgHandler->SendMessage(msg);
289 }
290 }
291
SendFunctionKey(int32_t funcKey)292 int32_t InputDataChannelStub::SendFunctionKey(int32_t funcKey)
293 {
294 IMSA_HILOGI("InputDataChannelStub::SendFunctionKey");
295 if (msgHandler == nullptr) {
296 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
297 }
298 MessageParcel *parcel = new MessageParcel;
299 parcel->WriteInt32(funcKey);
300 Message *msg = new Message(MessageID::MSG_ID_SEND_FUNCTION_KEY, parcel);
301 msgHandler->SendMessage(msg);
302 return ErrorCode::NO_ERROR;
303 }
304
MoveCursor(int32_t keyCode)305 int32_t InputDataChannelStub::MoveCursor(int32_t keyCode)
306 {
307 IMSA_HILOGI("InputDataChannelStub::MoveCursor");
308 if (msgHandler == nullptr) {
309 return ErrorCode::ERROR_CLIENT_NULL_POINTER;
310 }
311 MessageParcel *parcel = new MessageParcel;
312 parcel->WriteInt32(keyCode);
313 Message *msg = new Message(MessageID::MSG_ID_MOVE_CURSOR, parcel);
314 msgHandler->SendMessage(msg);
315 return ErrorCode::NO_ERROR;
316 }
317
SelectByRange(int32_t start,int32_t end)318 int32_t InputDataChannelStub::SelectByRange(int32_t start, int32_t end)
319 {
320 return ErrorCode::NO_ERROR;
321 }
322
SelectByMovement(int32_t direction,int32_t cursorMoveSkip)323 int32_t InputDataChannelStub::SelectByMovement(int32_t direction, int32_t cursorMoveSkip)
324 {
325 return ErrorCode::NO_ERROR;
326 }
327
HandleExtendAction(int32_t action)328 int32_t InputDataChannelStub::HandleExtendAction(int32_t action)
329 {
330 return ErrorCode::NO_ERROR;
331 }
332
SetHandler(MessageHandler * handler)333 void InputDataChannelStub::SetHandler(MessageHandler *handler)
334 {
335 msgHandler = handler;
336 }
337
SendMessage(const MsgConstructor & msgConstructor)338 int32_t InputDataChannelStub::SendMessage(const MsgConstructor &msgConstructor)
339 {
340 IMSA_HILOGD("InputMethodCoreStub run in");
341 if (msgHandler == nullptr) {
342 IMSA_HILOGE("InputMethodCoreStub msgHandler_ is nullptr");
343 return ErrorCode::ERROR_EX_NULL_POINTER;
344 }
345 auto *parcel = new (std::nothrow) MessageParcel();
346 if (parcel == nullptr) {
347 IMSA_HILOGE("parcel is nullptr");
348 return ErrorCode::ERROR_EX_NULL_POINTER;
349 }
350 auto *msg = msgConstructor(*parcel);
351 if (msg == nullptr) {
352 IMSA_HILOGE("msg is nullptr");
353 delete parcel;
354 return ErrorCode::ERROR_EX_NULL_POINTER;
355 }
356 msgHandler->SendMessage(msg);
357 return ErrorCode::NO_ERROR;
358 }
359 } // namespace MiscServices
360 } // namespace OHOS
361