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         default: {
81             return IRemoteStub::OnRemoteRequest(code, data, reply, option);
82         }
83     }
84     return ErrorCode::NO_ERROR;
85 }
86 
DispatchKeyEventOnRemote(MessageParcel & data,MessageParcel & reply)87 int32_t InputMethodAgentStub::DispatchKeyEventOnRemote(MessageParcel &data, MessageParcel &reply)
88 {
89     std::shared_ptr<MMI::KeyEvent> keyEvent = MMI::KeyEvent::Create();
90     if (keyEvent == nullptr) {
91         IMSA_HILOGE("keyEvent is nullptr!");
92         return ErrorCode::ERROR_NULL_POINTER;
93     }
94     if (!keyEvent->ReadFromParcel(data)) {
95         IMSA_HILOGE("failed to read key event from parcel!");
96         return ErrorCode::ERROR_EX_PARCELABLE;
97     }
98     auto consumerObject = data.ReadRemoteObject();
99     if (consumerObject == nullptr) {
100         IMSA_HILOGE("consumerObject is nullptr!");
101         return ErrorCode::ERROR_EX_PARCELABLE;
102     }
103     sptr<KeyEventConsumerProxy> consumer = new (std::nothrow) KeyEventConsumerProxy(consumerObject);
104     auto ret = InputMethodAbility::GetInstance()->DispatchKeyEvent(keyEvent, consumer);
105     return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
106 }
107 
SendPrivateCommandOnRemote(MessageParcel & data,MessageParcel & reply)108 int32_t InputMethodAgentStub::SendPrivateCommandOnRemote(MessageParcel &data, MessageParcel &reply)
109 {
110     std::unordered_map<std::string, PrivateDataValue> privateCommand;
111     if (!ITypesUtil::Unmarshal(data, privateCommand)) {
112         IMSA_HILOGE("failed to read message parcel!");
113         return ErrorCode::ERROR_EX_PARCELABLE;
114     }
115     auto ret = InputMethodAbility::GetInstance()->ReceivePrivateCommand(privateCommand);
116     return reply.WriteInt32(ret) ? ErrorCode::NO_ERROR : ErrorCode::ERROR_EX_PARCELABLE;
117 }
118 
OnAttributeChangeOnRemote(MessageParcel & data,MessageParcel & reply)119 int32_t InputMethodAgentStub::OnAttributeChangeOnRemote(MessageParcel &data, MessageParcel &reply)
120 {
121     InputAttribute attribute;
122     if (!ITypesUtil::Unmarshal(data, attribute)) {
123         IMSA_HILOGE("failed to read attribute from parcel!");
124         return ErrorCode::ERROR_EX_PARCELABLE;
125     }
126     OnAttributeChange(attribute);
127     reply.WriteNoException();
128     return ErrorCode::NO_ERROR;
129 }
130 
DispatchKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent,sptr<IKeyEventConsumer> & consumer)131 int32_t InputMethodAgentStub::DispatchKeyEvent(
132     const std::shared_ptr<MMI::KeyEvent> &keyEvent, sptr<IKeyEventConsumer> &consumer)
133 {
134     return false;
135 }
136 
SetCallingWindow(uint32_t windowId)137 void InputMethodAgentStub::SetCallingWindow(uint32_t windowId)
138 {
139     InputMethodAbility::GetInstance()->SetCallingWindow(windowId);
140 }
141 
OnCursorUpdate(int32_t positionX,int32_t positionY,int height)142 void InputMethodAgentStub::OnCursorUpdate(int32_t positionX, int32_t positionY, int height)
143 {
144     if (msgHandler_ == nullptr) {
145         return;
146     }
147     MessageParcel *data = new MessageParcel();
148     data->WriteInt32(positionX);
149     data->WriteInt32(positionY);
150     data->WriteInt32(height);
151     Message *message = new Message(MessageID::MSG_ID_ON_CURSOR_UPDATE, data);
152     msgHandler_->SendMessage(message);
153 }
154 
OnSelectionChange(std::u16string text,int32_t oldBegin,int32_t oldEnd,int32_t newBegin,int32_t newEnd)155 void InputMethodAgentStub::OnSelectionChange(
156     std::u16string text, int32_t oldBegin, int32_t oldEnd, int32_t newBegin, int32_t newEnd)
157 {
158     if (msgHandler_ == nullptr) {
159         return;
160     }
161     MessageParcel *data = new MessageParcel();
162     data->WriteString16(text);
163     data->WriteInt32(oldBegin);
164     data->WriteInt32(oldEnd);
165     data->WriteInt32(newBegin);
166     data->WriteInt32(newEnd);
167     Message *message = new Message(MessageID::MSG_ID_ON_SELECTION_CHANGE, data);
168     msgHandler_->SendMessage(message);
169 }
170 
SendPrivateCommand(const std::unordered_map<std::string,PrivateDataValue> & privateCommand)171 int32_t InputMethodAgentStub::SendPrivateCommand(
172     const std::unordered_map<std::string, PrivateDataValue> &privateCommand)
173 {
174     return ErrorCode::NO_ERROR;
175 }
176 
OnAttributeChange(const InputAttribute & attribute)177 void InputMethodAgentStub::OnAttributeChange(const InputAttribute &attribute)
178 {
179     if (msgHandler_ == nullptr) {
180         IMSA_HILOGE("msgHandler_ is nullptr!");
181         return;
182     }
183     auto data = new (std::nothrow) MessageParcel();
184     if (data == nullptr) {
185         IMSA_HILOGE("failed to create message parcel!");
186         return;
187     }
188     if (!ITypesUtil::Marshal(*data, attribute)) {
189         IMSA_HILOGE("failed to write attribute!");
190         delete data;
191         return;
192     }
193     auto message = new (std::nothrow) Message(MessageID::MSG_ID_ON_ATTRIBUTE_CHANGE, data);
194     if (message == nullptr) {
195         IMSA_HILOGE("failed to create Message!");
196         delete data;
197         return;
198     }
199     msgHandler_->SendMessage(message);
200 }
201 
SetMessageHandler(MessageHandler * msgHandler)202 void InputMethodAgentStub::SetMessageHandler(MessageHandler *msgHandler)
203 {
204     msgHandler_ = msgHandler;
205 }
206 } // namespace MiscServices
207 } // namespace OHOS