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