1 /*
2 * Copyright (C) 2022 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 "accessibility_element_operator_callback_proxy.h"
17 #include "accessibility_element_info_parcel.h"
18 #include "hilog_wrapper.h"
19
20 namespace OHOS {
21 namespace Accessibility {
22
23 constexpr int32_t MAX_RAWDATA_SIZE = 128 * 1024 * 1024; // RawData limit is 128M, limited by IPC
24 constexpr int32_t MULTI_TRANSMIT_FINISH = -1;
25 constexpr int32_t DATA_NUMBER_ONE_TIME = 400;
26
AccessibilityElementOperatorCallbackProxy(const sptr<IRemoteObject> & impl)27 AccessibilityElementOperatorCallbackProxy::AccessibilityElementOperatorCallbackProxy(
28 const sptr<IRemoteObject> &impl) : IRemoteProxy<IAccessibilityElementOperatorCallback>(impl)
29 {}
30
~AccessibilityElementOperatorCallbackProxy()31 AccessibilityElementOperatorCallbackProxy::~AccessibilityElementOperatorCallbackProxy()
32 {}
33
WriteInterfaceToken(MessageParcel & data)34 bool AccessibilityElementOperatorCallbackProxy::WriteInterfaceToken(MessageParcel &data)
35 {
36 HILOG_DEBUG();
37 if (!data.WriteInterfaceToken(AccessibilityElementOperatorCallbackProxy::GetDescriptor())) {
38 HILOG_ERROR("write interface token failed");
39 return false;
40 }
41 return true;
42 }
43
SendTransactCmd(AccessibilityInterfaceCode code,MessageParcel & data,MessageParcel & reply,MessageOption & option)44 bool AccessibilityElementOperatorCallbackProxy::SendTransactCmd(AccessibilityInterfaceCode code,
45 MessageParcel &data, MessageParcel &reply, MessageOption &option)
46 {
47 HILOG_DEBUG();
48
49 sptr<IRemoteObject> remoteObj = Remote();
50 if (remoteObj == nullptr) {
51 HILOG_ERROR("fail to send transact cmd %{public}d due to remote object", code);
52 return false;
53 }
54 int32_t ret = remoteObj->SendRequest(static_cast<uint32_t>(code), data, reply, option);
55 if (ret != NO_ERROR) {
56 HILOG_ERROR("receive error transact code %{public}d in transact cmd %{public}d", ret, code);
57 return false;
58 }
59 return true;
60 }
61
SetSearchElementInfoByAccessibilityIdResult(const std::vector<AccessibilityElementInfo> & infos,const int32_t requestId)62 void AccessibilityElementOperatorCallbackProxy::SetSearchElementInfoByAccessibilityIdResult(
63 const std::vector<AccessibilityElementInfo> &infos, const int32_t requestId)
64 {
65 HILOG_DEBUG("infos size %{public}zu, resquestId %{public}d", infos.size(), requestId);
66 MessageParcel data;
67 MessageParcel reply;
68 MessageOption option(MessageOption::TF_ASYNC);
69 if (!WriteInterfaceToken(data)) {
70 HILOG_ERROR("connection write token failed");
71 return;
72 }
73
74 if (!data.WriteInt32(requestId)) {
75 HILOG_ERROR("connection write request id failed");
76 return;
77 }
78
79 if (!data.WriteUint32(infos.size())) {
80 HILOG_ERROR("write infos's size failed");
81 return;
82 }
83
84 if (infos.size() != 0) {
85 MessageParcel tmpParcel;
86 tmpParcel.SetMaxCapacity(MAX_RAWDATA_SIZE);
87 // when set pracel's max capacity, it won't alloc memory immediately
88 // MessageParcel will expand memory dynamiclly
89 for (const auto &info : infos) {
90 AccessibilityElementInfoParcel infoParcel(info);
91 if (!tmpParcel.WriteParcelable(&infoParcel)) {
92 HILOG_ERROR("write accessibilityElementInfoParcel failed");
93 return;
94 }
95 }
96 size_t tmpParcelSize = tmpParcel.GetDataSize();
97 if (!data.WriteUint32(tmpParcelSize)) {
98 HILOG_ERROR("write rawData size failed");
99 return;
100 }
101 if (!data.WriteRawData(reinterpret_cast<uint8_t *>(tmpParcel.GetData()), tmpParcelSize)) {
102 HILOG_ERROR("write rawData failed");
103 return;
104 }
105 }
106
107 if (!SendTransactCmd(AccessibilityInterfaceCode::SET_RESULT_BY_ACCESSIBILITY_ID, data, reply, option)) {
108 HILOG_ERROR("setSearchElementInfoByAccessibilityIdResult failed");
109 return;
110 }
111 if (static_cast<RetError>(reply.ReadInt32() != RET_OK)) {
112 HILOG_ERROR("read reply code failed");
113 }
114 return;
115 }
116
SetSearchDefaultFocusByWindowIdResult(const std::vector<AccessibilityElementInfo> & infos,const int32_t requestId)117 void AccessibilityElementOperatorCallbackProxy::SetSearchDefaultFocusByWindowIdResult(
118 const std::vector<AccessibilityElementInfo> &infos, const int32_t requestId)
119 {
120 HILOG_DEBUG("infos size %{public}zu, resquestId %{public}d", infos.size(), requestId);
121 MessageParcel data;
122 MessageParcel reply;
123 MessageOption option(MessageOption::TF_ASYNC);
124 if (!WriteInterfaceToken(data)) {
125 HILOG_ERROR("connection write token failed");
126 return;
127 }
128
129 if (!data.WriteInt32(requestId)) {
130 HILOG_ERROR("connection write request id failed");
131 return;
132 }
133
134 if (!data.WriteUint32(infos.size())) {
135 HILOG_ERROR("write infos's size failed");
136 return;
137 }
138
139 if (infos.size() != 0) {
140 MessageParcel tmpParcel;
141 tmpParcel.SetMaxCapacity(MAX_RAWDATA_SIZE);
142 // when set pracel's max capacity, it won't allocate memory immediately
143 // MessageParcel will expand memory dynamiclly
144 for (const auto &info : infos) {
145 AccessibilityElementInfoParcel infoParcel(info);
146 if (!tmpParcel.WriteParcelable(&infoParcel)) {
147 HILOG_ERROR("write accessibilityElementInfoParcel failed");
148 return;
149 }
150 }
151 size_t tmpParcelSize = tmpParcel.GetDataSize();
152 if (!data.WriteUint32(tmpParcelSize)) {
153 HILOG_ERROR("write rawData size failed");
154 return;
155 }
156 if (!data.WriteRawData(reinterpret_cast<uint8_t *>(tmpParcel.GetData()), tmpParcelSize)) {
157 HILOG_ERROR("write rawData failed");
158 return;
159 }
160 }
161
162 if (!SendTransactCmd(AccessibilityInterfaceCode::SET_RESULT_BY_WINDOW_ID, data, reply, option)) {
163 HILOG_ERROR("setSearchDefaultFocusByWindowIdResult failed");
164 return;
165 }
166 if (static_cast<RetError>(reply.ReadInt32() != RET_OK)) {
167 HILOG_ERROR("read reply code failed");
168 }
169 return;
170 }
171
SetSearchElementInfoByTextResult(const std::vector<AccessibilityElementInfo> & infos,const int32_t requestId)172 void AccessibilityElementOperatorCallbackProxy::SetSearchElementInfoByTextResult(
173 const std::vector<AccessibilityElementInfo> &infos, const int32_t requestId)
174 {
175 HILOG_DEBUG();
176 MessageParcel data;
177 MessageParcel reply;
178 MessageOption option(MessageOption::TF_ASYNC);
179
180 if (!WriteInterfaceToken(data)) {
181 HILOG_ERROR("connection write token failed");
182 return;
183 }
184
185 if (!data.WriteInt32(infos.size())) {
186 HILOG_ERROR("write infos's size failed");
187 return;
188 }
189
190 for (auto &info : infos) {
191 AccessibilityElementInfoParcel infoParcel(info);
192 if (!data.WriteParcelable(&infoParcel)) {
193 HILOG_ERROR("write accessibility element info failed");
194 return;
195 }
196 }
197
198 if (!data.WriteInt32(requestId)) {
199 HILOG_ERROR("connection write request id failed");
200 return;
201 }
202
203 if (!SendTransactCmd(AccessibilityInterfaceCode::SET_RESULT_BY_TEXT,
204 data, reply, option)) {
205 HILOG_ERROR("set search element info by text result failed");
206 return;
207 }
208 }
209
SetFindFocusedElementInfoResult(const AccessibilityElementInfo & info,const int32_t requestId)210 void AccessibilityElementOperatorCallbackProxy::SetFindFocusedElementInfoResult(
211 const AccessibilityElementInfo &info, const int32_t requestId)
212 {
213 HILOG_DEBUG();
214 MessageParcel data;
215 MessageParcel reply;
216 MessageOption option(MessageOption::TF_ASYNC);
217 AccessibilityElementInfoParcel infoParcel(info);
218
219 if (!WriteInterfaceToken(data)) {
220 HILOG_ERROR("connection write token failed");
221 return;
222 }
223
224 if (!data.WriteParcelable(&infoParcel)) {
225 HILOG_ERROR("connection write info failed");
226 return;
227 }
228 if (!data.WriteInt32(requestId)) {
229 HILOG_ERROR("connection write request id failed");
230 return;
231 }
232
233 if (!SendTransactCmd(AccessibilityInterfaceCode::SET_RESULT_FOCUSED_INFO,
234 data, reply, option)) {
235 HILOG_ERROR("set find focused element info result failed");
236 return;
237 }
238 }
239
SetFocusMoveSearchResult(const AccessibilityElementInfo & info,const int32_t requestId)240 void AccessibilityElementOperatorCallbackProxy::SetFocusMoveSearchResult(const AccessibilityElementInfo &info,
241 const int32_t requestId)
242 {
243 HILOG_DEBUG();
244 MessageParcel data;
245 MessageParcel reply;
246 MessageOption option(MessageOption::TF_ASYNC);
247 AccessibilityElementInfoParcel infoParcel(info);
248
249 if (!WriteInterfaceToken(data)) {
250 HILOG_ERROR("connection write token failed");
251 return;
252 }
253
254 if (!data.WriteParcelable(&infoParcel)) {
255 HILOG_ERROR("connection write info failed");
256 return;
257 }
258
259 if (!data.WriteInt32(requestId)) {
260 HILOG_ERROR("connection write requestId failed");
261 return;
262 }
263
264 if (!SendTransactCmd(AccessibilityInterfaceCode::SET_RESULT_FOCUS_MOVE,
265 data, reply, option)) {
266 HILOG_ERROR("set focus move search result failed");
267 return;
268 }
269 }
270
SetExecuteActionResult(const bool succeeded,const int32_t requestId)271 void AccessibilityElementOperatorCallbackProxy::SetExecuteActionResult(const bool succeeded, const int32_t requestId)
272 {
273 HILOG_DEBUG();
274 MessageParcel data;
275 MessageParcel reply;
276 MessageOption option(MessageOption::TF_ASYNC);
277
278 if (!WriteInterfaceToken(data)) {
279 HILOG_ERROR("connection write token failed");
280 return;
281 }
282
283 if (!data.WriteBool(succeeded)) {
284 HILOG_ERROR("connection write failed");
285 return;
286 }
287
288 if (!data.WriteInt32(requestId)) {
289 HILOG_ERROR("connection write request id failed");
290 return;
291 }
292
293 if (!SendTransactCmd(AccessibilityInterfaceCode::SET_RESULT_PERFORM_ACTION,
294 data, reply, option)) {
295 HILOG_ERROR("set execute action result failed");
296 return;
297 }
298 }
299
SetCursorPositionResult(const int32_t cursorPosition,const int32_t requestId)300 void AccessibilityElementOperatorCallbackProxy::SetCursorPositionResult(const int32_t cursorPosition,
301 const int32_t requestId)
302 {
303 HILOG_DEBUG();
304 MessageParcel data;
305 MessageParcel reply;
306 MessageOption option(MessageOption::TF_ASYNC);
307
308 if (!WriteInterfaceToken(data)) {
309 HILOG_ERROR("connection write token failed");
310 return;
311 }
312 HILOG_INFO(" [cursorPosition:%{public}d]", cursorPosition);
313 if (!data.WriteInt32(cursorPosition)) {
314 HILOG_ERROR("connection write failed");
315 return;
316 }
317
318 if (!data.WriteInt32(requestId)) {
319 HILOG_ERROR("connection write request id failed");
320 return;
321 }
322
323 if (!SendTransactCmd(AccessibilityInterfaceCode::SET_RESULT_CURSOR_RESULT,
324 data, reply, option)) {
325 HILOG_ERROR("set cursor position result failed");
326 return;
327 }
328 }
329
330 } // namespace Accessibility
331 } // namespace OHOS
332