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