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_stub.h"
17 #include "accessibility_element_info_parcel.h"
18 #include "accessibility_gesture_inject_path_parcel.h"
19 #include "accessibility_ipc_interface_code.h"
20 #include "accessibility_permission.h"
21 #include "accessibility_window_info_parcel.h"
22 #include "hilog_wrapper.h"
23 #include "parcel_util.h"
24
25 #define SWITCH_BEGIN(code) switch (code) {
26 #define SWITCH_CASE(case_code, func) \
27 case case_code: { \
28 result_code = func(data, reply); \
29 break; \
30 }
31
32 #define SWITCH_END() \
33 default: { \
34 result_code = ERR_CODE_DEFAULT; \
35 HILOG_WARN("AccessibleAbilityChannelStub::OnRemoteRequest, default case, need check."); \
36 break; \
37 } \
38 }
39
40 #define ACCESSIBLE_ABILITY_CHANNEL_STUB_CASES() \
41 SWITCH_CASE( \
42 AccessibilityInterfaceCode::SEARCH_ELEMENTINFO_BY_ACCESSIBILITY_ID, HandleSearchElementInfoByAccessibilityId) \
43 SWITCH_CASE(AccessibilityInterfaceCode::SEARCH_ELEMENTINFOS_BY_TEXT, HandleSearchElementInfosByText) \
44 SWITCH_CASE(AccessibilityInterfaceCode::FIND_FOCUSED_ELEMENTINFO, HandleFindFocusedElementInfo) \
45 SWITCH_CASE(AccessibilityInterfaceCode::FOCUS_MOVE_SEARCH, HandleFocusMoveSearch) \
46 SWITCH_CASE(AccessibilityInterfaceCode::PERFORM_ACTION, HandleExecuteAction) \
47 SWITCH_CASE(AccessibilityInterfaceCode::SET_CURTAIN_SCREEN, HandleEnableScreenCurtain) \
48 SWITCH_CASE(AccessibilityInterfaceCode::GET_WINDOW, HandleGetWindow) \
49 SWITCH_CASE(AccessibilityInterfaceCode::GET_WINDOWS, HandleGetWindows) \
50 SWITCH_CASE(AccessibilityInterfaceCode::GET_WINDOWS_BY_DISPLAY_ID, HandleGetWindowsByDisplayId) \
51 SWITCH_CASE(AccessibilityInterfaceCode::SET_ON_KEY_PRESS_EVENT_RESULT, HandleSetOnKeyPressEventResult) \
52 SWITCH_CASE(AccessibilityInterfaceCode::SEND_SIMULATE_GESTURE_PATH, HandleSendSimulateGesturePath) \
53 SWITCH_CASE(AccessibilityInterfaceCode::SET_TARGET_BUNDLE_NAME, HandleSetTargetBundleName) \
54 SWITCH_CASE(AccessibilityInterfaceCode::GET_CURSOR_POSITION, HandleGetCursorPosition) \
55 SWITCH_CASE(AccessibilityInterfaceCode::SEARCH_DEFAULTFOCUSED_BY_WINDOW_ID, HandleSearchDefaultFocusedByWindowId)
56
57 namespace OHOS {
58 namespace Accessibility {
59 constexpr int32_t ERR_CODE_DEFAULT = -1000;
60
AccessibleAbilityChannelStub()61 AccessibleAbilityChannelStub::AccessibleAbilityChannelStub()
62 {
63 }
64
~AccessibleAbilityChannelStub()65 AccessibleAbilityChannelStub::~AccessibleAbilityChannelStub()
66 {
67 }
68
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)69 int AccessibleAbilityChannelStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
70 MessageOption &option)
71 {
72 HILOG_DEBUG("cmd = %{public}d, flags= %{public}d", code, option.GetFlags());
73 std::u16string descriptor = AccessibleAbilityChannelStub::GetDescriptor();
74 std::u16string remoteDescriptor = data.ReadInterfaceToken();
75 if (descriptor != remoteDescriptor) {
76 HILOG_INFO("local descriptor is not equal to remote");
77 return ERR_INVALID_STATE;
78 }
79
80 ErrCode result_code = ERR_NONE;
81 SWITCH_BEGIN(code)
82 ACCESSIBLE_ABILITY_CHANNEL_STUB_CASES()
83 SWITCH_END()
84
85 if (result_code != ERR_CODE_DEFAULT) {
86 return result_code;
87 }
88
89 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
90 }
91
HandleSearchElementInfoByAccessibilityId(MessageParcel & data,MessageParcel & reply)92 ErrCode AccessibleAbilityChannelStub::HandleSearchElementInfoByAccessibilityId(MessageParcel &data,
93 MessageParcel &reply)
94 {
95 HILOG_DEBUG();
96
97 ElementBasicInfo elementBasicInfo {};
98 elementBasicInfo.windowId = data.ReadInt32();
99 elementBasicInfo.treeId = data.ReadInt32();
100 elementBasicInfo.elementId = data.ReadInt64();
101 int32_t requestId = data.ReadInt32();
102
103 sptr<IRemoteObject> remote = data.ReadRemoteObject();
104 if (remote == nullptr) {
105 HILOG_ERROR("remote is nullptr.");
106 return ERR_INVALID_VALUE;
107 }
108 sptr<IAccessibilityElementOperatorCallback> callback =
109 iface_cast<IAccessibilityElementOperatorCallback>(remote);
110 if (callback == nullptr) {
111 HILOG_ERROR("callback is nullptr.");
112 return ERR_INVALID_VALUE;
113 }
114
115 int32_t mode = data.ReadInt32();
116 if (mode == PREFETCH_RECURSIVE_CHILDREN) {
117 if (!Permission::CheckCallingPermission(OHOS_PERMISSION_QUERY_ACCESSIBILITY_ELEMENT) &&
118 !Permission::IsStartByHdcd()) {
119 HILOG_ERROR("no get element permission");
120 reply.WriteInt32(RET_ERR_NO_CONNECTION);
121 return NO_ERROR;
122 }
123 }
124
125 if (mode == GET_SOURCE_MODE) {
126 mode = PREFETCH_RECURSIVE_CHILDREN;
127 }
128 bool isFilter = data.ReadBool();
129 RetError result = SearchElementInfoByAccessibilityId(elementBasicInfo, requestId, callback, mode,
130 isFilter);
131 HILOG_DEBUG("SearchElementInfoByAccessibilityId ret = %{public}d", result);
132 reply.WriteInt32(result);
133
134 return NO_ERROR;
135 }
136
HandleSearchDefaultFocusedByWindowId(MessageParcel & data,MessageParcel & reply)137 ErrCode AccessibleAbilityChannelStub::HandleSearchDefaultFocusedByWindowId(MessageParcel &data,
138 MessageParcel &reply)
139 {
140 HILOG_DEBUG();
141
142 ElementBasicInfo elementBasicInfo {};
143 elementBasicInfo.windowId = data.ReadInt32();
144 elementBasicInfo.elementId = data.ReadInt64();
145 elementBasicInfo.treeId = data.ReadInt32();
146 int32_t requestId = data.ReadInt32();
147
148 sptr<IRemoteObject> remote = data.ReadRemoteObject();
149 if (remote == nullptr) {
150 HILOG_ERROR("remote is nullptr.");
151 return ERR_INVALID_VALUE;
152 }
153 sptr<IAccessibilityElementOperatorCallback> callback =
154 iface_cast<IAccessibilityElementOperatorCallback>(remote);
155 if (callback == nullptr) {
156 HILOG_ERROR("callback is nullptr.");
157 return ERR_INVALID_VALUE;
158 }
159
160 int32_t mode = data.ReadInt32();
161 if (mode == PREFETCH_RECURSIVE_CHILDREN) {
162 if (!Permission::CheckCallingPermission(OHOS_PERMISSION_QUERY_ACCESSIBILITY_ELEMENT) &&
163 !Permission::IsStartByHdcd()) {
164 HILOG_ERROR("no get element permission");
165 reply.WriteInt32(RET_ERR_NO_CONNECTION);
166 return NO_ERROR;
167 }
168 }
169
170 if (mode == GET_SOURCE_MODE) {
171 mode = PREFETCH_RECURSIVE_CHILDREN;
172 }
173 bool isFilter = data.ReadBool();
174 RetError result = SearchDefaultFocusedByWindowId(elementBasicInfo, requestId, callback, mode,
175 isFilter);
176 HILOG_DEBUG("SearchDefaultFocusedByWindowId ret = %{public}d", result);
177 reply.WriteInt32(result);
178
179 return NO_ERROR;
180 }
181
HandleSearchElementInfosByText(MessageParcel & data,MessageParcel & reply)182 ErrCode AccessibleAbilityChannelStub::HandleSearchElementInfosByText(MessageParcel &data,
183 MessageParcel &reply)
184 {
185 HILOG_DEBUG();
186
187 int32_t accessibilityWindowId = data.ReadInt32();
188 int64_t elementId = data.ReadInt64();
189 std::string text = data.ReadString();
190 int32_t requestId = data.ReadInt32();
191
192 sptr<IRemoteObject> remote = data.ReadRemoteObject();
193 if (remote == nullptr) {
194 HILOG_ERROR("remote is nullptr.");
195 return ERR_INVALID_VALUE;
196 }
197 sptr<IAccessibilityElementOperatorCallback> callback =
198 iface_cast<IAccessibilityElementOperatorCallback>(remote);
199 if (callback == nullptr) {
200 HILOG_ERROR("callback is nullptr.");
201 return ERR_INVALID_VALUE;
202 }
203
204 RetError result = SearchElementInfosByText(accessibilityWindowId, elementId, text, requestId, callback);
205 HILOG_DEBUG("SearchElementInfosByText ret = %{public}d", result);
206 reply.WriteInt32(result);
207
208 return NO_ERROR;
209 }
210
HandleFindFocusedElementInfo(MessageParcel & data,MessageParcel & reply)211 ErrCode AccessibleAbilityChannelStub::HandleFindFocusedElementInfo(MessageParcel &data, MessageParcel &reply)
212 {
213 HILOG_DEBUG();
214
215 int32_t accessibilityWindowId = data.ReadInt32();
216 int64_t elementId = data.ReadInt64();
217 int32_t focusType = data.ReadInt32();
218 int32_t requestId = data.ReadInt32();
219
220 sptr<IRemoteObject> remote = data.ReadRemoteObject();
221 if (remote == nullptr) {
222 HILOG_ERROR("remote is nullptr.");
223 return ERR_INVALID_VALUE;
224 }
225 sptr<IAccessibilityElementOperatorCallback> callback =
226 iface_cast<IAccessibilityElementOperatorCallback>(remote);
227 if (callback == nullptr) {
228 HILOG_ERROR("callback is nullptr.");
229 return ERR_INVALID_VALUE;
230 }
231
232 RetError result = FindFocusedElementInfo(accessibilityWindowId, elementId, focusType, requestId, callback);
233 HILOG_DEBUG("FindFocusedElementInfo ret = %{public}d", result);
234 reply.WriteInt32(result);
235 return NO_ERROR;
236 }
237
HandleFocusMoveSearch(MessageParcel & data,MessageParcel & reply)238 ErrCode AccessibleAbilityChannelStub::HandleFocusMoveSearch(MessageParcel &data, MessageParcel &reply)
239 {
240 HILOG_DEBUG();
241
242 int32_t accessibilityWindowId = data.ReadInt32();
243 int64_t elementId = data.ReadInt64();
244 int32_t direction = data.ReadInt32();
245 int32_t requestId = data.ReadInt32();
246
247 sptr<IRemoteObject> remote = data.ReadRemoteObject();
248 if (remote == nullptr) {
249 HILOG_ERROR("remote is nullptr.");
250 return ERR_INVALID_VALUE;
251 }
252 sptr<IAccessibilityElementOperatorCallback> callback =
253 iface_cast<IAccessibilityElementOperatorCallback>(remote);
254 if (callback == nullptr) {
255 HILOG_ERROR("callback is nullptr.");
256 return ERR_INVALID_VALUE;
257 }
258
259 RetError result = FocusMoveSearch(accessibilityWindowId, elementId, direction, requestId, callback);
260 HILOG_DEBUG("FocusMoveSearch ret = %{public}d", result);
261 reply.WriteInt32(result);
262
263 return NO_ERROR;
264 }
265
HandleExecuteAction(MessageParcel & data,MessageParcel & reply)266 ErrCode AccessibleAbilityChannelStub::HandleExecuteAction(MessageParcel &data, MessageParcel &reply)
267 {
268 HILOG_DEBUG();
269
270 int32_t accessibilityWindowId = data.ReadInt32();
271 int64_t elementId = data.ReadInt64();
272 int32_t action = data.ReadInt32();
273
274 std::vector<std::string> actionArgumentsKey;
275 std::vector<std::string> actionArgumentsValue;
276 std::map<std::string, std::string> actionArguments;
277
278 if (!data.ReadStringVector(&actionArgumentsKey)) {
279 HILOG_ERROR("ReadStringVector actionArgumentsKey failed");
280 return ERR_INVALID_VALUE;
281 }
282 if (!data.ReadStringVector(&actionArgumentsValue)) {
283 HILOG_ERROR("ReadStringVector actionArgumentsValue failed");
284 return ERR_INVALID_VALUE;
285 }
286 if (actionArgumentsKey.size() != actionArgumentsValue.size()) {
287 HILOG_ERROR("Read actionArguments failed.");
288 return ERR_INVALID_VALUE;
289 }
290 for (size_t i = 0; i < actionArgumentsKey.size(); i++) {
291 actionArguments.insert(make_pair(actionArgumentsKey[i], actionArgumentsValue[i]));
292 }
293
294 int32_t requestId = data.ReadInt32();
295
296 sptr<IRemoteObject> remote = data.ReadRemoteObject();
297 if (remote == nullptr) {
298 HILOG_ERROR("remote is nullptr.");
299 return ERR_INVALID_VALUE;
300 }
301
302 auto callback = iface_cast<IAccessibilityElementOperatorCallback>(remote);
303 if (callback == nullptr) {
304 HILOG_ERROR("callback is nullptr");
305 return ERR_INVALID_VALUE;
306 }
307
308 RetError result = ExecuteAction(accessibilityWindowId, elementId, action, actionArguments, requestId, callback);
309 HILOG_DEBUG("ExecuteAction ret = %{public}d", result);
310 reply.WriteInt32(result);
311 return NO_ERROR;
312 }
313
HandleEnableScreenCurtain(MessageParcel & data,MessageParcel & reply)314 ErrCode AccessibleAbilityChannelStub::HandleEnableScreenCurtain(MessageParcel &data, MessageParcel &reply)
315 {
316 HILOG_DEBUG();
317
318 if (!Permission::IsSystemApp()) {
319 HILOG_WARN("Not system app");
320 reply.WriteInt32(RET_ERR_NOT_SYSTEM_APP);
321 return RET_ERR_NOT_SYSTEM_APP;
322 }
323
324 bool isEnable = data.ReadBool();
325 RetError result = EnableScreenCurtain(isEnable);
326 reply.WriteInt32(result);
327 return NO_ERROR;
328 }
329
HandleGetCursorPosition(MessageParcel & data,MessageParcel & reply)330 ErrCode AccessibleAbilityChannelStub::HandleGetCursorPosition(MessageParcel &data, MessageParcel &reply)
331 {
332 HILOG_DEBUG();
333
334 int32_t accessibilityWindowId = data.ReadInt32();
335 int64_t elementId = data.ReadInt64();
336 int32_t requestId = data.ReadInt32();
337 HILOG_INFO("AccessibleAbilityChannelStub::HandleGetCursorPosition The execution was successful");
338 sptr<IRemoteObject> remote = data.ReadRemoteObject();
339 if (remote == nullptr) {
340 HILOG_ERROR("remote is nullptr.");
341 return ERR_INVALID_VALUE;
342 }
343 auto callback = iface_cast<IAccessibilityElementOperatorCallback>(remote);
344 if (callback == nullptr) {
345 HILOG_ERROR("callback is nullptr");
346 return ERR_INVALID_VALUE;
347 }
348
349 RetError result = GetCursorPosition(accessibilityWindowId, elementId, requestId, callback);
350 HILOG_DEBUG("GetCursorPosition ret = %{public}d", result);
351 reply.WriteInt32(result);
352 return NO_ERROR;
353 }
354
HandleGetWindow(MessageParcel & data,MessageParcel & reply)355 ErrCode AccessibleAbilityChannelStub::HandleGetWindow(MessageParcel &data, MessageParcel &reply)
356 {
357 HILOG_DEBUG();
358
359 int32_t windowId = data.ReadInt32();
360 sptr<AccessibilityWindowInfoParcel> windowInfoParcel = new(std::nothrow) AccessibilityWindowInfoParcel();
361 if (windowInfoParcel == nullptr) {
362 HILOG_ERROR("Failed to create windowInfoParcel.");
363 return ERR_NULL_OBJECT;
364 }
365
366 RetError result = GetWindow(windowId, *windowInfoParcel);
367 if (!reply.WriteStrongParcelable(windowInfoParcel)) {
368 HILOG_ERROR("WriteStrongParcelable windows failed");
369 return ERR_INVALID_VALUE;
370 }
371
372 reply.WriteInt32(result);
373 return NO_ERROR;
374 }
375
HandleGetWindows(MessageParcel & data,MessageParcel & reply)376 ErrCode AccessibleAbilityChannelStub::HandleGetWindows(MessageParcel &data, MessageParcel &reply)
377 {
378 HILOG_DEBUG();
379 std::vector<AccessibilityWindowInfo> windows;
380 RetError result = GetWindows(windows);
381 if (!reply.WriteInt32(static_cast<int32_t>(windows.size()))) {
382 HILOG_ERROR("windows.size() write error: %{public}zu, ", windows.size());
383 return ERR_INVALID_VALUE;
384 }
385 for (auto &window : windows) {
386 sptr<AccessibilityWindowInfoParcel> windowInfo = new(std::nothrow) AccessibilityWindowInfoParcel(window);
387 if (windowInfo == nullptr) {
388 HILOG_ERROR("Failed to create windowInfo.");
389 return ERR_NULL_OBJECT;
390 }
391 if (!reply.WriteStrongParcelable(windowInfo)) {
392 HILOG_ERROR("WriteStrongParcelable windows failed");
393 return ERR_INVALID_VALUE;
394 }
395 }
396 reply.WriteInt32(result);
397 return NO_ERROR;
398 }
399
HandleGetWindowsByDisplayId(MessageParcel & data,MessageParcel & reply)400 ErrCode AccessibleAbilityChannelStub::HandleGetWindowsByDisplayId(MessageParcel &data, MessageParcel &reply)
401 {
402 HILOG_DEBUG();
403
404 uint64_t displayId = data.ReadUint64();
405 std::vector<AccessibilityWindowInfo> windows;
406 RetError result = GetWindowsByDisplayId(displayId, windows);
407 if (!reply.WriteInt32(static_cast<int32_t>(windows.size()))) {
408 HILOG_ERROR("windows.size() write error: %{public}zu, ", windows.size());
409 return ERR_INVALID_VALUE;
410 }
411 for (auto &window : windows) {
412 sptr<AccessibilityWindowInfoParcel> windowInfo = new(std::nothrow) AccessibilityWindowInfoParcel(window);
413 if (windowInfo == nullptr) {
414 HILOG_ERROR("Failed to create windowInfo.");
415 return ERR_NULL_OBJECT;
416 }
417 if (!reply.WriteStrongParcelable(windowInfo)) {
418 HILOG_ERROR("WriteStrongParcelable windows failed");
419 return ERR_INVALID_VALUE;
420 }
421 }
422 reply.WriteInt32(result);
423 return NO_ERROR;
424 }
425
HandleSetOnKeyPressEventResult(MessageParcel & data,MessageParcel & reply)426 ErrCode AccessibleAbilityChannelStub::HandleSetOnKeyPressEventResult(MessageParcel &data, MessageParcel &reply)
427 {
428 HILOG_DEBUG();
429
430 bool handled = data.ReadBool();
431 int32_t sequence = data.ReadInt32();
432 SetOnKeyPressEventResult(handled, sequence);
433
434 return NO_ERROR;
435 }
436
HandleSendSimulateGesturePath(MessageParcel & data,MessageParcel & reply)437 ErrCode AccessibleAbilityChannelStub::HandleSendSimulateGesturePath(MessageParcel &data, MessageParcel &reply)
438 {
439 HILOG_DEBUG();
440
441 sptr<AccessibilityGestureInjectPathParcel> positions =
442 data.ReadStrongParcelable<AccessibilityGestureInjectPathParcel>();
443 if (positions == nullptr) {
444 HILOG_ERROR("ReadStrongParcelable<AccessibilityGestureInjectPathParcel> failed");
445 return ERR_INVALID_VALUE;
446 }
447
448 std::shared_ptr<AccessibilityGestureInjectPath> gesturePath =
449 std::make_shared<AccessibilityGestureInjectPath>(*positions);
450 RetError result = SendSimulateGesture(gesturePath);
451 reply.WriteInt32(result);
452 return NO_ERROR;
453 }
454
HandleSetTargetBundleName(MessageParcel & data,MessageParcel & reply)455 ErrCode AccessibleAbilityChannelStub::HandleSetTargetBundleName(MessageParcel &data, MessageParcel &reply)
456 {
457 HILOG_DEBUG();
458 std::vector<std::string> targetBundleNames;
459 int32_t size = data.ReadInt32();
460 bool verifyResult = ContainerSecurityVerify(data, size, targetBundleNames.max_size());
461 if (!verifyResult) {
462 return TRANSACTION_ERR;
463 }
464 if (size < 0 || size > MAX_ALLOW_SIZE) {
465 return TRANSACTION_ERR;
466 }
467 for (int32_t i = 0; i < size; i++) {
468 std::string temp = data.ReadString();
469 targetBundleNames.emplace_back(temp);
470 }
471 RetError result = SetTargetBundleName(targetBundleNames);
472 reply.WriteInt32(result);
473 return NO_ERROR;
474 }
475 } // namespace Accessibility
476 } // namespace OHOS