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_method_agent_stub.h"
17
18 #include "global.h"
19 #include "input_method_ability.h"
20 #include "ipc_skeleton.h"
21 #include "itypes_util.h"
22 #include "message.h"
23 #include "message_handler.h"
24
25 namespace OHOS {
26 namespace MiscServices {
27 using namespace MessageID;
28
InputMethodAgentStub()29 InputMethodAgentStub::InputMethodAgentStub()
30 {
31 msgHandler_ = nullptr;
32 }
33
~InputMethodAgentStub()34 InputMethodAgentStub::~InputMethodAgentStub()
35 {
36 }
37
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)38 int32_t InputMethodAgentStub::OnRemoteRequest(
39 uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
40 {
41 IMSA_HILOGD("InputMethodAgentStub, code = %{public}u, callingPid: %{public}d, callingUid: %{public}d.", code,
42 IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid());
43 auto descriptorToken = data.ReadInterfaceToken();
44 if (descriptorToken != GetDescriptor()) {
45 return ErrorCode::ERROR_STATUS_UNKNOWN_TRANSACTION;
46 }
47
48 switch (code) {
49 case DISPATCH_KEY_EVENT: {
50 return DispatchKeyEventOnRemote(data, reply);
51 }
52 case SET_CALLING_WINDOW_ID: {
53 SetCallingWindow(data.ReadUint32());
54 break;
55 }
56 case ON_CURSOR_UPDATE: {
57 int32_t positionX = data.ReadInt32();
58 int32_t positionY = data.ReadInt32();
59 int32_t height = data.ReadInt32();
60 OnCursorUpdate(positionX, positionY, height);
61 reply.WriteNoException();
62 return ErrorCode::NO_ERROR;
63 }
64 case ON_SELECTION_CHANGE: {
65 std::u16string text = data.ReadString16();
66 int32_t oldBegin = data.ReadInt32();
67 int32_t oldEnd = data.ReadInt32();
68 int32_t newBegin = data.ReadInt32();
69 int32_t newEnd = data.ReadInt32();
70 OnSelectionChange(text, oldBegin, oldEnd, newBegin, newEnd);
71 reply.WriteNoException();
72 return ErrorCode::NO_ERROR;
73 }
74 case SEND_PRIVATE_COMMAND: {
75 return SendPrivateCommandOnRemote(data, reply);
76 }
77 case ON_ATTRIBUTE_CHANGE: {
78 return OnAttributeChangeOnRemote(data, reply);
79 }
80 case SEND_MESSAGE: {
81 return RecvMessageOnRemote(data, reply);
82 }
83 default: {
84 return IRemoteStub::OnRemoteRequest(code, data, reply, option);
85 }
86 }
87 return ErrorCode::NO_ERROR;
88 }
89
DispatchKeyEventOnRemote(MessageParcel & data,MessageParcel & reply)90 int32_t InputMethodAgentStub::DispatchKeyEventOnRemote(MessageParcel &data, MessageParcel &reply)
91 {
92 std::shared_ptr<MMI::KeyEvent> keyEvent = MMI::KeyEvent::Create();
93 if (keyEvent == nullptr) {
94 IMSA_HILOGE("keyEvent is nullptr!");
95 return ErrorCode::ERROR_NULL_POINTER;
96 }
97 if (!keyEvent->ReadFromParcel(data)) {
98 IMSA_HILOGE("failed to read key event from parcel!");
99 return ErrorCode::ERROR_EX_PARCELABLE;
100 }
101 auto consumerObject = data.ReadRemoteObject();
102 if (consumerObject == nullptr) {
103 IMSA_HILOGE("consumerObject is nullptr!");
104 return ErrorCode::ERROR_EX_PARCELABLE;
105 }
106 sptr<KeyEventConsumerProxy> consumer = new (std::nothrow) KeyEventConsumerProxy(consumerObject);
107 auto ret = InputMethodAbility::GetInstance()->DispatchKeyEvent(keyEvent, consumer);
108 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
109 }
110
SendPrivateCommandOnRemote(MessageParcel & data,MessageParcel & reply)111 int32_t InputMethodAgentStub::SendPrivateCommandOnRemote(MessageParcel &data, MessageParcel &reply)
112 {
113 std::unordered_map<std::string, PrivateDataValue> privateCommand;
114 if (!ITypesUtil::Unmarshal(data, privateCommand)) {
115 IMSA_HILOGE("failed to read message parcel!");
116 return ErrorCode::ERROR_EX_PARCELABLE;
117 }
118 auto ret = InputMethodAbility::GetInstance()->ReceivePrivateCommand(privateCommand);
119 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
120 }
121
OnAttributeChangeOnRemote(MessageParcel & data,MessageParcel & reply)122 int32_t InputMethodAgentStub::OnAttributeChangeOnRemote(MessageParcel &data, MessageParcel &reply)
123 {
124 InputAttribute attribute;
125 if (!ITypesUtil::Unmarshal(data, attribute)) {
126 IMSA_HILOGE("failed to read attribute from parcel!");
127 return ErrorCode::ERROR_EX_PARCELABLE;
128 }
129 OnAttributeChange(attribute);
130 reply.WriteNoException();
131 return ErrorCode::NO_ERROR;
132 }
133
DispatchKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent,sptr<IKeyEventConsumer> & consumer)134 int32_t InputMethodAgentStub::DispatchKeyEvent(
135 const std::shared_ptr<MMI::KeyEvent> &keyEvent, sptr<IKeyEventConsumer> &consumer)
136 {
137 return false;
138 }
139
SetCallingWindow(uint32_t windowId)140 void InputMethodAgentStub::SetCallingWindow(uint32_t windowId)
141 {
142 InputMethodAbility::GetInstance()->SetCallingWindow(windowId);
143 }
144
OnCursorUpdate(int32_t positionX,int32_t positionY,int height)145 void InputMethodAgentStub::OnCursorUpdate(int32_t positionX, int32_t positionY, int height)
146 {
147 if (msgHandler_ == nullptr) {
148 return;
149 }
150 MessageParcel *data = new MessageParcel();
151 data->WriteInt32(positionX);
152 data->WriteInt32(positionY);
153 data->WriteInt32(height);
154 Message *message = new Message(MessageID::MSG_ID_ON_CURSOR_UPDATE, data);
155 msgHandler_->SendMessage(message);
156 }
157
OnSelectionChange(std::u16string text,int32_t oldBegin,int32_t oldEnd,int32_t newBegin,int32_t newEnd)158 void InputMethodAgentStub::OnSelectionChange(
159 std::u16string text, int32_t oldBegin, int32_t oldEnd, int32_t newBegin, int32_t newEnd)
160 {
161 if (msgHandler_ == nullptr) {
162 return;
163 }
164 MessageParcel *data = new MessageParcel();
165 data->WriteString16(text);
166 data->WriteInt32(oldBegin);
167 data->WriteInt32(oldEnd);
168 data->WriteInt32(newBegin);
169 data->WriteInt32(newEnd);
170 Message *message = new Message(MessageID::MSG_ID_ON_SELECTION_CHANGE, data);
171 msgHandler_->SendMessage(message);
172 }
173
SendPrivateCommand(const std::unordered_map<std::string,PrivateDataValue> & privateCommand)174 int32_t InputMethodAgentStub::SendPrivateCommand(
175 const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
176 {
177 return ErrorCode::NO_ERROR;
178 }
179
OnAttributeChange(const InputAttribute & attribute)180 void InputMethodAgentStub::OnAttributeChange(const InputAttribute &attribute)
181 {
182 if (msgHandler_ == nullptr) {
183 IMSA_HILOGE("msgHandler_ is nullptr!");
184 return;
185 }
186 auto data = new (std::nothrow) MessageParcel();
187 if (data == nullptr) {
188 IMSA_HILOGE("failed to create message parcel!");
189 return;
190 }
191 if (!ITypesUtil::Marshal(*data, attribute)) {
192 IMSA_HILOGE("failed to write attribute!");
193 delete data;
194 return;
195 }
196 auto message = new (std::nothrow) Message(MessageID::MSG_ID_ON_ATTRIBUTE_CHANGE, data);
197 if (message == nullptr) {
198 IMSA_HILOGE("failed to create Message!");
199 delete data;
200 return;
201 }
202 msgHandler_->SendMessage(message);
203 }
204
SetMessageHandler(MessageHandler * msgHandler)205 void InputMethodAgentStub::SetMessageHandler(MessageHandler *msgHandler)
206 {
207 msgHandler_ = msgHandler;
208 }
209
RecvMessageOnRemote(MessageParcel & data,MessageParcel & reply)210 int32_t InputMethodAgentStub::RecvMessageOnRemote(MessageParcel &data, MessageParcel &reply)
211 {
212 ArrayBuffer arrayBuffer;
213 if (!ITypesUtil::Unmarshal(data, arrayBuffer)) {
214 IMSA_HILOGE("Failed to read arrayBuffer parcel!");
215 return ErrorCode::ERROR_EX_PARCELABLE;
216 }
217 auto ret = InputMethodAbility::GetInstance()->RecvMessage(arrayBuffer);
218 return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
219 }
220
SendMessage(const ArrayBuffer & arraybuffer)221 int32_t InputMethodAgentStub::SendMessage(const ArrayBuffer &arraybuffer)
222 {
223 return ErrorCode::NO_ERROR;
224 }
225 } // namespace MiscServices
226 } // namespace OHOS