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 "accessible_ability_channel_proxy.h"
17
18 #include <cinttypes>
19
20 #include "accessibility_element_info_parcel.h"
21 #include "accessibility_gesture_inject_path_parcel.h"
22 #include "accessibility_ipc_interface_code.h"
23 #include "accessibility_window_info_parcel.h"
24 #include "hilog_wrapper.h"
25
26 namespace OHOS {
27 namespace Accessibility {
AccessibleAbilityChannelProxy(const sptr<IRemoteObject> & object)28 AccessibleAbilityChannelProxy::AccessibleAbilityChannelProxy(
29 const sptr<IRemoteObject> &object): IRemoteProxy<IAccessibleAbilityChannel>(object)
30 {
31 }
32
WriteInterfaceToken(MessageParcel & data)33 bool AccessibleAbilityChannelProxy::WriteInterfaceToken(MessageParcel &data)
34 {
35 HILOG_DEBUG();
36
37 if (!data.WriteInterfaceToken(AccessibleAbilityChannelProxy::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 AccessibleAbilityChannelProxy::SendTransactCmd(AccessibilityInterfaceCode code,
45 MessageParcel &data, MessageParcel &reply, MessageOption &option)
46 {
47 HILOG_DEBUG();
48
49 sptr<IRemoteObject> remoteChannelProxy = Remote();
50 if (!remoteChannelProxy) {
51 HILOG_ERROR("fail to send transact cmd %{public}d due to remote object", code);
52 return false;
53 }
54 int32_t resultChannelProxy = remoteChannelProxy->SendRequest(static_cast<uint32_t>(code), data, reply, option);
55 if (resultChannelProxy != NO_ERROR) {
56 HILOG_ERROR("receive error transact code %{public}d in transact cmd %{public}d", resultChannelProxy, code);
57 return false;
58 }
59 return true;
60 }
61
SearchElementInfoByAccessibilityId(const int32_t accessibilityWindowId,const int64_t elementId,const int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback,const int32_t mode)62 RetError AccessibleAbilityChannelProxy::SearchElementInfoByAccessibilityId(const int32_t accessibilityWindowId,
63 const int64_t elementId, const int32_t requestId, const sptr<IAccessibilityElementOperatorCallback> &callback,
64 const int32_t mode)
65 {
66 HILOG_DEBUG();
67 if (!callback) {
68 HILOG_ERROR("callback is nullptr.");
69 return RET_ERR_INVALID_PARAM;
70 }
71
72 MessageParcel data;
73 MessageParcel reply;
74 MessageOption option;
75
76 if (!WriteInterfaceToken(data)) {
77 return RET_ERR_IPC_FAILED;
78 }
79 if (!data.WriteInt32(accessibilityWindowId)) {
80 HILOG_ERROR("accessibilityWindowId write error: %{public}d, ", accessibilityWindowId);
81 return RET_ERR_IPC_FAILED;
82 }
83 if (!data.WriteInt64(elementId)) {
84 HILOG_ERROR("elementId write error: %{public}" PRId64 "", elementId);
85 return RET_ERR_IPC_FAILED;
86 }
87 if (!data.WriteInt32(requestId)) {
88 HILOG_ERROR("requestId write error: %{public}d, ", requestId);
89 return RET_ERR_IPC_FAILED;
90 }
91 if (!data.WriteRemoteObject(callback->AsObject())) {
92 HILOG_ERROR("callback write error");
93 return RET_ERR_IPC_FAILED;
94 }
95 if (!data.WriteInt32(mode)) {
96 HILOG_ERROR("mode write error: %{public}d, ", mode);
97 return RET_ERR_IPC_FAILED;
98 }
99
100 if (!SendTransactCmd(AccessibilityInterfaceCode::SEARCH_ELEMENTINFO_BY_ACCESSIBILITY_ID,
101 data, reply, option)) {
102 HILOG_ERROR("fail to find elementInfo by elementId");
103 return RET_ERR_IPC_FAILED;
104 }
105 return static_cast<RetError>(reply.ReadInt32());
106 }
107
SearchElementInfosByText(const int32_t accessibilityWindowId,const int64_t elementId,const std::string & text,const int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback)108 RetError AccessibleAbilityChannelProxy::SearchElementInfosByText(const int32_t accessibilityWindowId,
109 const int64_t elementId, const std::string &text, const int32_t requestId,
110 const sptr<IAccessibilityElementOperatorCallback> &callback)
111 {
112 HILOG_DEBUG();
113
114 if (!callback) {
115 HILOG_ERROR("callback is nullptr.");
116 return RET_ERR_INVALID_PARAM;
117 }
118
119 MessageParcel data;
120 MessageParcel reply;
121 MessageOption option;
122
123 if (!WriteInterfaceToken(data)) {
124 return RET_ERR_IPC_FAILED;
125 }
126 if (!data.WriteInt32(accessibilityWindowId)) {
127 HILOG_ERROR("accessibilityWindowId write error: %{public}d, ", accessibilityWindowId);
128 return RET_ERR_IPC_FAILED;
129 }
130 if (!data.WriteInt64(elementId)) {
131 HILOG_ERROR("elementId write error: %{public}" PRId64 "", elementId);
132 return RET_ERR_IPC_FAILED;
133 }
134 if (!data.WriteString(text)) {
135 HILOG_ERROR("text write error: %{public}s, ", text.c_str());
136 return RET_ERR_IPC_FAILED;
137 }
138 if (!data.WriteInt32(requestId)) {
139 HILOG_ERROR("requestId write error: %{public}d, ", requestId);
140 return RET_ERR_IPC_FAILED;
141 }
142 if (!data.WriteRemoteObject(callback->AsObject())) {
143 HILOG_ERROR("callback write error");
144 return RET_ERR_IPC_FAILED;
145 }
146
147 if (!SendTransactCmd(AccessibilityInterfaceCode::SEARCH_ELEMENTINFOS_BY_TEXT,
148 data, reply, option)) {
149 HILOG_ERROR("fail to find elementInfo by text");
150 return RET_ERR_IPC_FAILED;
151 }
152 return static_cast<RetError>(reply.ReadInt32());
153 }
154
FindFocusedElementInfo(const int32_t accessibilityWindowId,const int64_t elementId,const int32_t focusType,const int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback)155 RetError AccessibleAbilityChannelProxy::FindFocusedElementInfo(const int32_t accessibilityWindowId,
156 const int64_t elementId, const int32_t focusType, const int32_t requestId,
157 const sptr<IAccessibilityElementOperatorCallback> &callback)
158 {
159 HILOG_DEBUG();
160 if (!callback) {
161 HILOG_ERROR("callback is nullptr.");
162 return RET_ERR_INVALID_PARAM;
163 }
164
165 MessageParcel data;
166 MessageParcel reply;
167 MessageOption option;
168
169 if (!WriteInterfaceToken(data)) {
170 return RET_ERR_IPC_FAILED;
171 }
172 if (!data.WriteInt32(accessibilityWindowId)) {
173 HILOG_ERROR("accessibilityWindowId write error: %{public}d, ", accessibilityWindowId);
174 return RET_ERR_IPC_FAILED;
175 }
176 if (!data.WriteInt64(elementId)) {
177 HILOG_ERROR("elementId write error: %{public}" PRId64 "", elementId);
178 return RET_ERR_IPC_FAILED;
179 }
180 if (!data.WriteInt32(focusType)) {
181 HILOG_ERROR("focusType write error: %{public}d, ", focusType);
182 return RET_ERR_IPC_FAILED;
183 }
184 if (!data.WriteInt32(requestId)) {
185 HILOG_ERROR("requestId write error: %{public}d, ", requestId);
186 return RET_ERR_IPC_FAILED;
187 }
188 if (!data.WriteRemoteObject(callback->AsObject())) {
189 HILOG_ERROR("callback write error");
190 return RET_ERR_IPC_FAILED;
191 }
192
193 if (!SendTransactCmd(AccessibilityInterfaceCode::FIND_FOCUSED_ELEMENTINFO, data, reply, option)) {
194 HILOG_ERROR("fail to gain focus");
195 return RET_ERR_IPC_FAILED;
196 }
197 return static_cast<RetError>(reply.ReadInt32());
198 }
199
FocusMoveSearch(const int32_t accessibilityWindowId,const int64_t elementId,const int32_t direction,const int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback)200 RetError AccessibleAbilityChannelProxy::FocusMoveSearch(const int32_t accessibilityWindowId, const int64_t elementId,
201 const int32_t direction, const int32_t requestId, const sptr<IAccessibilityElementOperatorCallback> &callback)
202 {
203 HILOG_DEBUG();
204 if (!callback) {
205 HILOG_ERROR("callback is nullptr.");
206 return RET_ERR_INVALID_PARAM;
207 }
208
209 MessageParcel data;
210 MessageParcel reply;
211 MessageOption option;
212
213 if (!WriteInterfaceToken(data)) {
214 return RET_ERR_IPC_FAILED;
215 }
216 if (!data.WriteInt32(accessibilityWindowId)) {
217 HILOG_ERROR("accessibilityWindowId write error: %{public}d, ", accessibilityWindowId);
218 return RET_ERR_IPC_FAILED;
219 }
220 if (!data.WriteInt64(elementId)) {
221 HILOG_ERROR("elementId write error: %{public}" PRId64 "", elementId);
222 return RET_ERR_IPC_FAILED;
223 }
224 if (!data.WriteInt32(direction)) {
225 HILOG_ERROR("direction write error: %{public}d, ", direction);
226 return RET_ERR_IPC_FAILED;
227 }
228 if (!data.WriteInt32(requestId)) {
229 HILOG_ERROR("requestId write error: %{public}d, ", requestId);
230 return RET_ERR_IPC_FAILED;
231 }
232 if (!data.WriteRemoteObject(callback->AsObject())) {
233 HILOG_ERROR("callback write error");
234 return RET_ERR_IPC_FAILED;
235 }
236
237 if (!SendTransactCmd(AccessibilityInterfaceCode::FOCUS_MOVE_SEARCH, data, reply, option)) {
238 HILOG_ERROR("fail to search focus");
239 return RET_ERR_IPC_FAILED;
240 }
241 return static_cast<RetError>(reply.ReadInt32());
242 }
243
ExecuteAction(const int32_t accessibilityWindowId,const int64_t elementId,const int32_t action,const std::map<std::string,std::string> & actionArguments,const int32_t requestId,const sptr<IAccessibilityElementOperatorCallback> & callback)244 RetError AccessibleAbilityChannelProxy::ExecuteAction(const int32_t accessibilityWindowId, const int64_t elementId,
245 const int32_t action, const std::map<std::string, std::string> &actionArguments, const int32_t requestId,
246 const sptr<IAccessibilityElementOperatorCallback> &callback)
247 {
248 HILOG_DEBUG();
249
250 MessageParcel data;
251 MessageParcel reply;
252 MessageOption option;
253
254 if (!WriteInterfaceToken(data)) {
255 return RET_ERR_IPC_FAILED;
256 }
257 if (!data.WriteInt32(accessibilityWindowId)) {
258 HILOG_ERROR("accessibilityWindowId write error: %{public}d, ", accessibilityWindowId);
259 return RET_ERR_IPC_FAILED;
260 }
261 if (!data.WriteInt64(elementId)) {
262 HILOG_ERROR("elementId write error: %{public}" PRId64 "", elementId);
263 return RET_ERR_IPC_FAILED;
264 }
265 if (!data.WriteInt32(action)) {
266 HILOG_ERROR("action write error: %{public}d, ", action);
267 return RET_ERR_IPC_FAILED;
268 }
269
270 std::vector<std::string> actionArgumentsKey {};
271 std::vector<std::string> actionArgumentsValue {};
272 for (auto iter = actionArguments.begin(); iter != actionArguments.end(); iter++) {
273 actionArgumentsKey.push_back(iter->first);
274 actionArgumentsValue.push_back(iter->second);
275 }
276 if (!data.WriteStringVector(actionArgumentsKey)) {
277 HILOG_ERROR("actionArgumentsKey write error");
278 return RET_ERR_IPC_FAILED;
279 }
280 if (!data.WriteStringVector(actionArgumentsValue)) {
281 HILOG_ERROR("actionArgumentsValue write error");
282 return RET_ERR_IPC_FAILED;
283 }
284
285 if (!data.WriteInt32(requestId)) {
286 HILOG_ERROR("requestId write error: %{public}d, ", requestId);
287 return RET_ERR_IPC_FAILED;
288 }
289 if (!callback || !data.WriteRemoteObject(callback->AsObject())) {
290 HILOG_ERROR("callback write error");
291 return RET_ERR_IPC_FAILED;
292 }
293
294 if (!SendTransactCmd(AccessibilityInterfaceCode::PERFORM_ACTION,
295 data, reply, option)) {
296 HILOG_ERROR("fail to perform accessibility action");
297 return RET_ERR_IPC_FAILED;
298 }
299 return static_cast<RetError>(reply.ReadInt32());
300 }
301
GetWindow(const int32_t windowId,AccessibilityWindowInfo & windowInfo)302 RetError AccessibleAbilityChannelProxy::GetWindow(const int32_t windowId, AccessibilityWindowInfo &windowInfo)
303 {
304 HILOG_DEBUG();
305
306 MessageParcel data;
307 MessageParcel reply;
308 MessageOption option;
309
310 if (!WriteInterfaceToken(data)) {
311 return RET_ERR_IPC_FAILED;
312 }
313
314 if (!data.WriteInt32(windowId)) {
315 HILOG_ERROR("windowId write error: %{public}d, ", windowId);
316 return RET_ERR_IPC_FAILED;
317 }
318
319 if (!SendTransactCmd(AccessibilityInterfaceCode::GET_WINDOW, data, reply, option)) {
320 HILOG_ERROR("fail to get window");
321 return RET_ERR_IPC_FAILED;
322 }
323
324 sptr<AccessibilityWindowInfoParcel> windowInfoParcel = reply.ReadStrongParcelable<AccessibilityWindowInfoParcel>();
325 if (!windowInfoParcel) {
326 HILOG_ERROR("ReadStrongParcelable<AccessibilityWindowInfoParcel> failed");
327 return RET_ERR_IPC_FAILED;
328 }
329 windowInfo = *windowInfoParcel;
330
331 return static_cast<RetError>(reply.ReadInt32());
332 }
333
GetWindows(std::vector<AccessibilityWindowInfo> & windows)334 RetError AccessibleAbilityChannelProxy::GetWindows(std::vector<AccessibilityWindowInfo> &windows)
335 {
336 HILOG_DEBUG();
337 MessageParcel data;
338 MessageParcel reply;
339 MessageOption option;
340
341 if (!WriteInterfaceToken(data)) {
342 return RET_ERR_IPC_FAILED;
343 }
344
345 if (!SendTransactCmd(AccessibilityInterfaceCode::GET_WINDOWS, data, reply, option)) {
346 HILOG_ERROR("fail to get windows");
347 return RET_ERR_IPC_FAILED;
348 }
349
350 int32_t windowsSize = reply.ReadInt32();
351 for (int32_t i = 0; i < windowsSize; i++) {
352 sptr<AccessibilityWindowInfoParcel> window = reply.ReadStrongParcelable<AccessibilityWindowInfoParcel>();
353 if (!window) {
354 HILOG_ERROR("ReadStrongParcelable<AccessibilityWindowInfoParcel> failed");
355 return RET_ERR_IPC_FAILED;
356 }
357 windows.emplace_back(*window);
358 }
359
360 return static_cast<RetError>(reply.ReadInt32());
361 }
362
GetWindowsByDisplayId(const uint64_t displayId,std::vector<AccessibilityWindowInfo> & windows)363 RetError AccessibleAbilityChannelProxy::GetWindowsByDisplayId(const uint64_t displayId,
364 std::vector<AccessibilityWindowInfo> &windows)
365 {
366 HILOG_DEBUG();
367
368 MessageParcel data;
369 MessageParcel reply;
370 MessageOption option;
371
372 if (!WriteInterfaceToken(data)) {
373 return RET_ERR_IPC_FAILED;
374 }
375
376 if (!data.WriteUint64(displayId)) {
377 HILOG_ERROR("displayId write error: %{public}" PRIu64 ", ", displayId);
378 return RET_ERR_IPC_FAILED;
379 }
380
381 if (!SendTransactCmd(AccessibilityInterfaceCode::GET_WINDOWS_BY_DISPLAY_ID, data, reply, option)) {
382 HILOG_ERROR("fail to get windows");
383 return RET_ERR_IPC_FAILED;
384 }
385
386 int32_t windowsSize = reply.ReadInt32();
387 for (int32_t i = 0; i < windowsSize; i++) {
388 sptr<AccessibilityWindowInfoParcel> window = reply.ReadStrongParcelable<AccessibilityWindowInfoParcel>();
389 if (!window) {
390 HILOG_ERROR("ReadStrongParcelable<AccessibilityWindowInfoParcel> failed");
391 return RET_ERR_IPC_FAILED;
392 }
393 windows.emplace_back(*window);
394 }
395
396 return static_cast<RetError>(reply.ReadInt32());
397 }
398
SetOnKeyPressEventResult(const bool handled,const int32_t sequence)399 void AccessibleAbilityChannelProxy::SetOnKeyPressEventResult(const bool handled, const int32_t sequence)
400 {
401 HILOG_DEBUG();
402
403 MessageParcel data;
404 MessageParcel reply;
405 MessageOption option(MessageOption::TF_ASYNC);
406
407 if (!WriteInterfaceToken(data)) {
408 return;
409 }
410 if (!data.WriteBool(handled)) {
411 HILOG_ERROR("handled write error: %{public}d, ", handled);
412 return;
413 }
414 if (!data.WriteInt32(sequence)) {
415 HILOG_ERROR("sequence write error: %{public}d, ", sequence);
416 return;
417 }
418 if (!SendTransactCmd(AccessibilityInterfaceCode::SET_ON_KEY_PRESS_EVENT_RESULT,
419 data, reply, option)) {
420 HILOG_ERROR("fail to set onKeyPressEvent result");
421 }
422 }
423
SendSimulateGesture(const std::shared_ptr<AccessibilityGestureInjectPath> & gesturePath)424 RetError AccessibleAbilityChannelProxy::SendSimulateGesture(
425 const std::shared_ptr<AccessibilityGestureInjectPath>& gesturePath)
426 {
427 HILOG_DEBUG();
428 sptr<AccessibilityGestureInjectPathParcel> path =
429 new(std::nothrow) AccessibilityGestureInjectPathParcel(*gesturePath);
430 if (!path) {
431 HILOG_ERROR("Failed to create path.");
432 return RET_ERR_NULLPTR;
433 }
434
435 MessageParcel data;
436 MessageParcel reply;
437 MessageOption option(MessageOption::TF_SYNC);
438
439 if (!WriteInterfaceToken(data)) {
440 return RET_ERR_IPC_FAILED;
441 }
442
443 if (!data.WriteStrongParcelable(path)) {
444 HILOG_ERROR("WriteStrongParcelable<AccessibilityGestureInjectPathParcel> failed");
445 return RET_ERR_IPC_FAILED;
446 }
447
448 if (!SendTransactCmd(AccessibilityInterfaceCode::SEND_SIMULATE_GESTURE_PATH, data, reply, option)) {
449 HILOG_ERROR("fail to send simulation gesture path");
450 return RET_ERR_IPC_FAILED;
451 }
452 return static_cast<RetError>(reply.ReadInt32());
453 }
454
SetTargetBundleName(const std::vector<std::string> & targetBundleNames)455 RetError AccessibleAbilityChannelProxy::SetTargetBundleName(const std::vector<std::string> &targetBundleNames)
456 {
457 HILOG_DEBUG();
458
459 MessageParcel data;
460 MessageParcel reply;
461 MessageOption option(MessageOption::TF_SYNC);
462
463 if (!WriteInterfaceToken(data)) {
464 return RET_ERR_IPC_FAILED;
465 }
466 if (!data.WriteInt32(targetBundleNames.size())) {
467 HILOG_ERROR("targetBundleNames.size() write error: %{public}zu, ", targetBundleNames.size());
468 return RET_ERR_IPC_FAILED;
469 }
470 for (auto &targetBundleName : targetBundleNames) {
471 if (!data.WriteString(targetBundleName)) {
472 HILOG_ERROR("targetBundleName write error: %{public}s, ", targetBundleName.c_str());
473 return RET_ERR_IPC_FAILED;
474 }
475 }
476 if (!SendTransactCmd(AccessibilityInterfaceCode::SET_TARGET_BUNDLE_NAME, data, reply, option)) {
477 HILOG_ERROR("fail to set target bundle name filter");
478 return RET_ERR_IPC_FAILED;
479 }
480 return static_cast<RetError>(reply.ReadInt32());
481 }
482 } // namespace Accessibility
483 } // namespace OHOS