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